1 use std::env; 2 use std::process::Command; 3 use std::str; 4 main()5fn main() { 6 println!("cargo:rerun-if-changed=build.rs"); 7 8 let compiler = match rustc_minor_version() { 9 Some(compiler) => compiler, 10 None => return, 11 }; 12 13 if compiler >= 80 { 14 println!("cargo:rustc-check-cfg=cfg(doc_cfg)"); 15 println!("cargo:rustc-check-cfg=cfg(no_alloc_crate)"); 16 println!("cargo:rustc-check-cfg=cfg(no_const_vec_new)"); 17 println!("cargo:rustc-check-cfg=cfg(no_exhaustive_int_match)"); 18 println!("cargo:rustc-check-cfg=cfg(no_non_exhaustive)"); 19 println!("cargo:rustc-check-cfg=cfg(no_nonzero_bitscan)"); 20 println!("cargo:rustc-check-cfg=cfg(no_str_strip_prefix)"); 21 println!("cargo:rustc-check-cfg=cfg(no_track_caller)"); 22 println!("cargo:rustc-check-cfg=cfg(no_unsafe_op_in_unsafe_fn_lint)"); 23 println!("cargo:rustc-check-cfg=cfg(test_node_semver)"); 24 } 25 26 if compiler < 33 { 27 // Exhaustive integer patterns. On older compilers, a final `_` arm is 28 // required even if every possible integer value is otherwise covered. 29 // https://github.com/rust-lang/rust/issues/50907 30 println!("cargo:rustc-cfg=no_exhaustive_int_match"); 31 } 32 33 if compiler < 36 { 34 // extern crate alloc. 35 // https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html#the-alloc-crate-is-stable 36 println!("cargo:rustc-cfg=no_alloc_crate"); 37 } 38 39 if compiler < 39 { 40 // const Vec::new. 41 // https://doc.rust-lang.org/std/vec/struct.Vec.html#method.new 42 println!("cargo:rustc-cfg=no_const_vec_new"); 43 } 44 45 if compiler < 40 { 46 // #[non_exhaustive]. 47 // https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#non_exhaustive-structs-enums-and-variants 48 println!("cargo:rustc-cfg=no_non_exhaustive"); 49 } 50 51 if compiler < 45 { 52 // String::strip_prefix. 53 // https://doc.rust-lang.org/std/primitive.str.html#method.strip_prefix 54 println!("cargo:rustc-cfg=no_str_strip_prefix"); 55 } 56 57 if compiler < 46 { 58 // #[track_caller]. 59 // https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller 60 println!("cargo:rustc-cfg=no_track_caller"); 61 } 62 63 if compiler < 52 { 64 // #![deny(unsafe_op_in_unsafe_fn)]. 65 // https://github.com/rust-lang/rust/issues/71668 66 println!("cargo:rustc-cfg=no_unsafe_op_in_unsafe_fn_lint"); 67 } 68 69 if compiler < 53 { 70 // Efficient intrinsics for count-leading-zeros and count-trailing-zeros 71 // on NonZero integers stabilized in 1.53.0. On many architectures these 72 // are more efficient than counting zeros on ordinary zeroable integers. 73 // https://doc.rust-lang.org/std/num/struct.NonZeroU64.html#method.leading_zeros 74 // https://doc.rust-lang.org/std/num/struct.NonZeroU64.html#method.trailing_zeros 75 println!("cargo:rustc-cfg=no_nonzero_bitscan"); 76 } 77 } 78 rustc_minor_version() -> Option<u32>79fn rustc_minor_version() -> Option<u32> { 80 let rustc = env::var_os("RUSTC")?; 81 let output = Command::new(rustc).arg("--version").output().ok()?; 82 let version = str::from_utf8(&output.stdout).ok()?; 83 let mut pieces = version.split('.'); 84 if pieces.next() != Some("rustc 1") { 85 return None; 86 } 87 pieces.next()?.parse().ok() 88 } 89