# nto-qnx **Tier: 3** [BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system. The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit] and [BlackBerry][BlackBerry]. [BlackBerry]: https://blackberry.qnx.com [Elektrobit]: https://www.elektrobit.com ## Target maintainers - Florian Bartels, `Florian.Bartels@elektrobit.com`, https://github.com/flba-eb - Tristan Roach, `TRoach@blackberry.com`, https://github.com/gh-tr ## Requirements Currently, only cross-compilation for QNX Neutrino on AArch64 and x86_64 are supported (little endian). Adding other architectures that are supported by QNX Neutrino is possible. The standard library does not yet support QNX Neutrino. Therefore, only `no_std` code can be compiled. `core` and `alloc` (with default allocator) are supported. Applications must link against `libc.so` (see example). This is required because applications always link against the `crt` library and `crt` depends on `libc.so`. The correct version of `qcc` must be available by setting the `$PATH` variable (e.g. by sourcing `qnxsdp-env.sh` of the QNX Neutrino toolchain). ### Small example application ```rust,ignore (platform-specific) #![no_std] #![no_main] #![feature(lang_items)] // We must always link against libc, even if no external functions are used // "extern C" - Block can be empty but must be present #[link(name = "c")] extern "C" { pub fn printf(format: *const core::ffi::c_char, ...) -> core::ffi::c_int; } #[no_mangle] pub extern "C" fn main(_argc: isize, _argv: *const *const u8) -> isize { const HELLO: &'static str = "Hello World, the answer is %d\n\0"; unsafe { printf(HELLO.as_ptr() as *const _, 42); } 0 } use core::panic::PanicInfo; #[panic_handler] fn panic(_panic: &PanicInfo<'_>) -> ! { loop {} } #[lang = "eh_personality"] #[no_mangle] pub extern "C" fn rust_eh_personality() {} ``` The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.1. There are no further known requirements. ## Conditional compilation For conditional compilation, following QNX Neutrino specific attributes are defined: - `target_os` = `"nto"` - `target_env` = `"nto71"` (for QNX Neutrino 7.1) ## Building the target 1. Create a `config.toml` Example content: ```toml profile = "compiler" changelog-seen = 2 ``` 2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets) Run the following: ```bash env \ CC_aarch64-unknown-nto-qnx710="qcc" \ CFLAGS_aarch64-unknown-nto-qnx710="-Vgcc_ntoaarch64le_cxx" \ CXX_aarch64-unknown-nto-qnx710="qcc" \ AR_aarch64_unknown_nto_qnx710="ntoaarch64-ar" \ CC_x86_64-pc-nto-qnx710="qcc" \ CFLAGS_x86_64-pc-nto-qnx710="-Vgcc_ntox86_64_cxx" \ CXX_x86_64-pc-nto-qnx710="qcc" \ AR_x86_64_pc_nto_qnx710="ntox86_64-ar" \ ./x.py build --target aarch64-unknown-nto-qnx710 --target x86_64-pc-nto-qnx710 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ ``` ## Building Rust programs Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you must either build Rust with the target enabled (see "Building the target" above), or build your own copy of `core` by using `build-std` or similar. ## Testing Compiled executables can directly be run on QNX Neutrino. ## Cross-compilation toolchains and C code Compiling C code requires the same environment variables to be set as compiling the Rust toolchain (see above), to ensure `qcc` is used with proper arguments. To ensure compatibility, do not specify any further arguments that for example change calling conventions or memory layout.