1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
# 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.
|