Skip to content

Commit

Permalink
Move common code to mod nto_qnx
Browse files Browse the repository at this point in the history
  • Loading branch information
flba-eb committed Nov 30, 2024
1 parent e4fee66 commit 3d8d21a
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 137 deletions.
95 changes: 94 additions & 1 deletion compiler/rustc_target/src/spec/base/nto_qnx.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -16,3 +18,94 @@ 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");

linker_param.leak()
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
use crate::spec::Target;
use crate::spec::base::nto_qnx;

pub(crate) fn target() -> Target {
let mut target = super::aarch64_unknown_nto_qnx710::target();
target.options.env = "nto71_iosock".into();
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 =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
"-Vgcc_ntoaarch64le_cxx",
get_iosock_param(),
]);
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::Aarch64);
target.options.env = "nto71_iosock".into();
target
}

// 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() -> &'static str {
let target_dir =
std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into());
let linker_param = format!("-L{target_dir}/aarch64le/io-sock/lib");

linker_param.leak()
}
20 changes: 10 additions & 10 deletions compiler/rustc_target/src/spec/targets/i586_pc_nto_qnx700.rs
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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,
Expand Down
34 changes: 9 additions & 25 deletions compiler/rustc_target/src/spec/targets/x86_64_pc_nto_qnx710.rs
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
use crate::spec::Target;
use crate::spec::base::nto_qnx;

pub(crate) fn target() -> Target {
let mut target = super::x86_64_pc_nto_qnx710::target();
target.options.env = "nto71_iosock".into();
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 =
TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[
"-Vgcc_ntox86_64_cxx",
get_iosock_param(),
]);
nto_qnx::pre_link_args(nto_qnx::ApiVariant::IoSock, nto_qnx::Arch::X86_64);
target.options.env = "nto71_iosock".into();
target
}

// 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() -> &'static str {
let target_dir =
std::env::var("QNX_TARGET").unwrap_or_else(|_| "PLEASE_SET_ENV_VAR_QNX_TARGET".into());
let linker_param = format!("-L{target_dir}/x86_64/io-sock/lib");

linker_param.leak()
}
43 changes: 24 additions & 19 deletions src/doc/rustc/src/platform-support/nto-qnx.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,31 @@ To compile for QNX Neutrino (aarch64 and x86_64) and Linux (x86_64):

```bash
export build_env='
CC_aarch64-unknown-nto-qnx710=qcc
CFLAGS_aarch64-unknown-nto-qnx710=-Vgcc_ntoaarch64le_cxx
CXX_aarch64-unknown-nto-qnx710=qcc
CC_i586_pc_nto_qnx700=qcc
CFLAGS_i586_pc_nto_qnx700=-Vgcc_ntox86_cxx
CXX_i586_pc_nto_qnx700=qcc
AR_i586_pc_nto_qnx700=ntox86-ar
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_aarch64-unknown-nto-qnx710_iosock=qcc
CFLAGS_aarch64-unknown-nto-qnx710_iosock=-Vgcc_ntoaarch64le_cxx
CXX_aarch64-unknown-nto-qnx710_iosock=qcc
CC_aarch64_unknown_nto_qnx710_iosock=qcc
CFLAGS_aarch64_unknown_nto_qnx710_iosock=-Vgcc_ntoaarch64le_cxx
CXX_aarch64_unknown_nto_qnx710_iosock=qcc
AR_aarch64_unknown_nto_qnx710_iosock=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_aarch64_unknown_nto_qnx700=qcc
CFLAGS_aarch64_unknown_nto_qnx700=-Vgcc_ntoaarch64le_cxx
CXX_aarch64_unknown_nto_qnx700=qcc
AR_aarch64_unknown_nto_qnx700=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 \
Expand All @@ -167,15 +180,7 @@ 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'
export build_env=<see above>

# Disable tests that only work on the host or don't make sense for this target.
# See also:
Expand Down

0 comments on commit 3d8d21a

Please sign in to comment.