summaryrefslogtreecommitdiffstats
path: root/src/doc/rustc/src/platform-support/nto-qnx.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/rustc/src/platform-support/nto-qnx.md')
-rw-r--r--src/doc/rustc/src/platform-support/nto-qnx.md175
1 files changed, 150 insertions, 25 deletions
diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md
index 37d0c3197..38198fe6c 100644
--- a/src/doc/rustc/src/platform-support/nto-qnx.md
+++ b/src/doc/rustc/src/platform-support/nto-qnx.md
@@ -2,9 +2,9 @@
**Tier: 3**
-[BlackBerry® QNX®][BlackBerry] Neutrino (nto) Real-time operating system.
+[QNX®][BlackBerry] Neutrino (nto) Real-time operating system.
The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit]
-and [BlackBerry][BlackBerry].
+and [Blackberry QNX][BlackBerry].
[BlackBerry]: https://blackberry.qnx.com
[Elektrobit]: https://www.elektrobit.com
@@ -19,19 +19,24 @@ and [BlackBerry][BlackBerry].
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.
+The standard library, including `core` and `alloc` (with default allocator) are supported.
-`core` and `alloc` (with default allocator) are supported.
+For building or using the Rust toolchain for QNX Neutrino, the
+[QNX Software Development Platform (SDP)](https://blackberry.qnx.com/en/products/foundation-software/qnx-software-development-platform)
+must be installed and initialized.
+Initialization is usually done by sourcing `qnxsdp-env.sh` (this will be installed as part of the SDP, see also installation instruction provided with the SDP).
+Afterwards [`qcc`](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.utilities/topic/q/qcc.html) (QNX C/C++ compiler)
+should be available (in the `$PATH` variable).
+`qcc` will be called e.g. for linking executables.
-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).
+When linking `no_std` applications, they must link against `libc.so` (see example). This is
+required because applications always link against the `crt` library and `crt` depends on `libc.so`.
+This is done automatically when using the standard library.
### Small example application
+Small `no_std` example is shown below. Applications using the standard library work as well.
+
```rust,ignore (platform-specific)
#![no_std]
#![no_main]
@@ -89,30 +94,150 @@ 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:
+Compiling the Rust toolchain requires the same environment variables used for compiling C binaries.
+Refer to the [QNX developer manual](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.prog/topic/devel_OS_version.html).
+
+To compile for QNX Neutrino (aarch64 and x86_64) and Linux (x86_64):
```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/
+export build_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'
+
+env $build_env \
+ ./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
```
+## Running the Rust test suite
+
+The test suites of the Rust compiler and standard library can be executed much like other Rust targets.
+The environment for testing should match the one used during compiler compilation (refer to `build_env` and `qcc`/`PATH` above) with the
+addition of the TEST_DEVICE_ADDR environment variable.
+The TEST_DEVICE_ADDR variable controls the remote runner and should point to the target, despite localhost being shown in the following example.
+Note that some tests are failing which is why they are currently excluded by the target maintainers which can be seen in the following example.
+
+To run all tests on a x86_64 QNX Neutrino target:
+
+```bash
+export TEST_DEVICE_ADDR="localhost:12345" # must address the test target, can be a SSH tunnel
+export build_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'
+
+# Disable tests that only work on the host or don't make sense for this target.
+# See also:
+# - src/ci/docker/host-x86_64/i686-gnu/Dockerfile
+# - https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Running.20tests.20on.20remote.20target
+# - .github/workflows/ci.yml
+export exclude_tests='
+ --exclude src/bootstrap
+ --exclude src/tools/error_index_generator
+ --exclude src/tools/linkchecker
+ --exclude tests/ui-fulldeps
+ --exclude rustc
+ --exclude rustdoc
+ --exclude tests/run-make-fulldeps'
+
+env $build_env \
+ ./x.py test -j 1 \
+ $exclude_tests \
+ --stage 1 \
+ --target x86_64-pc-nto-qnx710
+```
+
+Currently, only one thread can be used when testing due to limitations in `libc::fork` and `libc::posix_spawnp`.
+See [fork documentation](https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html)
+(error section) for more information.
+This can be achieved by using the `-j 1` parameter in the `x.py` call.
+This issue is being researched and we will try to allow parallelism in the future.
+
## 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.
+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.
+Compiled executables can run directly on QNX Neutrino.
+
+### Rust std library test suite
+
+The target needs sufficient resources to execute all tests. The commands below assume that a QEMU image
+is used.
+
+* Ensure that the temporary directory used by `remote-test-server` has enough free space and inodes.
+ 5GB of free space and 40000 inodes are known to be sufficient (the test will create more than 32k files).
+ To create a QEMU image in an empty directory, run this command inside the directory:
+
+ ```bash
+ mkqnximage --type=qemu --ssh-ident=$HOME/.ssh/id_ed25519.pub --data-size=5000 --data-inodes=40000
+ ```
+
+ `/data` should have enough free resources.
+ Set the `TMPDIR` environment variable accordingly when running `remote-test-server`, e.g.:
+ ```bash
+ TMPDIR=/data/tmp/rust remote-test-server --bind 0.0.0.0:12345
+ ```
+
+* Ensure the TCP stack can handle enough parallel connections (default is 200, should be 300 or higher).
+ After creating an image (see above), edit the file `output/build/startup.sh`:
+ 1. Search for `io-pkt-v6-hc`
+ 2. Add the parameter `-ptcpip threads_max=300`, e.g.:
+ ```text
+ io-pkt-v6-hc -U 33:33 -d e1000 -ptcpip threads_max=300
+ ```
+ 3. Update the image by running `mkqnximage` again with the same parameters as above for creating it.
+
+* Running and stopping the virtual machine
+
+ To start the virtual machine, run inside the directory of the VM:
+
+ ```bash
+ mkqnximage --run=-h
+ ```
+
+ To stop the virtual machine, run inside the directory of the VM:
+
+ ```bash
+ mkqnximage --stop
+ ```
+
+* Ensure local networking
+
+ Ensure that 'localhost' is getting resolved to 127.0.0.1. If you can't ping the localhost, some tests may fail.
+ Ensure it's appended to /etc/hosts (if first `ping` command fails).
+ Commands have to be executed inside the virtual machine!
+
+ ```bash
+ $ ping localhost
+ ping: Cannot resolve "localhost" (Host name lookup failure)
+
+ $ echo "127.0.0.1 localhost" >> /etc/hosts
+
+ $ ping localhost
+ PING localhost (127.0.0.1): 56 data bytes
+ 64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=1 ms
+ ```
## 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.
+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.