]>
Commit | Line | Data |
---|---|---|
8faf50e0 XL |
1 | use std::env; |
2 | use std::process::Command; | |
3 | use std::str::{self, FromStr}; | |
4 | ||
5 | // The rustc-cfg strings below are *not* public API. Please let us know by | |
6 | // opening a GitHub issue if your build environment requires some way to enable | |
7 | // these cfgs other than by executing our build script. | |
8 | fn main() { | |
9 | let minor = match rustc_minor_version() { | |
10 | Some(minor) => minor, | |
11 | None => return, | |
12 | }; | |
13 | ||
b7449926 XL |
14 | let target = env::var("TARGET").unwrap(); |
15 | let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; | |
16 | ||
dc9dc135 XL |
17 | // std::collections::Bound was stabilized in Rust 1.17 |
18 | // but it was moved to core::ops later in Rust 1.26: | |
19 | // https://doc.rust-lang.org/core/ops/enum.Bound.html | |
20 | if minor >= 26 { | |
21 | println!("cargo:rustc-cfg=ops_bound"); | |
22 | } else if minor >= 17 && cfg!(feature = "std") { | |
23 | println!("cargo:rustc-cfg=collections_bound"); | |
24 | } | |
25 | ||
26 | // core::cmp::Reverse stabilized in Rust 1.19: | |
27 | // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html | |
28 | if minor >= 19 { | |
29 | println!("cargo:rustc-cfg=core_reverse"); | |
30 | } | |
31 | ||
f035d41b | 32 | // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: |
8faf50e0 | 33 | // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str |
f035d41b | 34 | // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path |
8faf50e0 XL |
35 | if minor >= 20 { |
36 | println!("cargo:rustc-cfg=de_boxed_c_str"); | |
f035d41b | 37 | println!("cargo:rustc-cfg=de_boxed_path"); |
8faf50e0 XL |
38 | } |
39 | ||
40 | // From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21: | |
41 | // https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>> | |
42 | // https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>> | |
43 | if minor >= 21 { | |
44 | println!("cargo:rustc-cfg=de_rc_dst"); | |
45 | } | |
46 | ||
47 | // Duration available in core since Rust 1.25: | |
48 | // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations | |
49 | if minor >= 25 { | |
50 | println!("cargo:rustc-cfg=core_duration"); | |
51 | } | |
52 | ||
53 | // 128-bit integers stabilized in Rust 1.26: | |
54 | // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html | |
b7449926 XL |
55 | // |
56 | // Disabled on Emscripten targets as Emscripten doesn't | |
57 | // currently support integers larger than 64 bits. | |
58 | if minor >= 26 && !emscripten { | |
8faf50e0 XL |
59 | println!("cargo:rustc-cfg=integer128"); |
60 | } | |
61 | ||
b7449926 XL |
62 | // Inclusive ranges methods stabilized in Rust 1.27: |
63 | // https://github.com/rust-lang/rust/pull/50758 | |
64 | if minor >= 27 { | |
65 | println!("cargo:rustc-cfg=range_inclusive"); | |
66 | } | |
67 | ||
8faf50e0 | 68 | // Non-zero integers stabilized in Rust 1.28: |
f035d41b | 69 | // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations |
8faf50e0 XL |
70 | if minor >= 28 { |
71 | println!("cargo:rustc-cfg=num_nonzero"); | |
72 | } | |
e1599b0c XL |
73 | |
74 | // TryFrom, Atomic types, and non-zero signed integers stabilized in Rust 1.34: | |
75 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto | |
76 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations | |
77 | if minor >= 34 { | |
78 | println!("cargo:rustc-cfg=core_try_from"); | |
79 | println!("cargo:rustc-cfg=num_nonzero_signed"); | |
80 | ||
81 | // Whitelist of archs that support std::sync::atomic module. Ideally we | |
82 | // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. | |
83 | // Instead this is based on rustc's src/librustc_target/spec/*.rs. | |
84 | let has_atomic64 = target.starts_with("x86_64") | |
85 | || target.starts_with("i686") | |
86 | || target.starts_with("aarch64") | |
87 | || target.starts_with("powerpc64") | |
88 | || target.starts_with("sparc64") | |
89 | || target.starts_with("mips64el"); | |
90 | let has_atomic32 = has_atomic64 || emscripten; | |
91 | if has_atomic64 { | |
92 | println!("cargo:rustc-cfg=std_atomic64"); | |
93 | } | |
94 | if has_atomic32 { | |
95 | println!("cargo:rustc-cfg=std_atomic"); | |
96 | } | |
97 | } | |
8faf50e0 XL |
98 | } |
99 | ||
100 | fn rustc_minor_version() -> Option<u32> { | |
101 | let rustc = match env::var_os("RUSTC") { | |
102 | Some(rustc) => rustc, | |
103 | None => return None, | |
104 | }; | |
105 | ||
106 | let output = match Command::new(rustc).arg("--version").output() { | |
107 | Ok(output) => output, | |
108 | Err(_) => return None, | |
109 | }; | |
110 | ||
111 | let version = match str::from_utf8(&output.stdout) { | |
112 | Ok(version) => version, | |
113 | Err(_) => return None, | |
114 | }; | |
115 | ||
8faf50e0 XL |
116 | let mut pieces = version.split('.'); |
117 | if pieces.next() != Some("rustc 1") { | |
118 | return None; | |
119 | } | |
120 | ||
121 | let next = match pieces.next() { | |
122 | Some(next) => next, | |
123 | None => return None, | |
124 | }; | |
125 | ||
126 | u32::from_str(next).ok() | |
127 | } |