1
- use crate :: spec:: { RelroLevel , TargetOptions , cvs} ;
1
+ use crate :: spec:: {
2
+ Cc , LinkArgs , LinkerFlavor , Lld , RelroLevel , Target , TargetMetadata , TargetOptions , cvs,
3
+ } ;
2
4
3
5
pub ( crate ) fn opts ( ) -> TargetOptions {
4
6
TargetOptions {
@@ -16,3 +18,96 @@ pub(crate) fn opts() -> TargetOptions {
16
18
..Default :: default ( )
17
19
}
18
20
}
21
+
22
+ pub ( crate ) fn meta ( ) -> TargetMetadata {
23
+ TargetMetadata { description : None , tier : Some ( 3 ) , host_tools : Some ( false ) , std : Some ( true ) }
24
+ }
25
+
26
+ pub ( 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
+
50
+ pub ( 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
+
68
+ pub ( 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 ( LinkerFlavor :: Gnu ( Cc :: Yes , Lld :: No ) , & [
81
+ qcc_arg,
82
+ get_iosock_param ( arch_lib_dir) ,
83
+ ] ) ,
84
+ }
85
+ }
86
+
87
+ pub ( crate ) enum ApiVariant {
88
+ Default ,
89
+ IoSock ,
90
+ }
91
+
92
+ pub ( 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
105
+ fn 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
+ }
0 commit comments