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 | println!("cargo:rerun-if-changed=build.rs" ); |
10 | |
11 | let minor = match rustc_minor_version() { |
12 | Some(minor) => minor, |
13 | None => return, |
14 | }; |
15 | |
16 | let target = env::var("TARGET" ).unwrap(); |
17 | let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten" ; |
18 | |
19 | // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add |
20 | // stabilized in Rust 1.34: |
21 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto |
22 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations |
23 | if minor < 34 { |
24 | println!("cargo:rustc-cfg=no_core_try_from" ); |
25 | println!("cargo:rustc-cfg=no_num_nonzero_signed" ); |
26 | println!("cargo:rustc-cfg=no_systemtime_checked_add" ); |
27 | println!("cargo:rustc-cfg=no_relaxed_trait_bounds" ); |
28 | } |
29 | |
30 | // f32::copysign and f64::copysign stabilized in Rust 1.35. |
31 | // https://blog.rust-lang.org/2019/05/23/Rust-1.35.0.html#copy-the-sign-of-a-floating-point-number-onto-another |
32 | if minor < 35 { |
33 | println!("cargo:rustc-cfg=no_float_copysign" ); |
34 | } |
35 | |
36 | // Current minimum supported version of serde_derive crate is Rust 1.56. |
37 | if minor < 56 { |
38 | println!("cargo:rustc-cfg=no_serde_derive" ); |
39 | } |
40 | |
41 | // Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60. |
42 | if minor < 60 { |
43 | println!("cargo:rustc-cfg=no_target_has_atomic" ); |
44 | // Allowlist of archs that support std::sync::atomic module. This is |
45 | // based on rustc's compiler/rustc_target/src/spec/*.rs. |
46 | let has_atomic64 = target.starts_with("x86_64" ) |
47 | || target.starts_with("i686" ) |
48 | || target.starts_with("aarch64" ) |
49 | || target.starts_with("powerpc64" ) |
50 | || target.starts_with("sparc64" ) |
51 | || target.starts_with("mips64el" ) |
52 | || target.starts_with("riscv64" ); |
53 | let has_atomic32 = has_atomic64 || emscripten; |
54 | if minor < 34 || !has_atomic64 { |
55 | println!("cargo:rustc-cfg=no_std_atomic64" ); |
56 | } |
57 | if minor < 34 || !has_atomic32 { |
58 | println!("cargo:rustc-cfg=no_std_atomic" ); |
59 | } |
60 | } |
61 | |
62 | // Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64. |
63 | // https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc |
64 | if minor < 64 { |
65 | println!("cargo:rustc-cfg=no_core_cstr" ); |
66 | } |
67 | } |
68 | |
69 | fn rustc_minor_version() -> Option<u32> { |
70 | let rustc = match env::var_os("RUSTC" ) { |
71 | Some(rustc) => rustc, |
72 | None => return None, |
73 | }; |
74 | |
75 | let output = match Command::new(rustc).arg("--version" ).output() { |
76 | Ok(output) => output, |
77 | Err(_) => return None, |
78 | }; |
79 | |
80 | let version = match str::from_utf8(&output.stdout) { |
81 | Ok(version) => version, |
82 | Err(_) => return None, |
83 | }; |
84 | |
85 | let mut pieces = version.split('.' ); |
86 | if pieces.next() != Some("rustc 1" ) { |
87 | return None; |
88 | } |
89 | |
90 | let next = match pieces.next() { |
91 | Some(next) => next, |
92 | None => return None, |
93 | }; |
94 | |
95 | u32::from_str(next).ok() |
96 | } |
97 | |