]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131) | |
12 | //! | |
13 | //! Rust targets a wide variety of usecases, and in the interest of flexibility, | |
14 | //! allows new target triples to be defined in configuration files. Most users | |
15 | //! will not need to care about these, but this is invaluable when porting Rust | |
16 | //! to a new platform, and allows for an unprecedented level of control over how | |
17 | //! the compiler works. | |
18 | //! | |
19 | //! # Using custom targets | |
20 | //! | |
21 | //! A target triple, as passed via `rustc --target=TRIPLE`, will first be | |
22 | //! compared against the list of built-in targets. This is to ease distributing | |
23 | //! rustc (no need for configuration files) and also to hold these built-in | |
24 | //! targets as immutable and sacred. If `TRIPLE` is not one of the built-in | |
25 | //! targets, rustc will check if a file named `TRIPLE` exists. If it does, it | |
26 | //! will be loaded as the target configuration. If the file does not exist, | |
27 | //! rustc will search each directory in the environment variable | |
28 | //! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will | |
29 | //! be loaded. If no file is found in any of those directories, a fatal error | |
a7813a04 | 30 | //! will be given. |
1a4d82fc JJ |
31 | //! |
32 | //! Projects defining their own targets should use | |
33 | //! `--target=path/to/my-awesome-platform.json` instead of adding to | |
34 | //! `RUST_TARGET_PATH`. | |
35 | //! | |
36 | //! # Defining a new target | |
37 | //! | |
38 | //! Targets are defined using [JSON](http://json.org/). The `Target` struct in | |
39 | //! this module defines the format the JSON file should take, though each | |
40 | //! underscore in the field names should be replaced with a hyphen (`-`) in the | |
41 | //! JSON file. Some fields are required in every target specification, such as | |
54a0048b SL |
42 | //! `llvm-target`, `target-endian`, `target-pointer-width`, `data-layout`, |
43 | //! `arch`, and `os`. In general, options passed to rustc with `-C` override | |
44 | //! the target's settings, though `target-feature` and `link-args` will *add* | |
45 | //! to the list specified by the target, rather than replace. | |
1a4d82fc | 46 | |
5bcae85e SL |
47 | use serialize::json::{Json, ToJson}; |
48 | use std::collections::BTreeMap; | |
1a4d82fc | 49 | use std::default::Default; |
c34b1796 | 50 | use std::io::prelude::*; |
c30ab7b3 SL |
51 | use syntax::abi::{Abi, lookup as lookup_abi}; |
52 | ||
cc61c64b | 53 | use {LinkerFlavor, PanicStrategy}; |
1a4d82fc | 54 | |
d9579d0f | 55 | mod android_base; |
1a4d82fc | 56 | mod apple_base; |
85aaf69f | 57 | mod apple_ios_base; |
c30ab7b3 | 58 | mod arm_base; |
c34b1796 | 59 | mod bitrig_base; |
d9579d0f | 60 | mod dragonfly_base; |
32a655c1 | 61 | mod emscripten_base; |
d9579d0f | 62 | mod freebsd_base; |
9e0c209e | 63 | mod haiku_base; |
d9579d0f | 64 | mod linux_base; |
a7813a04 | 65 | mod linux_musl_base; |
85aaf69f | 66 | mod openbsd_base; |
c1a9b12d | 67 | mod netbsd_base; |
7453a54e | 68 | mod solaris_base; |
d9579d0f | 69 | mod windows_base; |
62682a34 | 70 | mod windows_msvc_base; |
c30ab7b3 SL |
71 | mod thumb_base; |
72 | mod fuchsia_base; | |
32a655c1 | 73 | mod redox_base; |
1a4d82fc | 74 | |
cc61c64b | 75 | pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>; |
5bcae85e SL |
76 | pub type TargetResult = Result<Target, String>; |
77 | ||
7453a54e | 78 | macro_rules! supported_targets { |
c30ab7b3 | 79 | ( $(($triple:expr, $module:ident),)+ ) => ( |
7453a54e SL |
80 | $(mod $module;)* |
81 | ||
82 | /// List of supported targets | |
5bcae85e SL |
83 | const TARGETS: &'static [&'static str] = &[$($triple),*]; |
84 | ||
85 | fn load_specific(target: &str) -> TargetResult { | |
86 | match target { | |
87 | $( | |
88 | $triple => { | |
9e0c209e | 89 | let mut t = $module::target()?; |
5bcae85e SL |
90 | t.options.is_builtin = true; |
91 | ||
92 | // round-trip through the JSON parser to ensure at | |
93 | // run-time that the parser works correctly | |
9e0c209e | 94 | t = Target::from_json(t.to_json())?; |
5bcae85e SL |
95 | debug!("Got builtin target: {:?}", t); |
96 | Ok(t) | |
97 | }, | |
98 | )+ | |
99 | _ => Err(format!("Unable to find target: {}", target)) | |
100 | } | |
101 | } | |
102 | ||
103 | pub fn get_targets() -> Box<Iterator<Item=String>> { | |
104 | Box::new(TARGETS.iter().filter_map(|t| -> Option<String> { | |
105 | load_specific(t) | |
106 | .and(Ok(t.to_string())) | |
107 | .ok() | |
108 | })) | |
109 | } | |
110 | ||
111 | #[cfg(test)] | |
112 | mod test_json_encode_decode { | |
113 | use serialize::json::ToJson; | |
114 | use super::Target; | |
115 | $(use super::$module;)* | |
7453a54e | 116 | |
7453a54e | 117 | $( |
5bcae85e SL |
118 | #[test] |
119 | fn $module() { | |
120 | // Grab the TargetResult struct. If we successfully retrieved | |
121 | // a Target, then the test JSON encoding/decoding can run for this | |
122 | // Target on this testing platform (i.e., checking the iOS targets | |
123 | // only on a Mac test platform). | |
124 | let _ = $module::target().map(|original| { | |
125 | let as_json = original.to_json(); | |
126 | let parsed = Target::from_json(as_json).unwrap(); | |
127 | assert_eq!(original, parsed); | |
128 | }); | |
7453a54e SL |
129 | } |
130 | )* | |
7453a54e SL |
131 | } |
132 | ) | |
133 | } | |
134 | ||
135 | supported_targets! { | |
136 | ("x86_64-unknown-linux-gnu", x86_64_unknown_linux_gnu), | |
137 | ("i686-unknown-linux-gnu", i686_unknown_linux_gnu), | |
138 | ("i586-unknown-linux-gnu", i586_unknown_linux_gnu), | |
139 | ("mips-unknown-linux-gnu", mips_unknown_linux_gnu), | |
9e0c209e SL |
140 | ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64), |
141 | ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64), | |
7453a54e SL |
142 | ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), |
143 | ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), | |
144 | ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), | |
145 | ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), | |
9e0c209e | 146 | ("s390x-unknown-linux-gnu", s390x_unknown_linux_gnu), |
7453a54e SL |
147 | ("arm-unknown-linux-gnueabi", arm_unknown_linux_gnueabi), |
148 | ("arm-unknown-linux-gnueabihf", arm_unknown_linux_gnueabihf), | |
5bcae85e SL |
149 | ("arm-unknown-linux-musleabi", arm_unknown_linux_musleabi), |
150 | ("arm-unknown-linux-musleabihf", arm_unknown_linux_musleabihf), | |
476ff2be | 151 | ("armv5te-unknown-linux-gnueabi", armv5te_unknown_linux_gnueabi), |
7453a54e | 152 | ("armv7-unknown-linux-gnueabihf", armv7_unknown_linux_gnueabihf), |
5bcae85e | 153 | ("armv7-unknown-linux-musleabihf", armv7_unknown_linux_musleabihf), |
7453a54e SL |
154 | ("aarch64-unknown-linux-gnu", aarch64_unknown_linux_gnu), |
155 | ("x86_64-unknown-linux-musl", x86_64_unknown_linux_musl), | |
156 | ("i686-unknown-linux-musl", i686_unknown_linux_musl), | |
157 | ("mips-unknown-linux-musl", mips_unknown_linux_musl), | |
158 | ("mipsel-unknown-linux-musl", mipsel_unknown_linux_musl), | |
9e0c209e SL |
159 | ("mips-unknown-linux-uclibc", mips_unknown_linux_uclibc), |
160 | ("mipsel-unknown-linux-uclibc", mipsel_unknown_linux_uclibc), | |
7453a54e | 161 | |
32a655c1 SL |
162 | ("sparc64-unknown-linux-gnu", sparc64_unknown_linux_gnu), |
163 | ||
7453a54e | 164 | ("i686-linux-android", i686_linux_android), |
cc61c64b | 165 | ("x86_64-linux-android", x86_64_linux_android), |
7453a54e | 166 | ("arm-linux-androideabi", arm_linux_androideabi), |
a7813a04 | 167 | ("armv7-linux-androideabi", armv7_linux_androideabi), |
7453a54e SL |
168 | ("aarch64-linux-android", aarch64_linux_android), |
169 | ||
8bb4bdeb | 170 | ("aarch64-unknown-freebsd", aarch64_unknown_freebsd), |
7453a54e SL |
171 | ("i686-unknown-freebsd", i686_unknown_freebsd), |
172 | ("x86_64-unknown-freebsd", x86_64_unknown_freebsd), | |
173 | ||
174 | ("i686-unknown-dragonfly", i686_unknown_dragonfly), | |
175 | ("x86_64-unknown-dragonfly", x86_64_unknown_dragonfly), | |
176 | ||
177 | ("x86_64-unknown-bitrig", x86_64_unknown_bitrig), | |
476ff2be SL |
178 | |
179 | ("i686-unknown-openbsd", i686_unknown_openbsd), | |
7453a54e | 180 | ("x86_64-unknown-openbsd", x86_64_unknown_openbsd), |
476ff2be | 181 | |
8bb4bdeb | 182 | ("i686-unknown-netbsd", i686_unknown_netbsd), |
32a655c1 | 183 | ("sparc64-unknown-netbsd", sparc64_unknown_netbsd), |
7453a54e SL |
184 | ("x86_64-unknown-netbsd", x86_64_unknown_netbsd), |
185 | ("x86_64-rumprun-netbsd", x86_64_rumprun_netbsd), | |
186 | ||
c30ab7b3 SL |
187 | ("i686-unknown-haiku", i686_unknown_haiku), |
188 | ("x86_64-unknown-haiku", x86_64_unknown_haiku), | |
9e0c209e | 189 | |
7453a54e SL |
190 | ("x86_64-apple-darwin", x86_64_apple_darwin), |
191 | ("i686-apple-darwin", i686_apple_darwin), | |
192 | ||
c30ab7b3 SL |
193 | ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia), |
194 | ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia), | |
195 | ||
32a655c1 SL |
196 | ("x86_64-unknown-redox", x86_64_unknown_redox), |
197 | ||
7453a54e SL |
198 | ("i386-apple-ios", i386_apple_ios), |
199 | ("x86_64-apple-ios", x86_64_apple_ios), | |
200 | ("aarch64-apple-ios", aarch64_apple_ios), | |
201 | ("armv7-apple-ios", armv7_apple_ios), | |
202 | ("armv7s-apple-ios", armv7s_apple_ios), | |
203 | ||
204 | ("x86_64-sun-solaris", x86_64_sun_solaris), | |
8bb4bdeb | 205 | ("sparcv9-sun-solaris", sparcv9_sun_solaris), |
7453a54e SL |
206 | |
207 | ("x86_64-pc-windows-gnu", x86_64_pc_windows_gnu), | |
208 | ("i686-pc-windows-gnu", i686_pc_windows_gnu), | |
209 | ||
210 | ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc), | |
211 | ("i686-pc-windows-msvc", i686_pc_windows_msvc), | |
54a0048b | 212 | ("i586-pc-windows-msvc", i586_pc_windows_msvc), |
7453a54e SL |
213 | |
214 | ("le32-unknown-nacl", le32_unknown_nacl), | |
c30ab7b3 SL |
215 | ("asmjs-unknown-emscripten", asmjs_unknown_emscripten), |
216 | ("wasm32-unknown-emscripten", wasm32_unknown_emscripten), | |
041b39d2 | 217 | ("wasm32-experimental-emscripten", wasm32_experimental_emscripten), |
c30ab7b3 SL |
218 | |
219 | ("thumbv6m-none-eabi", thumbv6m_none_eabi), | |
220 | ("thumbv7m-none-eabi", thumbv7m_none_eabi), | |
221 | ("thumbv7em-none-eabi", thumbv7em_none_eabi), | |
222 | ("thumbv7em-none-eabihf", thumbv7em_none_eabihf), | |
041b39d2 XL |
223 | |
224 | ("msp430-none-elf", msp430_none_elf), | |
7453a54e SL |
225 | } |
226 | ||
1a4d82fc JJ |
227 | /// Everything `rustc` knows about how to compile for a specific target. |
228 | /// | |
229 | /// Every field here must be specified, and has no default value. | |
5bcae85e | 230 | #[derive(PartialEq, Clone, Debug)] |
1a4d82fc | 231 | pub struct Target { |
1a4d82fc JJ |
232 | /// Target triple to pass to LLVM. |
233 | pub llvm_target: String, | |
234 | /// String to use as the `target_endian` `cfg` variable. | |
235 | pub target_endian: String, | |
236 | /// String to use as the `target_pointer_width` `cfg` variable. | |
237 | pub target_pointer_width: String, | |
238 | /// OS name to use for conditional compilation. | |
239 | pub target_os: String, | |
d9579d0f AL |
240 | /// Environment name to use for conditional compilation. |
241 | pub target_env: String, | |
b039eaaf SL |
242 | /// Vendor name to use for conditional compilation. |
243 | pub target_vendor: String, | |
7453a54e SL |
244 | /// Architecture to use for ABI considerations. Valid options: "x86", |
245 | /// "x86_64", "arm", "aarch64", "mips", "powerpc", and "powerpc64". | |
1a4d82fc | 246 | pub arch: String, |
54a0048b SL |
247 | /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. |
248 | pub data_layout: String, | |
cc61c64b XL |
249 | /// Linker flavor |
250 | pub linker_flavor: LinkerFlavor, | |
1a4d82fc JJ |
251 | /// Optional settings with defaults. |
252 | pub options: TargetOptions, | |
253 | } | |
254 | ||
255 | /// Optional aspects of a target specification. | |
256 | /// | |
257 | /// This has an implementation of `Default`, see each field for what the default is. In general, | |
258 | /// these try to take "minimal defaults" that don't assume anything about the runtime they run in. | |
5bcae85e | 259 | #[derive(PartialEq, Clone, Debug)] |
1a4d82fc | 260 | pub struct TargetOptions { |
54a0048b SL |
261 | /// Whether the target is built-in or loaded from a custom target specification. |
262 | pub is_builtin: bool, | |
263 | ||
1a4d82fc JJ |
264 | /// Linker to invoke. Defaults to "cc". |
265 | pub linker: String, | |
62682a34 SL |
266 | /// Archive utility to use when managing archives. Defaults to "ar". |
267 | pub ar: String, | |
92a42be0 | 268 | |
d9579d0f AL |
269 | /// Linker arguments that are unconditionally passed *before* any |
270 | /// user-defined libraries. | |
cc61c64b | 271 | pub pre_link_args: LinkArgs, |
92a42be0 SL |
272 | /// Objects to link before all others, always found within the |
273 | /// sysroot folder. | |
274 | pub pre_link_objects_exe: Vec<String>, // ... when linking an executable | |
275 | pub pre_link_objects_dll: Vec<String>, // ... when linking a dylib | |
276 | /// Linker arguments that are unconditionally passed after any | |
277 | /// user-defined but before post_link_objects. Standard platform | |
278 | /// libraries that should be always be linked to, usually go here. | |
cc61c64b | 279 | pub late_link_args: LinkArgs, |
92a42be0 SL |
280 | /// Objects to link after all others, always found within the |
281 | /// sysroot folder. | |
282 | pub post_link_objects: Vec<String>, | |
d9579d0f AL |
283 | /// Linker arguments that are unconditionally passed *after* any |
284 | /// user-defined libraries. | |
cc61c64b | 285 | pub post_link_args: LinkArgs, |
92a42be0 | 286 | |
041b39d2 XL |
287 | /// Environment variables to be set before invoking the linker. |
288 | pub link_env: Vec<(String, String)>, | |
289 | ||
32a655c1 SL |
290 | /// Extra arguments to pass to the external assembler (when used) |
291 | pub asm_args: Vec<String>, | |
292 | ||
d9579d0f | 293 | /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults |
a7813a04 | 294 | /// to "generic". |
1a4d82fc | 295 | pub cpu: String, |
d9579d0f AL |
296 | /// Default target features to pass to LLVM. These features will *always* be |
297 | /// passed, and cannot be disabled even via `-C`. Corresponds to `llc | |
298 | /// -mattr=$features`. | |
1a4d82fc JJ |
299 | pub features: String, |
300 | /// Whether dynamic linking is available on this target. Defaults to false. | |
301 | pub dynamic_linking: bool, | |
302 | /// Whether executables are available on this target. iOS, for example, only allows static | |
303 | /// libraries. Defaults to false. | |
304 | pub executables: bool, | |
1a4d82fc JJ |
305 | /// Relocation model to use in object file. Corresponds to `llc |
306 | /// -relocation-model=$relocation_model`. Defaults to "pic". | |
307 | pub relocation_model: String, | |
308 | /// Code model to use. Corresponds to `llc -code-model=$code_model`. Defaults to "default". | |
309 | pub code_model: String, | |
310 | /// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false. | |
311 | pub disable_redzone: bool, | |
312 | /// Eliminate frame pointers from stack frames if possible. Defaults to true. | |
313 | pub eliminate_frame_pointer: bool, | |
314 | /// Emit each function in its own section. Defaults to true. | |
315 | pub function_sections: bool, | |
316 | /// String to prepend to the name of every dynamic library. Defaults to "lib". | |
317 | pub dll_prefix: String, | |
318 | /// String to append to the name of every dynamic library. Defaults to ".so". | |
319 | pub dll_suffix: String, | |
320 | /// String to append to the name of every executable. | |
321 | pub exe_suffix: String, | |
322 | /// String to prepend to the name of every static library. Defaults to "lib". | |
323 | pub staticlib_prefix: String, | |
324 | /// String to append to the name of every static library. Defaults to ".a". | |
325 | pub staticlib_suffix: String, | |
92a42be0 SL |
326 | /// OS family to use for conditional compilation. Valid options: "unix", "windows". |
327 | pub target_family: Option<String>, | |
476ff2be SL |
328 | /// Whether the target toolchain is like OpenBSD's. |
329 | /// Only useful for compiling against OpenBSD, for configuring abi when returning a struct. | |
330 | pub is_like_openbsd: bool, | |
cc61c64b XL |
331 | /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS, |
332 | /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false. | |
1a4d82fc | 333 | pub is_like_osx: bool, |
7453a54e SL |
334 | /// Whether the target toolchain is like Solaris's. |
335 | /// Only useful for compiling against Illumos/Solaris, | |
336 | /// as they have a different set of linker flags. Defaults to false. | |
337 | pub is_like_solaris: bool, | |
1a4d82fc | 338 | /// Whether the target toolchain is like Windows'. Only useful for compiling against Windows, |
c34b1796 | 339 | /// only really used for figuring out how to find libraries, since Windows uses its own |
1a4d82fc JJ |
340 | /// library naming convention. Defaults to false. |
341 | pub is_like_windows: bool, | |
62682a34 | 342 | pub is_like_msvc: bool, |
85aaf69f SL |
343 | /// Whether the target toolchain is like Android's. Only useful for compiling against Android. |
344 | /// Defaults to false. | |
345 | pub is_like_android: bool, | |
8bb4bdeb XL |
346 | /// Whether the target toolchain is like Emscripten's. Only useful for compiling with |
347 | /// Emscripten toolchain. | |
348 | /// Defaults to false. | |
349 | pub is_like_emscripten: bool, | |
1a4d82fc JJ |
350 | /// Whether the linker support GNU-like arguments such as -O. Defaults to false. |
351 | pub linker_is_gnu: bool, | |
5bcae85e SL |
352 | /// The MinGW toolchain has a known issue that prevents it from correctly |
353 | /// handling COFF object files with more than 2^15 sections. Since each weak | |
354 | /// symbol needs its own COMDAT section, weak linkage implies a large | |
355 | /// number sections that easily exceeds the given limit for larger | |
356 | /// codebases. Consequently we want a way to disallow weak linkage on some | |
357 | /// platforms. | |
358 | pub allows_weak_linkage: bool, | |
1a4d82fc JJ |
359 | /// Whether the linker support rpaths or not. Defaults to false. |
360 | pub has_rpath: bool, | |
b039eaaf SL |
361 | /// Whether to disable linking to the default libraries, typically corresponds |
362 | /// to `-nodefaultlibs`. Defaults to true. | |
363 | pub no_default_libraries: bool, | |
62682a34 SL |
364 | /// Dynamically linked executables can be compiled as position independent |
365 | /// if the default relocation model of position independent code is not | |
366 | /// changed. This is a requirement to take advantage of ASLR, as otherwise | |
367 | /// the functions in the executable are not randomized and can be used | |
368 | /// during an exploit of a vulnerability in any code. | |
1a4d82fc | 369 | pub position_independent_executables: bool, |
c1a9b12d SL |
370 | /// Format that archives should be emitted in. This affects whether we use |
371 | /// LLVM to assemble an archive or fall back to the system linker, and | |
372 | /// currently only "gnu" is used to fall into LLVM. Unknown strings cause | |
373 | /// the system linker to be used. | |
374 | pub archive_format: String, | |
e9174d1e SL |
375 | /// Is asm!() allowed? Defaults to true. |
376 | pub allow_asm: bool, | |
c1a9b12d SL |
377 | /// Whether the target uses a custom unwind resumption routine. |
378 | /// By default LLVM lowers `resume` instructions into calls to `_Unwind_Resume` | |
379 | /// defined in libgcc. If this option is enabled, the target must provide | |
380 | /// `eh_unwind_resume` lang item. | |
381 | pub custom_unwind_resume: bool, | |
e9174d1e | 382 | |
041b39d2 XL |
383 | /// If necessary, a different crate to link exe allocators by default |
384 | pub exe_allocation_crate: Option<String>, | |
9cc50fc6 SL |
385 | |
386 | /// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for | |
387 | /// this target. | |
388 | pub has_elf_tls: bool, | |
7453a54e SL |
389 | // This is mainly for easy compatibility with emscripten. |
390 | // If we give emcc .o files that are actually .bc files it | |
391 | // will 'just work'. | |
392 | pub obj_is_bitcode: bool, | |
a7813a04 | 393 | |
476ff2be SL |
394 | // LLVM can't produce object files for this target. Instead, we'll make LLVM |
395 | // emit assembly and then use `gcc` to turn that assembly into an object | |
396 | // file | |
397 | pub no_integrated_as: bool, | |
398 | ||
32a655c1 SL |
399 | /// Don't use this field; instead use the `.min_atomic_width()` method. |
400 | pub min_atomic_width: Option<u64>, | |
401 | ||
c30ab7b3 SL |
402 | /// Don't use this field; instead use the `.max_atomic_width()` method. |
403 | pub max_atomic_width: Option<u64>, | |
404 | ||
405 | /// Panic strategy: "unwind" or "abort" | |
406 | pub panic_strategy: PanicStrategy, | |
407 | ||
408 | /// A blacklist of ABIs unsupported by the current target. Note that generic | |
409 | /// ABIs are considered to be supported on all platforms and cannot be blacklisted. | |
410 | pub abi_blacklist: Vec<Abi>, | |
476ff2be SL |
411 | |
412 | /// Whether or not the CRT is statically linked by default. | |
413 | pub crt_static_default: bool, | |
041b39d2 XL |
414 | |
415 | /// Whether or not stack probes (__rust_probestack) are enabled | |
416 | pub stack_probes: bool, | |
1a4d82fc JJ |
417 | } |
418 | ||
419 | impl Default for TargetOptions { | |
62682a34 SL |
420 | /// Create a set of "sane defaults" for any target. This is still |
421 | /// incomplete, and if used for compilation, will certainly not work. | |
1a4d82fc JJ |
422 | fn default() -> TargetOptions { |
423 | TargetOptions { | |
54a0048b | 424 | is_builtin: false, |
e9174d1e SL |
425 | linker: option_env!("CFG_DEFAULT_LINKER").unwrap_or("cc").to_string(), |
426 | ar: option_env!("CFG_DEFAULT_AR").unwrap_or("ar").to_string(), | |
cc61c64b XL |
427 | pre_link_args: LinkArgs::new(), |
428 | post_link_args: LinkArgs::new(), | |
32a655c1 | 429 | asm_args: Vec::new(), |
1a4d82fc JJ |
430 | cpu: "generic".to_string(), |
431 | features: "".to_string(), | |
432 | dynamic_linking: false, | |
433 | executables: false, | |
1a4d82fc JJ |
434 | relocation_model: "pic".to_string(), |
435 | code_model: "default".to_string(), | |
436 | disable_redzone: false, | |
437 | eliminate_frame_pointer: true, | |
438 | function_sections: true, | |
439 | dll_prefix: "lib".to_string(), | |
440 | dll_suffix: ".so".to_string(), | |
441 | exe_suffix: "".to_string(), | |
442 | staticlib_prefix: "lib".to_string(), | |
443 | staticlib_suffix: ".a".to_string(), | |
92a42be0 | 444 | target_family: None, |
476ff2be | 445 | is_like_openbsd: false, |
1a4d82fc | 446 | is_like_osx: false, |
7453a54e | 447 | is_like_solaris: false, |
1a4d82fc | 448 | is_like_windows: false, |
85aaf69f | 449 | is_like_android: false, |
8bb4bdeb | 450 | is_like_emscripten: false, |
62682a34 | 451 | is_like_msvc: false, |
1a4d82fc | 452 | linker_is_gnu: false, |
5bcae85e | 453 | allows_weak_linkage: true, |
1a4d82fc | 454 | has_rpath: false, |
b039eaaf | 455 | no_default_libraries: true, |
1a4d82fc | 456 | position_independent_executables: false, |
92a42be0 SL |
457 | pre_link_objects_exe: Vec::new(), |
458 | pre_link_objects_dll: Vec::new(), | |
d9579d0f | 459 | post_link_objects: Vec::new(), |
cc61c64b | 460 | late_link_args: LinkArgs::new(), |
041b39d2 | 461 | link_env: Vec::new(), |
7453a54e | 462 | archive_format: "gnu".to_string(), |
c1a9b12d | 463 | custom_unwind_resume: false, |
041b39d2 | 464 | exe_allocation_crate: None, |
e9174d1e | 465 | allow_asm: true, |
9cc50fc6 | 466 | has_elf_tls: false, |
7453a54e | 467 | obj_is_bitcode: false, |
476ff2be | 468 | no_integrated_as: false, |
32a655c1 | 469 | min_atomic_width: None, |
c30ab7b3 SL |
470 | max_atomic_width: None, |
471 | panic_strategy: PanicStrategy::Unwind, | |
472 | abi_blacklist: vec![], | |
476ff2be | 473 | crt_static_default: false, |
041b39d2 | 474 | stack_probes: false, |
1a4d82fc JJ |
475 | } |
476 | } | |
477 | } | |
478 | ||
479 | impl Target { | |
480 | /// Given a function ABI, turn "System" into the correct ABI for this target. | |
7453a54e | 481 | pub fn adjust_abi(&self, abi: Abi) -> Abi { |
1a4d82fc | 482 | match abi { |
7453a54e | 483 | Abi::System => { |
1a4d82fc | 484 | if self.options.is_like_windows && self.arch == "x86" { |
7453a54e | 485 | Abi::Stdcall |
1a4d82fc | 486 | } else { |
7453a54e | 487 | Abi::C |
1a4d82fc JJ |
488 | } |
489 | }, | |
490 | abi => abi | |
491 | } | |
492 | } | |
493 | ||
32a655c1 SL |
494 | /// Minimum integer size in bits that this target can perform atomic |
495 | /// operations on. | |
496 | pub fn min_atomic_width(&self) -> u64 { | |
497 | self.options.min_atomic_width.unwrap_or(8) | |
498 | } | |
499 | ||
c30ab7b3 SL |
500 | /// Maximum integer size in bits that this target can perform atomic |
501 | /// operations on. | |
502 | pub fn max_atomic_width(&self) -> u64 { | |
503 | self.options.max_atomic_width.unwrap_or(self.target_pointer_width.parse().unwrap()) | |
504 | } | |
505 | ||
506 | pub fn is_abi_supported(&self, abi: Abi) -> bool { | |
507 | abi.generic() || !self.options.abi_blacklist.contains(&abi) | |
508 | } | |
509 | ||
1a4d82fc | 510 | /// Load a target descriptor from a JSON object. |
5bcae85e SL |
511 | pub fn from_json(obj: Json) -> TargetResult { |
512 | // While ugly, this code must remain this way to retain | |
513 | // compatibility with existing JSON fields and the internal | |
514 | // expected naming of the Target and TargetOptions structs. | |
515 | // To ensure compatibility is retained, the built-in targets | |
516 | // are round-tripped through this code to catch cases where | |
517 | // the JSON parser is not updated to match the structs. | |
1a4d82fc | 518 | |
85aaf69f | 519 | let get_req_field = |name: &str| { |
1a4d82fc JJ |
520 | match obj.find(name) |
521 | .map(|s| s.as_string()) | |
522 | .and_then(|os| os.map(|s| s.to_string())) { | |
5bcae85e | 523 | Some(val) => Ok(val), |
92a42be0 | 524 | None => { |
5bcae85e | 525 | return Err(format!("Field {} in target specification is required", name)) |
92a42be0 | 526 | } |
1a4d82fc JJ |
527 | } |
528 | }; | |
529 | ||
b039eaaf SL |
530 | let get_opt_field = |name: &str, default: &str| { |
531 | obj.find(name).and_then(|s| s.as_string()) | |
532 | .map(|s| s.to_string()) | |
533 | .unwrap_or(default.to_string()) | |
534 | }; | |
535 | ||
1a4d82fc | 536 | let mut base = Target { |
9e0c209e SL |
537 | llvm_target: get_req_field("llvm-target")?, |
538 | target_endian: get_req_field("target-endian")?, | |
539 | target_pointer_width: get_req_field("target-pointer-width")?, | |
540 | data_layout: get_req_field("data-layout")?, | |
541 | arch: get_req_field("arch")?, | |
542 | target_os: get_req_field("os")?, | |
b039eaaf SL |
543 | target_env: get_opt_field("env", ""), |
544 | target_vendor: get_opt_field("vendor", "unknown"), | |
cc61c64b XL |
545 | linker_flavor: LinkerFlavor::from_str(&*get_req_field("linker-flavor")?) |
546 | .ok_or_else(|| { | |
547 | format!("linker flavor must be {}", LinkerFlavor::one_of()) | |
548 | })?, | |
1a4d82fc JJ |
549 | options: Default::default(), |
550 | }; | |
551 | ||
552 | macro_rules! key { | |
553 | ($key_name:ident) => ( { | |
554 | let name = (stringify!($key_name)).replace("_", "-"); | |
85aaf69f | 555 | obj.find(&name[..]).map(|o| o.as_string() |
1a4d82fc JJ |
556 | .map(|s| base.options.$key_name = s.to_string())); |
557 | } ); | |
558 | ($key_name:ident, bool) => ( { | |
559 | let name = (stringify!($key_name)).replace("_", "-"); | |
85aaf69f | 560 | obj.find(&name[..]) |
1a4d82fc JJ |
561 | .map(|o| o.as_boolean() |
562 | .map(|s| base.options.$key_name = s)); | |
563 | } ); | |
c30ab7b3 | 564 | ($key_name:ident, Option<u64>) => ( { |
a7813a04 XL |
565 | let name = (stringify!($key_name)).replace("_", "-"); |
566 | obj.find(&name[..]) | |
567 | .map(|o| o.as_u64() | |
c30ab7b3 SL |
568 | .map(|s| base.options.$key_name = Some(s))); |
569 | } ); | |
570 | ($key_name:ident, PanicStrategy) => ( { | |
571 | let name = (stringify!($key_name)).replace("_", "-"); | |
572 | obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| { | |
573 | match s { | |
574 | "unwind" => base.options.$key_name = PanicStrategy::Unwind, | |
575 | "abort" => base.options.$key_name = PanicStrategy::Abort, | |
576 | _ => return Some(Err(format!("'{}' is not a valid value for \ | |
577 | panic-strategy. Use 'unwind' or 'abort'.", | |
578 | s))), | |
579 | } | |
580 | Some(Ok(())) | |
581 | })).unwrap_or(Ok(())) | |
a7813a04 | 582 | } ); |
1a4d82fc JJ |
583 | ($key_name:ident, list) => ( { |
584 | let name = (stringify!($key_name)).replace("_", "-"); | |
85aaf69f | 585 | obj.find(&name[..]).map(|o| o.as_array() |
1a4d82fc JJ |
586 | .map(|v| base.options.$key_name = v.iter() |
587 | .map(|a| a.as_string().unwrap().to_string()).collect() | |
588 | ) | |
589 | ); | |
590 | } ); | |
e9174d1e SL |
591 | ($key_name:ident, optional) => ( { |
592 | let name = (stringify!($key_name)).replace("_", "-"); | |
593 | if let Some(o) = obj.find(&name[..]) { | |
594 | base.options.$key_name = o | |
595 | .as_string() | |
596 | .map(|s| s.to_string() ); | |
597 | } | |
598 | } ); | |
cc61c64b XL |
599 | ($key_name:ident, LinkerFlavor) => ( { |
600 | let name = (stringify!($key_name)).replace("_", "-"); | |
601 | obj.find(&name[..]).and_then(|o| o.as_string().map(|s| { | |
602 | LinkerFlavor::from_str(&s).ok_or_else(|| { | |
603 | Err(format!("'{}' is not a valid value for linker-flavor. \ | |
604 | Use 'em', 'gcc', 'ld' or 'msvc.", s)) | |
605 | }) | |
606 | })).unwrap_or(Ok(())) | |
607 | } ); | |
608 | ($key_name:ident, link_args) => ( { | |
609 | let name = (stringify!($key_name)).replace("_", "-"); | |
610 | if let Some(obj) = obj.find(&name[..]).and_then(|o| o.as_object()) { | |
611 | let mut args = LinkArgs::new(); | |
612 | for (k, v) in obj { | |
613 | let k = LinkerFlavor::from_str(&k).ok_or_else(|| { | |
614 | format!("{}: '{}' is not a valid value for linker-flavor. \ | |
615 | Use 'em', 'gcc', 'ld' or 'msvc'", name, k) | |
616 | })?; | |
617 | ||
618 | let v = v.as_array().map(|a| { | |
619 | a | |
620 | .iter() | |
621 | .filter_map(|o| o.as_string()) | |
622 | .map(|s| s.to_owned()) | |
623 | .collect::<Vec<_>>() | |
624 | }).unwrap_or(vec![]); | |
625 | ||
626 | args.insert(k, v); | |
627 | } | |
628 | base.options.$key_name = args; | |
629 | } | |
630 | } ); | |
041b39d2 XL |
631 | ($key_name:ident, env) => ( { |
632 | let name = (stringify!($key_name)).replace("_", "-"); | |
633 | if let Some(a) = obj.find(&name[..]).and_then(|o| o.as_array()) { | |
634 | for o in a { | |
635 | if let Some(s) = o.as_string() { | |
636 | let p = s.split('=').collect::<Vec<_>>(); | |
637 | if p.len() == 2 { | |
638 | let k = p[0].to_string(); | |
639 | let v = p[1].to_string(); | |
640 | base.options.$key_name.push((k, v)); | |
641 | } | |
642 | } | |
643 | } | |
644 | } | |
645 | } ); | |
1a4d82fc JJ |
646 | } |
647 | ||
5bcae85e | 648 | key!(is_builtin, bool); |
1a4d82fc | 649 | key!(linker); |
5bcae85e | 650 | key!(ar); |
cc61c64b | 651 | key!(pre_link_args, link_args); |
5bcae85e SL |
652 | key!(pre_link_objects_exe, list); |
653 | key!(pre_link_objects_dll, list); | |
cc61c64b | 654 | key!(late_link_args, link_args); |
5bcae85e | 655 | key!(post_link_objects, list); |
cc61c64b | 656 | key!(post_link_args, link_args); |
041b39d2 | 657 | key!(link_env, env); |
32a655c1 | 658 | key!(asm_args, list); |
5bcae85e SL |
659 | key!(cpu); |
660 | key!(features); | |
661 | key!(dynamic_linking, bool); | |
662 | key!(executables, bool); | |
1a4d82fc JJ |
663 | key!(relocation_model); |
664 | key!(code_model); | |
5bcae85e SL |
665 | key!(disable_redzone, bool); |
666 | key!(eliminate_frame_pointer, bool); | |
667 | key!(function_sections, bool); | |
1a4d82fc JJ |
668 | key!(dll_prefix); |
669 | key!(dll_suffix); | |
670 | key!(exe_suffix); | |
671 | key!(staticlib_prefix); | |
672 | key!(staticlib_suffix); | |
92a42be0 | 673 | key!(target_family, optional); |
476ff2be | 674 | key!(is_like_openbsd, bool); |
1a4d82fc | 675 | key!(is_like_osx, bool); |
5bcae85e | 676 | key!(is_like_solaris, bool); |
1a4d82fc | 677 | key!(is_like_windows, bool); |
a7813a04 | 678 | key!(is_like_msvc, bool); |
8bb4bdeb | 679 | key!(is_like_emscripten, bool); |
5bcae85e | 680 | key!(is_like_android, bool); |
1a4d82fc | 681 | key!(linker_is_gnu, bool); |
5bcae85e | 682 | key!(allows_weak_linkage, bool); |
1a4d82fc | 683 | key!(has_rpath, bool); |
b039eaaf | 684 | key!(no_default_libraries, bool); |
5bcae85e | 685 | key!(position_independent_executables, bool); |
92a42be0 | 686 | key!(archive_format); |
e9174d1e | 687 | key!(allow_asm, bool); |
92a42be0 | 688 | key!(custom_unwind_resume, bool); |
041b39d2 | 689 | key!(exe_allocation_crate, optional); |
5bcae85e SL |
690 | key!(has_elf_tls, bool); |
691 | key!(obj_is_bitcode, bool); | |
476ff2be | 692 | key!(no_integrated_as, bool); |
c30ab7b3 | 693 | key!(max_atomic_width, Option<u64>); |
32a655c1 | 694 | key!(min_atomic_width, Option<u64>); |
c30ab7b3 | 695 | try!(key!(panic_strategy, PanicStrategy)); |
476ff2be | 696 | key!(crt_static_default, bool); |
041b39d2 | 697 | key!(stack_probes, bool); |
c30ab7b3 SL |
698 | |
699 | if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) { | |
700 | for name in array.iter().filter_map(|abi| abi.as_string()) { | |
701 | match lookup_abi(name) { | |
702 | Some(abi) => { | |
703 | if abi.generic() { | |
704 | return Err(format!("The ABI \"{}\" is considered to be supported on \ | |
705 | all targets and cannot be blacklisted", abi)) | |
706 | } | |
707 | ||
708 | base.options.abi_blacklist.push(abi) | |
709 | } | |
710 | None => return Err(format!("Unknown ABI \"{}\" in target specification", name)) | |
711 | } | |
712 | } | |
713 | } | |
1a4d82fc | 714 | |
5bcae85e | 715 | Ok(base) |
1a4d82fc JJ |
716 | } |
717 | ||
c34b1796 AL |
718 | /// Search RUST_TARGET_PATH for a JSON file specifying the given target |
719 | /// triple. Note that it could also just be a bare filename already, so also | |
720 | /// check for that. If one of the hardcoded targets we know about, just | |
721 | /// return it directly. | |
1a4d82fc | 722 | /// |
c34b1796 AL |
723 | /// The error string could come from any of the APIs called, including |
724 | /// filesystem access and JSON decoding. | |
1a4d82fc | 725 | pub fn search(target: &str) -> Result<Target, String> { |
85aaf69f SL |
726 | use std::env; |
727 | use std::ffi::OsString; | |
c34b1796 AL |
728 | use std::fs::File; |
729 | use std::path::{Path, PathBuf}; | |
1a4d82fc JJ |
730 | use serialize::json; |
731 | ||
732 | fn load_file(path: &Path) -> Result<Target, String> { | |
54a0048b | 733 | let mut f = File::open(path).map_err(|e| e.to_string())?; |
c34b1796 | 734 | let mut contents = Vec::new(); |
54a0048b SL |
735 | f.read_to_end(&mut contents).map_err(|e| e.to_string())?; |
736 | let obj = json::from_reader(&mut &contents[..]) | |
737 | .map_err(|e| e.to_string())?; | |
5bcae85e | 738 | Target::from_json(obj) |
1a4d82fc JJ |
739 | } |
740 | ||
5bcae85e | 741 | if let Ok(t) = load_specific(target) { |
7453a54e | 742 | return Ok(t) |
1a4d82fc JJ |
743 | } |
744 | ||
1a4d82fc JJ |
745 | let path = Path::new(target); |
746 | ||
747 | if path.is_file() { | |
748 | return load_file(&path); | |
749 | } | |
750 | ||
751 | let path = { | |
752 | let mut target = target.to_string(); | |
753 | target.push_str(".json"); | |
c34b1796 | 754 | PathBuf::from(target) |
1a4d82fc JJ |
755 | }; |
756 | ||
c34b1796 AL |
757 | let target_path = env::var_os("RUST_TARGET_PATH") |
758 | .unwrap_or(OsString::new()); | |
1a4d82fc | 759 | |
1a4d82fc JJ |
760 | // FIXME 16351: add a sane default search path? |
761 | ||
85aaf69f | 762 | for dir in env::split_paths(&target_path) { |
c34b1796 | 763 | let p = dir.join(&path); |
1a4d82fc JJ |
764 | if p.is_file() { |
765 | return load_file(&p); | |
766 | } | |
767 | } | |
768 | ||
769 | Err(format!("Could not find specification for target {:?}", target)) | |
770 | } | |
771 | } | |
e9174d1e | 772 | |
5bcae85e SL |
773 | impl ToJson for Target { |
774 | fn to_json(&self) -> Json { | |
775 | let mut d = BTreeMap::new(); | |
776 | let default: TargetOptions = Default::default(); | |
777 | ||
778 | macro_rules! target_val { | |
779 | ($attr:ident) => ( { | |
780 | let name = (stringify!($attr)).replace("_", "-"); | |
781 | d.insert(name.to_string(), self.$attr.to_json()); | |
782 | } ); | |
783 | ($attr:ident, $key_name:expr) => ( { | |
784 | let name = $key_name; | |
785 | d.insert(name.to_string(), self.$attr.to_json()); | |
786 | } ); | |
787 | } | |
788 | ||
789 | macro_rules! target_option_val { | |
790 | ($attr:ident) => ( { | |
791 | let name = (stringify!($attr)).replace("_", "-"); | |
792 | if default.$attr != self.options.$attr { | |
793 | d.insert(name.to_string(), self.options.$attr.to_json()); | |
794 | } | |
795 | } ); | |
796 | ($attr:ident, $key_name:expr) => ( { | |
797 | let name = $key_name; | |
798 | if default.$attr != self.options.$attr { | |
799 | d.insert(name.to_string(), self.options.$attr.to_json()); | |
800 | } | |
801 | } ); | |
cc61c64b XL |
802 | (link_args - $attr:ident) => ( { |
803 | let name = (stringify!($attr)).replace("_", "-"); | |
804 | if default.$attr != self.options.$attr { | |
805 | let obj = self.options.$attr | |
806 | .iter() | |
807 | .map(|(k, v)| (k.desc().to_owned(), v.clone())) | |
808 | .collect::<BTreeMap<_, _>>(); | |
809 | d.insert(name.to_string(), obj.to_json()); | |
810 | } | |
811 | } ); | |
041b39d2 XL |
812 | (env - $attr:ident) => ( { |
813 | let name = (stringify!($attr)).replace("_", "-"); | |
814 | if default.$attr != self.options.$attr { | |
815 | let obj = self.options.$attr | |
816 | .iter() | |
817 | .map(|&(ref k, ref v)| k.clone() + "=" + &v) | |
818 | .collect::<Vec<_>>(); | |
819 | d.insert(name.to_string(), obj.to_json()); | |
820 | } | |
821 | } ); | |
822 | ||
5bcae85e SL |
823 | } |
824 | ||
825 | target_val!(llvm_target); | |
826 | target_val!(target_endian); | |
827 | target_val!(target_pointer_width); | |
828 | target_val!(arch); | |
829 | target_val!(target_os, "os"); | |
830 | target_val!(target_env, "env"); | |
831 | target_val!(target_vendor, "vendor"); | |
5bcae85e | 832 | target_val!(data_layout); |
cc61c64b | 833 | target_val!(linker_flavor); |
5bcae85e SL |
834 | |
835 | target_option_val!(is_builtin); | |
836 | target_option_val!(linker); | |
837 | target_option_val!(ar); | |
cc61c64b | 838 | target_option_val!(link_args - pre_link_args); |
5bcae85e SL |
839 | target_option_val!(pre_link_objects_exe); |
840 | target_option_val!(pre_link_objects_dll); | |
cc61c64b | 841 | target_option_val!(link_args - late_link_args); |
5bcae85e | 842 | target_option_val!(post_link_objects); |
cc61c64b | 843 | target_option_val!(link_args - post_link_args); |
041b39d2 | 844 | target_option_val!(env - link_env); |
32a655c1 | 845 | target_option_val!(asm_args); |
5bcae85e SL |
846 | target_option_val!(cpu); |
847 | target_option_val!(features); | |
848 | target_option_val!(dynamic_linking); | |
849 | target_option_val!(executables); | |
850 | target_option_val!(relocation_model); | |
851 | target_option_val!(code_model); | |
852 | target_option_val!(disable_redzone); | |
853 | target_option_val!(eliminate_frame_pointer); | |
854 | target_option_val!(function_sections); | |
855 | target_option_val!(dll_prefix); | |
856 | target_option_val!(dll_suffix); | |
857 | target_option_val!(exe_suffix); | |
858 | target_option_val!(staticlib_prefix); | |
859 | target_option_val!(staticlib_suffix); | |
860 | target_option_val!(target_family); | |
476ff2be | 861 | target_option_val!(is_like_openbsd); |
5bcae85e SL |
862 | target_option_val!(is_like_osx); |
863 | target_option_val!(is_like_solaris); | |
864 | target_option_val!(is_like_windows); | |
865 | target_option_val!(is_like_msvc); | |
8bb4bdeb | 866 | target_option_val!(is_like_emscripten); |
5bcae85e SL |
867 | target_option_val!(is_like_android); |
868 | target_option_val!(linker_is_gnu); | |
869 | target_option_val!(allows_weak_linkage); | |
870 | target_option_val!(has_rpath); | |
5bcae85e SL |
871 | target_option_val!(no_default_libraries); |
872 | target_option_val!(position_independent_executables); | |
873 | target_option_val!(archive_format); | |
874 | target_option_val!(allow_asm); | |
875 | target_option_val!(custom_unwind_resume); | |
5bcae85e SL |
876 | target_option_val!(exe_allocation_crate); |
877 | target_option_val!(has_elf_tls); | |
878 | target_option_val!(obj_is_bitcode); | |
476ff2be | 879 | target_option_val!(no_integrated_as); |
32a655c1 | 880 | target_option_val!(min_atomic_width); |
5bcae85e | 881 | target_option_val!(max_atomic_width); |
c30ab7b3 | 882 | target_option_val!(panic_strategy); |
476ff2be | 883 | target_option_val!(crt_static_default); |
041b39d2 | 884 | target_option_val!(stack_probes); |
c30ab7b3 SL |
885 | |
886 | if default.abi_blacklist != self.options.abi_blacklist { | |
887 | d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter() | |
888 | .map(Abi::name).map(|name| name.to_json()) | |
889 | .collect::<Vec<_>>().to_json()); | |
890 | } | |
5bcae85e SL |
891 | |
892 | Json::Object(d) | |
893 | } | |
894 | } | |
895 | ||
041b39d2 | 896 | fn maybe_jemalloc() -> Option<String> { |
7453a54e | 897 | if cfg!(feature = "jemalloc") { |
041b39d2 | 898 | Some("alloc_jemalloc".to_string()) |
7453a54e | 899 | } else { |
041b39d2 | 900 | None |
e9174d1e SL |
901 | } |
902 | } |