Rollup merge of #133631 - flba-eb:add_nto_qnx71_iosock_support, r=workingjubilee
Support QNX 7.1 with `io-sock`+libstd and QNX 8.0 (`no_std` only) Changes of this pull request: 1. Refactor code for qnx nto targets to share more code in file `nto_qnx.rs` 1. Add support for an additional network stack on nto qnx 7.1. QNX 7.1 supports two network stacks: 1. `io-pkt`, which is default 2. `io-sock`, which is optional on 7.1 but default in QNX 8.0 As one can see in the [io-sock migration notes](https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html), this changes the libc API in a way similar to e.g. linux-gnu vs. linux-musl. This change adds a new target which has a different value for `target_env`, so that e.g. libc can distinguish between both APIs. 2. Add initial support for QNX 8.0, thanks to AkhilTThomas. As it turned out, the problem with forking many processes still exists in QNX 8.0. Because if this, we are now using it for any QNX version (i.e. not check for `target_env` anymore).
This commit is contained in:
commit
0d0e841594
17 changed files with 285 additions and 141 deletions
|
@ -1,4 +1,6 @@
|
|||
use crate::spec::{RelroLevel, TargetOptions, cvs};
|
||||
use crate::spec::{
|
||||
Cc, LinkArgs, LinkerFlavor, Lld, RelroLevel, Target, TargetMetadata, TargetOptions, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
|
@ -16,3 +18,96 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn meta() -> TargetMetadata {
|
||||
TargetMetadata { description: None, tier: Some(3), host_tools: Some(false), std: Some(true) }
|
||||
}
|
||||
|
||||
pub(crate) fn aarch64() -> Target {
|
||||
Target {
|
||||
llvm_target: "aarch64-unknown-unknown".into(),
|
||||
metadata: meta(),
|
||||
pointer_width: 64,
|
||||
// from: https://llvm.org/docs/LangRef.html#data-layout
|
||||
// e = little endian
|
||||
// m:e = ELF mangling: Private symbols get a .L prefix
|
||||
// i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
|
||||
// i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
|
||||
// i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
|
||||
// i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
|
||||
// n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
|
||||
// S128 = 128 bits are the natural alignment of the stack in bits.
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
max_atomic_width: Some(128),
|
||||
..opts()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn x86_64() -> Target {
|
||||
Target {
|
||||
llvm_target: "x86_64-pc-unknown".into(),
|
||||
metadata: meta(),
|
||||
pointer_width: 64,
|
||||
data_layout:
|
||||
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
||||
arch: "x86_64".into(),
|
||||
options: TargetOptions {
|
||||
cpu: "x86-64".into(),
|
||||
plt_by_default: false,
|
||||
max_atomic_width: Some(64),
|
||||
vendor: "pc".into(),
|
||||
..opts()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn pre_link_args(api_var: ApiVariant, arch: Arch) -> LinkArgs {
|
||||
let (qcc_arg, arch_lib_dir) = match arch {
|
||||
Arch::Aarch64 => ("-Vgcc_ntoaarch64le_cxx", "aarch64le"),
|
||||
Arch::I586 => {
|
||||
("-Vgcc_ntox86_cxx", "notSupportedByQnx_compiler/rustc_target/src/spec/base/nto_qnx.rs")
|
||||
}
|
||||
Arch::X86_64 => ("-Vgcc_ntox86_64_cxx", "x86_64"),
|
||||
};
|
||||
match api_var {
|
||||
ApiVariant::Default => {
|
||||
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[qcc_arg])
|
||||
}
|
||||
ApiVariant::IoSock => TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
|
||||
qcc_arg,
|
||||
get_iosock_param(arch_lib_dir),
|
||||
]),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum ApiVariant {
|
||||
Default,
|
||||
IoSock,
|
||||
}
|
||||
|
||||
pub(crate) enum Arch {
|
||||
Aarch64,
|
||||
I586,
|
||||
X86_64,
|
||||
}
|
||||
|
||||
// When using `io-sock` on QNX, we must add a search path for the linker so
|
||||
// that it prefers the io-sock version.
|
||||
// The path depends on the host, i.e. we cannot hard-code it here, but have
|
||||
// to determine it when the compiler runs.
|
||||
// When using the QNX toolchain, the environment variable QNX_TARGET is always set.
|
||||
// More information:
|
||||
// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html
|
||||
fn get_iosock_param(arch_lib_dir: &str) -> &'static str {
|
||||
let target_dir = std::env::var("QNX_TARGET")
|
||||
.unwrap_or_else(|_| "QNX_TARGET_not_set_please_source_qnxsdp-env.sh".into());
|
||||
let linker_param = format!("-L{target_dir}/{arch_lib_dir}/io-sock/lib");
|
||||
|
||||
// FIXME: leaking this is kind of weird: we're feeding these into something that expects an
|
||||
// `AsRef<OsStr>`, but often converts to `OsString` anyways, so shouldn't we just demand an `OsString`?
|
||||
linker_param.leak()
|
||||
}
|
||||
|
|
|
@ -1963,7 +1963,11 @@ supported_targets! {
|
|||
|
||||
("aarch64-unknown-nto-qnx700", aarch64_unknown_nto_qnx700),
|
||||
("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx710),
|
||||
("aarch64-unknown-nto-qnx710_iosock", aarch64_unknown_nto_qnx710_iosock),
|
||||
("aarch64-unknown-nto-qnx800", aarch64_unknown_nto_qnx800),
|
||||
("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710),
|
||||
("x86_64-pc-nto-qnx710_iosock", x86_64_pc_nto_qnx710_iosock),
|
||||
("x86_64-pc-nto-qnx800", x86_64_pc_nto_qnx800),
|
||||
("i586-pc-nto-qnx700", i586_pc_nto_qnx700),
|
||||
|
||||
("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos),
|
||||
|
|
|
@ -1,37 +1,11 @@
|
|||
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
|
||||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
// In QNX, libc does not provide a compatible ABI between versions.
|
||||
// To distinguish between QNX versions, we needed a stable conditional compilation switch,
|
||||
// which is why we needed to implement different targets in the compiler.
|
||||
Target {
|
||||
llvm_target: "aarch64-unknown-unknown".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: Some("ARM64 QNX Neutrino 7.0 RTOS".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
// from: https://llvm.org/docs/LangRef.html#data-layout
|
||||
// e = little endian
|
||||
// m:e = ELF mangling: Private symbols get a .L prefix
|
||||
// i8:8:32 = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
|
||||
// i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
|
||||
// i64:64 = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
|
||||
// i128:128 = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
|
||||
// n32:64 = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
|
||||
// S128 = 128 bits are the natural alignment of the stack in bits.
|
||||
data_layout: "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
|
||||
arch: "aarch64".into(),
|
||||
options: TargetOptions {
|
||||
features: "+v8a".into(),
|
||||
max_atomic_width: Some(128),
|
||||
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
|
||||
"-Vgcc_ntoaarch64le_cxx",
|
||||
]),
|
||||
env: "nto70".into(),
|
||||
..base::nto_qnx::opts()
|
||||
},
|
||||
}
|
||||
let mut target = nto_qnx::aarch64();
|
||||
target.metadata.description = Some("ARM64 QNX Neutrino 7.0 RTOS".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
|
||||
target.options.env = "nto70".into();
|
||||
target
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut base = super::aarch64_unknown_nto_qnx700::target();
|
||||
base.metadata.description = Some("ARM64 QNX Neutrino 7.1 RTOS".into());
|
||||
base.options.env = "nto71".into();
|
||||
base
|
||||
let mut target = nto_qnx::aarch64();
|
||||
target.metadata.description =
|
||||
Some("ARM64 QNX Neutrino 7.1 RTOS with io-pkt network stack".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
|
||||
target.options.env = "nto71".into();
|
||||
target
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut target = nto_qnx::aarch64();
|
||||
target.metadata.description =
|
||||
Some("ARM64 QNX Neutrino 7.1 RTOS with io-sock network stack".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64);
|
||||
target.options.env = "nto71_iosock".into();
|
||||
target
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut target = nto_qnx::aarch64();
|
||||
target.metadata.description = Some("ARM64 QNX Neutrino 8.0 RTOS".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::Aarch64);
|
||||
target.options.env = "nto80".into();
|
||||
target
|
||||
}
|
|
@ -1,14 +1,13 @@
|
|||
use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, base};
|
||||
use crate::spec::base::nto_qnx;
|
||||
use crate::spec::{StackProbeType, Target, TargetOptions, base};
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut meta = nto_qnx::meta();
|
||||
meta.description = Some("32-bit x86 QNX Neutrino 7.0 RTOS".into());
|
||||
meta.std = Some(false);
|
||||
Target {
|
||||
llvm_target: "i586-pc-unknown".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: Some("32-bit x86 QNX Neutrino 7.0 RTOS".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(false),
|
||||
},
|
||||
metadata: meta,
|
||||
pointer_width: 32,
|
||||
data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
|
||||
i128:128-f64:32:64-f80:32-n8:16:32-S128"
|
||||
|
@ -17,9 +16,10 @@ pub(crate) fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
cpu: "pentium4".into(),
|
||||
max_atomic_width: Some(64),
|
||||
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
|
||||
"-Vgcc_ntox86_cxx",
|
||||
]),
|
||||
pre_link_args: nto_qnx::pre_link_args(
|
||||
nto_qnx::ApiVariant::Default,
|
||||
nto_qnx::Arch::I586,
|
||||
),
|
||||
env: "nto70".into(),
|
||||
vendor: "pc".into(),
|
||||
stack_probes: StackProbeType::Inline,
|
||||
|
|
|
@ -1,28 +1,12 @@
|
|||
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions, base};
|
||||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
Target {
|
||||
llvm_target: "x86_64-pc-unknown".into(),
|
||||
metadata: crate::spec::TargetMetadata {
|
||||
description: Some("x86 64-bit QNX Neutrino 7.1 RTOS".into()),
|
||||
tier: Some(3),
|
||||
host_tools: Some(false),
|
||||
std: Some(true),
|
||||
},
|
||||
pointer_width: 64,
|
||||
data_layout:
|
||||
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
|
||||
arch: "x86_64".into(),
|
||||
options: TargetOptions {
|
||||
cpu: "x86-64".into(),
|
||||
plt_by_default: false,
|
||||
max_atomic_width: Some(64),
|
||||
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
|
||||
"-Vgcc_ntox86_64_cxx",
|
||||
]),
|
||||
env: "nto71".into(),
|
||||
vendor: "pc".into(),
|
||||
..base::nto_qnx::opts()
|
||||
},
|
||||
}
|
||||
let mut target = nto_qnx::x86_64();
|
||||
target.metadata.description =
|
||||
Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-pkt network stack".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64);
|
||||
target.options.env = "nto71".into();
|
||||
target
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut target = nto_qnx::x86_64();
|
||||
target.metadata.description =
|
||||
Some("x86 64-bit QNX Neutrino 7.1 RTOS with io-sock network stack".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64);
|
||||
target.options.env = "nto71_iosock".into();
|
||||
target
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
use crate::spec::Target;
|
||||
use crate::spec::base::nto_qnx;
|
||||
|
||||
pub(crate) fn target() -> Target {
|
||||
let mut target = nto_qnx::x86_64();
|
||||
target.metadata.description = Some("x86 64-bit QNX Neutrino 8.0 RTOS".into());
|
||||
target.options.pre_link_args =
|
||||
nto_qnx::pre_link_args(nto_qnx::ApiVariant::Default, nto_qnx::Arch::X86_64);
|
||||
target.options.env = "nto80".into();
|
||||
target
|
||||
}
|
|
@ -139,7 +139,8 @@ test = true
|
|||
level = "warn"
|
||||
check-cfg = [
|
||||
'cfg(bootstrap)',
|
||||
'cfg(target_arch, values("xtensa"))',
|
||||
'cfg(target_arch, values("xtensa", "aarch64-unknown-nto-qnx710_iosock", "x86_64-pc-nto-qnx710_iosock", "x86_64-pc-nto-qnx800","aarch64-unknown-nto-qnx800"))',
|
||||
'cfg(target_env, values("nto71_iosock", "nto80"))',
|
||||
# std use #[path] imports to portable-simd `std_float` crate
|
||||
# and to the `backtrace` crate which messes-up with Cargo list
|
||||
# of declared features, we therefor expect any feature cfg
|
||||
|
|
|
@ -19,8 +19,7 @@ use crate::sys::process::process_common::*;
|
|||
use crate::{fmt, mem, sys};
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
// This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
|
||||
if #[cfg(any(target_env = "nto70", target_env = "nto71"))] {
|
||||
if #[cfg(target_os = "nto")] {
|
||||
use crate::thread;
|
||||
use libc::{c_char, posix_spawn_file_actions_t, posix_spawnattr_t};
|
||||
use crate::time::Duration;
|
||||
|
@ -187,12 +186,7 @@ impl Command {
|
|||
|
||||
// Attempts to fork the process. If successful, returns Ok((0, -1))
|
||||
// in the child, and Ok((child_pid, -1)) in the parent.
|
||||
#[cfg(not(any(
|
||||
target_os = "watchos",
|
||||
target_os = "tvos",
|
||||
target_env = "nto70",
|
||||
target_env = "nto71"
|
||||
)))]
|
||||
#[cfg(not(any(target_os = "watchos", target_os = "tvos", target_os = "nto")))]
|
||||
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
|
||||
cvt(libc::fork())
|
||||
}
|
||||
|
@ -201,8 +195,7 @@ impl Command {
|
|||
// or closed a file descriptor while the fork() was occurring".
|
||||
// Documentation says "... or try calling fork() again". This is what we do here.
|
||||
// See also https://www.qnx.com/developers/docs/7.1/#com.qnx.doc.neutrino.lib_ref/topic/f/fork.html
|
||||
// This workaround is only needed for QNX 7.0 and 7.1. The bug should have been fixed in 8.0
|
||||
#[cfg(any(target_env = "nto70", target_env = "nto71"))]
|
||||
#[cfg(target_os = "nto")]
|
||||
unsafe fn do_fork(&mut self) -> Result<pid_t, io::Error> {
|
||||
use crate::sys::os::errno;
|
||||
|
||||
|
|
|
@ -34,6 +34,10 @@ pub struct Finder {
|
|||
// Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap).
|
||||
const STAGE0_MISSING_TARGETS: &[&str] = &[
|
||||
// just a dummy comment so the list doesn't get onelined
|
||||
"aarch64-unknown-nto-qnx710_iosock",
|
||||
"x86_64-pc-nto-qnx710_iosock",
|
||||
"x86_64-pc-nto-qnx800",
|
||||
"aarch64-unknown-nto-qnx800",
|
||||
];
|
||||
|
||||
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM
|
||||
|
|
|
@ -259,7 +259,9 @@ target | std | host | notes
|
|||
`aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI)
|
||||
[`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD
|
||||
[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS |
|
||||
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS |
|
||||
[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
|
||||
[`aarch64-unknown-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
|
||||
[`aarch64-unknown-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 8.0 RTOS |
|
||||
[`aarch64-unknown-nuttx`](platform-support/nuttx.md) | * | | ARM64 with NuttX
|
||||
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
|
||||
[`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS
|
||||
|
@ -404,7 +406,9 @@ target | std | host | notes
|
|||
[`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly
|
||||
[`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS
|
||||
[`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator
|
||||
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS |
|
||||
[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with default network stack (io-pkt) |
|
||||
[`x86_64-pc-nto-qnx710_iosock`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 7.1 RTOS with new network stack (io-sock) |
|
||||
[`x86_64-pc-nto-qnx800`](platform-support/nto-qnx.md) | ✓ | | x86 64-bit QNX Neutrino 8.0 RTOS |
|
||||
[`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3
|
||||
`x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
|
||||
`x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
**Tier: 3**
|
||||
|
||||
[QNX®][BlackBerry] Neutrino (nto) Real-time operating system.
|
||||
The support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit]
|
||||
and [Blackberry QNX][BlackBerry].
|
||||
The [QNX®][qnx.com] Neutrino (nto) Real-time operating system. Known as QNX OS
|
||||
from version 8 onwards.
|
||||
|
||||
[BlackBerry]: https://blackberry.qnx.com
|
||||
This support has been implemented jointly by [Elektrobit Automotive GmbH][Elektrobit]
|
||||
and [QNX][qnx.com].
|
||||
|
||||
[qnx.com]: https://blackberry.qnx.com
|
||||
[Elektrobit]: https://www.elektrobit.com
|
||||
|
||||
## Target maintainers
|
||||
|
@ -18,21 +20,29 @@ and [Blackberry QNX][BlackBerry].
|
|||
|
||||
## Requirements
|
||||
|
||||
Currently, the following QNX Neutrino versions and compilation targets are supported:
|
||||
Currently, the following QNX versions and compilation targets are supported:
|
||||
|
||||
| QNX Neutrino Version | Target Architecture | Full support | `no_std` support |
|
||||
|----------------------|---------------------|:------------:|:----------------:|
|
||||
| 7.1 | AArch64 | ✓ | ✓ |
|
||||
| 7.1 | x86_64 | ✓ | ✓ |
|
||||
| 7.0 | AArch64 | ? | ✓ |
|
||||
| 7.0 | x86 | | ✓ |
|
||||
| Target Tuple | QNX Version | Target Architecture | Full support | `no_std` support |
|
||||
| ----------------------------------- | ----------------------------- | ------------------- | :----------: | :--------------: |
|
||||
| `aarch64-unknown-nto-qnx800` | QNX OS 8.0 | AArch64 | ? | ✓ |
|
||||
| `x86_64-pc-nto-qnx800` | QNX OS 8.0 | x86_64 | ? | ✓ |
|
||||
| `aarch64-unknown-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | AArch64 | ✓ | ✓ |
|
||||
| `x86_64-pc-nto-qnx710` | QNX Neutrino 7.1 with io-pkt | x86_64 | ✓ | ✓ |
|
||||
| `aarch64-unknown-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | AArch64 | ? | ✓ |
|
||||
| `x86_64-pc-nto-qnx710_iosock` | QNX Neutrino 7.1 with io-sock | x86_64 | ? | ✓ |
|
||||
| `aarch64-unknown-nto-qnx700` | QNX Neutrino 7.0 | AArch64 | ? | ✓ |
|
||||
| `i586-pc-nto-qnx700` | QNX Neutrino 7.0 | x86 | | ✓ |
|
||||
|
||||
Adding other architectures that are supported by QNX Neutrino is possible.
|
||||
On QNX Neutrino 7.0 and 7.1, `io-pkt` is used as network stack by default.
|
||||
QNX Neutrino 7.1 includes the optional network stack `io-sock`.
|
||||
QNX OS 8.0 always uses `io-sock`. QNX OS 8.0 support is currently work in progress.
|
||||
|
||||
In the table above, 'full support' indicates support for building Rust applications with the full standard library.
|
||||
'`no_std` support' indicates that only `core` and `alloc` are available.
|
||||
Adding other architectures that are supported by QNX is possible.
|
||||
|
||||
For building or using the Rust toolchain for QNX Neutrino, the
|
||||
In the table above, 'full support' indicates support for building Rust applications with the full standard library. A '?' means that support is in-progress.
|
||||
'`no_std` support' is for building `#![no_std]` applications where only `core` and `alloc` are available.
|
||||
|
||||
For building or using the Rust toolchain for QNX, 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).
|
||||
|
@ -98,52 +108,73 @@ fn panic(_panic: &PanicInfo<'_>) -> ! {
|
|||
pub extern "C" fn rust_eh_personality() {}
|
||||
```
|
||||
|
||||
The QNX Neutrino support of Rust has been tested with QNX Neutrino 7.0 and 7.1.
|
||||
The QNX support in Rust has been tested with QNX Neutrino 7.0 and 7.1. Support for QNX OS 8.0 is a work in progress.
|
||||
|
||||
There are no further known requirements.
|
||||
|
||||
## Conditional compilation
|
||||
|
||||
For conditional compilation, following QNX Neutrino specific attributes are defined:
|
||||
For conditional compilation, following QNX specific attributes are defined:
|
||||
|
||||
- `target_os` = `"nto"`
|
||||
- `target_env` = `"nto71"` (for QNX Neutrino 7.1)
|
||||
- `target_env` = `"nto71"` (for QNX Neutrino 7.1 with "classic" network stack "io_pkt")
|
||||
- `target_env` = `"nto71_iosock"` (for QNX Neutrino 7.1 with network stack "io_sock")
|
||||
- `target_env` = `"nto70"` (for QNX Neutrino 7.0)
|
||||
- `target_env` = `"nto80"` (for QNX OS 8.0)
|
||||
|
||||
## Building the target
|
||||
|
||||
1. Create a `config.toml`
|
||||
|
||||
Example content:
|
||||
Example content:
|
||||
|
||||
```toml
|
||||
profile = "compiler"
|
||||
change-id = 115898
|
||||
```
|
||||
```toml
|
||||
profile = "compiler"
|
||||
change-id = 999999
|
||||
```
|
||||
|
||||
2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host (for both `aarch64` and `x86_64` targets)
|
||||
2. Compile the Rust toolchain for an `x86_64-unknown-linux-gnu` host
|
||||
|
||||
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).
|
||||
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):
|
||||
To compile for QNX, environment variables must be set to use the correct tools and compiler switches:
|
||||
|
||||
```bash
|
||||
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'
|
||||
- `CC_<target>=qcc`
|
||||
- `CFLAGS_<target>=<nto_cflag>`
|
||||
- `CXX_<target>=qcc`
|
||||
- `AR_<target>=<nto_ar>`
|
||||
|
||||
env $build_env \
|
||||
./x.py build \
|
||||
--target aarch64-unknown-nto-qnx710,x86_64-pc-nto-qnx710,x86_64-unknown-linux-gnu \
|
||||
rustc library/core library/alloc library/std
|
||||
```
|
||||
With:
|
||||
|
||||
- `<target>` target triplet using underscores instead of hyphens, e.g. `aarch64_unknown_nto_qnx710`
|
||||
- `<nto_cflag>`
|
||||
|
||||
- `-Vgcc_ntox86_cxx` for x86 (32 bit)
|
||||
- `-Vgcc_ntox86_64_cxx` for x86_64 (64 bit)
|
||||
- `-Vgcc_ntoaarch64le_cxx` for Aarch64 (64 bit)
|
||||
|
||||
- `<nto_ar>`
|
||||
|
||||
- `ntox86-ar` for x86 (32 bit)
|
||||
- `ntox86_64-ar` for x86_64 (64 bit)
|
||||
- `ntoaarch64-ar` for Aarch64 (64 bit)
|
||||
|
||||
Example to build the Rust toolchain including a standard library for x86_64-linux-gnu and Aarch64-QNX-7.1:
|
||||
|
||||
```bash
|
||||
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
|
||||
'
|
||||
|
||||
env $build_env \
|
||||
./x.py build \
|
||||
--target x86_64-unknown-linux-gnu,aarch64-unknown-nto-qnx710 \
|
||||
rustc library/core library/alloc library/std
|
||||
```
|
||||
|
||||
## Running the Rust test suite
|
||||
|
||||
|
@ -153,19 +184,11 @@ 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:
|
||||
To run all tests on a x86_64 QNX Neutrino 7.1 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'
|
||||
export build_env=<see above>
|
||||
|
||||
# Disable tests that only work on the host or don't make sense for this target.
|
||||
# See also:
|
||||
|
@ -195,7 +218,7 @@ or build your own copy of `core` by using `build-std` or similar.
|
|||
|
||||
## Testing
|
||||
|
||||
Compiled executables can run directly on QNX Neutrino.
|
||||
Compiled executables can run directly on QNX.
|
||||
|
||||
### Rust std library test suite
|
||||
|
||||
|
|
|
@ -57,6 +57,12 @@
|
|||
//@ revisions: aarch64_unknown_nto_qnx710
|
||||
//@ [aarch64_unknown_nto_qnx710] compile-flags: --target aarch64-unknown-nto-qnx710
|
||||
//@ [aarch64_unknown_nto_qnx710] needs-llvm-components: aarch64
|
||||
//@ revisions: aarch64_unknown_nto_qnx710_iosock
|
||||
//@ [aarch64_unknown_nto_qnx710_iosock] compile-flags: --target aarch64-unknown-nto-qnx710_iosock
|
||||
//@ [aarch64_unknown_nto_qnx710_iosock] needs-llvm-components: aarch64
|
||||
//@ revisions: aarch64_unknown_nto_qnx800
|
||||
//@ [aarch64_unknown_nto_qnx800] compile-flags: --target aarch64-unknown-nto-qnx800
|
||||
//@ [aarch64_unknown_nto_qnx800] needs-llvm-components: aarch64
|
||||
//@ revisions: aarch64_unknown_openbsd
|
||||
//@ [aarch64_unknown_openbsd] compile-flags: --target aarch64-unknown-openbsd
|
||||
//@ [aarch64_unknown_openbsd] needs-llvm-components: aarch64
|
||||
|
@ -564,6 +570,12 @@
|
|||
//@ revisions: x86_64_pc_nto_qnx710
|
||||
//@ [x86_64_pc_nto_qnx710] compile-flags: --target x86_64-pc-nto-qnx710
|
||||
//@ [x86_64_pc_nto_qnx710] needs-llvm-components: x86
|
||||
//@ revisions: x86_64_pc_nto_qnx710_iosock
|
||||
//@ [x86_64_pc_nto_qnx710_iosock] compile-flags: --target x86_64-pc-nto-qnx710_iosock
|
||||
//@ [x86_64_pc_nto_qnx710_iosock] needs-llvm-components: x86
|
||||
//@ revisions: x86_64_pc_nto_qnx800
|
||||
//@ [x86_64_pc_nto_qnx800] compile-flags: --target x86_64-pc-nto-qnx800
|
||||
//@ [x86_64_pc_nto_qnx800] needs-llvm-components: x86
|
||||
//@ revisions: x86_64_pc_solaris
|
||||
//@ [x86_64_pc_solaris] compile-flags: --target x86_64-pc-solaris
|
||||
//@ [x86_64_pc_solaris] needs-llvm-components: x86
|
||||
|
|
|
@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
|||
LL | target_env = "_UNEXPECTED_VALUE",
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc`
|
||||
= note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `nto71_iosock`, `nto80`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc`
|
||||
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
|
||||
|
||||
warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue