• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::env;
2 use std::ffi::OsString;
3 use std::process::{self, Command, Stdio};
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.
main()8 fn main() {
9     println!("cargo:rerun-if-changed=build.rs");
10 
11     // Note: add "/build.rs" to package.include in Cargo.toml if adding any
12     // conditional compilation within the library.
13 
14     if !unstable() {
15         println!("cargo:rustc-cfg=syn_disable_nightly_tests");
16     }
17 }
18 
unstable() -> bool19 fn unstable() -> bool {
20     let rustc = cargo_env_var("RUSTC");
21 
22     // Pick up Cargo rustc configuration.
23     let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
24         let mut cmd = Command::new(wrapper);
25         // The wrapper's first argument is supposed to be the path to rustc.
26         cmd.arg(rustc);
27         cmd
28     } else {
29         Command::new(rustc)
30     };
31 
32     cmd.stdin(Stdio::null());
33     cmd.stdout(Stdio::null());
34     cmd.stderr(Stdio::null());
35     cmd.arg("-");
36 
37     // Find out whether this is a nightly or dev build.
38     cmd.env_remove("RUSTC_BOOTSTRAP");
39     cmd.arg("-Zcrate-attr=feature(rustc_private)");
40 
41     // Pass `-Zunpretty` to terminate earlier without writing out any "emit"
42     // files. Use `expanded` to proceed far enough to actually apply crate
43     // attrs. With `unpretty=normal` or `--print`, not enough compilation
44     // happens to recognize that the feature attribute is unstable.
45     cmd.arg("-Zunpretty=expanded");
46 
47     // Set #![no_std] to bypass loading libstd.rlib. This is a 7.5% speedup.
48     cmd.arg("-Zcrate-attr=no_std");
49 
50     cmd.arg("--crate-type=lib");
51     cmd.arg("--edition=2021");
52 
53     if let Some(target) = env::var_os("TARGET") {
54         cmd.arg("--target").arg(target);
55     }
56 
57     // If Cargo wants to set RUSTFLAGS, use that.
58     if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
59         if !rustflags.is_empty() {
60             for arg in rustflags.split('\x1f') {
61                 cmd.arg(arg);
62             }
63         }
64     }
65 
66     // This rustc invocation should take around 0.03 seconds.
67     match cmd.status() {
68         Ok(status) => status.success(),
69         Err(_) => false,
70     }
71 }
72 
cargo_env_var(key: &str) -> OsString73 fn cargo_env_var(key: &str) -> OsString {
74     env::var_os(key).unwrap_or_else(|| {
75         eprintln!(
76             "Environment variable ${} is not set during execution of build script",
77             key,
78         );
79         process::exit(1);
80     })
81 }
82