Yi Kong | e94f392 | 2020-08-31 01:24:17 +0800 | [diff] [blame] | 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 | |
| 14 | let target = env::var("TARGET").unwrap(); |
| 15 | let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; |
| 16 | |
| 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 | |
| 32 | // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20: |
| 33 | // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str |
| 34 | // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path |
| 35 | if minor >= 20 { |
| 36 | println!("cargo:rustc-cfg=de_boxed_c_str"); |
| 37 | println!("cargo:rustc-cfg=de_boxed_path"); |
| 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 |
| 55 | // |
| 56 | // Disabled on Emscripten targets as Emscripten doesn't |
| 57 | // currently support integers larger than 64 bits. |
| 58 | if minor >= 26 && !emscripten { |
| 59 | println!("cargo:rustc-cfg=integer128"); |
| 60 | } |
| 61 | |
| 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 | |
| 68 | // Non-zero integers stabilized in Rust 1.28: |
| 69 | // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations |
| 70 | if minor >= 28 { |
| 71 | println!("cargo:rustc-cfg=num_nonzero"); |
| 72 | } |
| 73 | |
Haibo Huang | b308584 | 2021-02-09 17:58:09 -0800 | [diff] [blame] | 74 | // Current minimum supported version of serde_derive crate is Rust 1.31. |
| 75 | if minor >= 31 { |
| 76 | println!("cargo:rustc-cfg=serde_derive"); |
| 77 | } |
| 78 | |
Joel Galenson | b32e272 | 2021-04-13 10:05:58 -0700 | [diff] [blame] | 79 | // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add |
| 80 | // stabilized in Rust 1.34: |
Yi Kong | e94f392 | 2020-08-31 01:24:17 +0800 | [diff] [blame] | 81 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto |
| 82 | // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations |
| 83 | if minor >= 34 { |
| 84 | println!("cargo:rustc-cfg=core_try_from"); |
| 85 | println!("cargo:rustc-cfg=num_nonzero_signed"); |
Joel Galenson | b32e272 | 2021-04-13 10:05:58 -0700 | [diff] [blame] | 86 | println!("cargo:rustc-cfg=systemtime_checked_add"); |
Yi Kong | e94f392 | 2020-08-31 01:24:17 +0800 | [diff] [blame] | 87 | |
| 88 | // Whitelist of archs that support std::sync::atomic module. Ideally we |
| 89 | // would use #[cfg(target_has_atomic = "...")] but it is not stable yet. |
| 90 | // Instead this is based on rustc's src/librustc_target/spec/*.rs. |
| 91 | let has_atomic64 = target.starts_with("x86_64") |
| 92 | || target.starts_with("i686") |
| 93 | || target.starts_with("aarch64") |
| 94 | || target.starts_with("powerpc64") |
| 95 | || target.starts_with("sparc64") |
| 96 | || target.starts_with("mips64el"); |
| 97 | let has_atomic32 = has_atomic64 || emscripten; |
| 98 | if has_atomic64 { |
| 99 | println!("cargo:rustc-cfg=std_atomic64"); |
| 100 | } |
| 101 | if has_atomic32 { |
| 102 | println!("cargo:rustc-cfg=std_atomic"); |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | fn rustc_minor_version() -> Option<u32> { |
| 108 | let rustc = match env::var_os("RUSTC") { |
| 109 | Some(rustc) => rustc, |
| 110 | None => return None, |
| 111 | }; |
| 112 | |
| 113 | let output = match Command::new(rustc).arg("--version").output() { |
| 114 | Ok(output) => output, |
| 115 | Err(_) => return None, |
| 116 | }; |
| 117 | |
| 118 | let version = match str::from_utf8(&output.stdout) { |
| 119 | Ok(version) => version, |
| 120 | Err(_) => return None, |
| 121 | }; |
| 122 | |
| 123 | let mut pieces = version.split('.'); |
| 124 | if pieces.next() != Some("rustc 1") { |
| 125 | return None; |
| 126 | } |
| 127 | |
| 128 | let next = match pieces.next() { |
| 129 | Some(next) => next, |
| 130 | None => return None, |
| 131 | }; |
| 132 | |
| 133 | u32::from_str(next).ok() |
| 134 | } |