rustc_target/spec/base/
nto_qnx.rs

1use crate::spec::{
2    Cc, LinkArgs, LinkerFlavor, Lld, RelroLevel, Target, TargetMetadata, TargetOptions, cvs,
3};
4
5pub(crate) fn opts() -> TargetOptions {
6    TargetOptions {
7        crt_static_respected: true,
8        dynamic_linking: true,
9        executables: true,
10        families: cvs!["unix"],
11        has_rpath: true,
12        has_thread_local: false,
13        linker: Some("qcc".into()),
14        os: "nto".into(),
15        position_independent_executables: true,
16        static_position_independent_executables: true,
17        relro_level: RelroLevel::Full,
18        ..Default::default()
19    }
20}
21
22pub(crate) fn meta() -> TargetMetadata {
23    TargetMetadata { description: None, tier: Some(3), host_tools: Some(false), std: Some(true) }
24}
25
26pub(crate) fn aarch64() -> Target {
27    Target {
28        llvm_target: "aarch64-unknown-unknown".into(),
29        metadata: meta(),
30        pointer_width: 64,
31        // from: https://llvm.org/docs/LangRef.html#data-layout
32        // e         = little endian
33        // m:e       = ELF mangling: Private symbols get a .L prefix
34        // i8:8:32   = 8-bit-integer, minimum_alignment=8, preferred_alignment=32
35        // i16:16:32 = 16-bit-integer, minimum_alignment=16, preferred_alignment=32
36        // i64:64    = 64-bit-integer, minimum_alignment=64, preferred_alignment=64
37        // i128:128  = 128-bit-integer, minimum_alignment=128, preferred_alignment=128
38        // n32:64    = 32 and 64 are native integer widths; Elements of this set are considered to support most general arithmetic operations efficiently.
39        // S128      = 128 bits are the natural alignment of the stack in bits.
40        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(),
41        arch: "aarch64".into(),
42        options: TargetOptions {
43            features: "+v8a".into(),
44            max_atomic_width: Some(128),
45            ..opts()
46        }
47    }
48}
49
50pub(crate) fn x86_64() -> Target {
51    Target {
52        llvm_target: "x86_64-pc-unknown".into(),
53        metadata: meta(),
54        pointer_width: 64,
55        data_layout:
56            "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
57        arch: "x86_64".into(),
58        options: TargetOptions {
59            cpu: "x86-64".into(),
60            plt_by_default: false,
61            max_atomic_width: Some(64),
62            vendor: "pc".into(),
63            ..opts()
64        },
65    }
66}
67
68pub(crate) fn pre_link_args(api_var: ApiVariant, arch: Arch) -> LinkArgs {
69    let (qcc_arg, arch_lib_dir) = match arch {
70        Arch::Aarch64 => ("-Vgcc_ntoaarch64le_cxx", "aarch64le"),
71        Arch::I586 => {
72            ("-Vgcc_ntox86_cxx", "notSupportedByQnx_compiler/rustc_target/src/spec/base/nto_qnx.rs")
73        }
74        Arch::X86_64 => ("-Vgcc_ntox86_64_cxx", "x86_64"),
75    };
76    match api_var {
77        ApiVariant::Default => {
78            TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[qcc_arg])
79        }
80        ApiVariant::IoSock => TargetOptions::link_args(
81            LinkerFlavor::Gnu(Cc::Yes, Lld::No),
82            &[qcc_arg, get_iosock_param(arch_lib_dir)],
83        ),
84    }
85}
86
87pub(crate) enum ApiVariant {
88    Default,
89    IoSock,
90}
91
92pub(crate) enum Arch {
93    Aarch64,
94    I586,
95    X86_64,
96}
97
98// When using `io-sock` on QNX, we must add a search path for the linker so
99// that it prefers the io-sock version.
100// The path depends on the host, i.e. we cannot hard-code it here, but have
101// to determine it when the compiler runs.
102// When using the QNX toolchain, the environment variable QNX_TARGET is always set.
103// More information:
104// https://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.io_sock/topic/migrate_app.html
105fn get_iosock_param(arch_lib_dir: &str) -> &'static str {
106    let target_dir = std::env::var("QNX_TARGET")
107        .unwrap_or_else(|_| "QNX_TARGET_not_set_please_source_qnxsdp-env.sh".into());
108    let linker_param = format!("-L{target_dir}/{arch_lib_dir}/io-sock/lib");
109
110    // FIXME: leaking this is kind of weird: we're feeding these into something that expects an
111    // `AsRef<OsStr>`, but often converts to `OsString` anyways, so shouldn't we just demand an `OsString`?
112    linker_param.leak()
113}