17ac06127Sopenharmony_ci// rustc-cfg emitted by the build script: 27ac06127Sopenharmony_ci// 37ac06127Sopenharmony_ci// "wrap_proc_macro" 47ac06127Sopenharmony_ci// Wrap types from libproc_macro rather than polyfilling the whole API. 57ac06127Sopenharmony_ci// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set, 67ac06127Sopenharmony_ci// because we can't emulate the unstable API without emulating everything 77ac06127Sopenharmony_ci// else. Also enabled unconditionally on nightly, in which case the 87ac06127Sopenharmony_ci// procmacro2_semver_exempt surface area is implemented by using the 97ac06127Sopenharmony_ci// nightly-only proc_macro API. 107ac06127Sopenharmony_ci// 117ac06127Sopenharmony_ci// "hygiene" 127ac06127Sopenharmony_ci// Enable Span::mixed_site() and non-dummy behavior of Span::resolved_at 137ac06127Sopenharmony_ci// and Span::located_at. Enabled on Rust 1.45+. 147ac06127Sopenharmony_ci// 157ac06127Sopenharmony_ci// "proc_macro_span" 167ac06127Sopenharmony_ci// Enable non-dummy behavior of Span::start and Span::end methods which 177ac06127Sopenharmony_ci// requires an unstable compiler feature. Enabled when building with 187ac06127Sopenharmony_ci// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable 197ac06127Sopenharmony_ci// features. 207ac06127Sopenharmony_ci// 217ac06127Sopenharmony_ci// "super_unstable" 227ac06127Sopenharmony_ci// Implement the semver exempt API in terms of the nightly-only proc_macro 237ac06127Sopenharmony_ci// API. Enabled when using procmacro2_semver_exempt on a nightly compiler. 247ac06127Sopenharmony_ci// 257ac06127Sopenharmony_ci// "span_locations" 267ac06127Sopenharmony_ci// Provide methods Span::start and Span::end which give the line/column 277ac06127Sopenharmony_ci// location of a token. Enabled by procmacro2_semver_exempt or the 287ac06127Sopenharmony_ci// "span-locations" Cargo cfg. This is behind a cfg because tracking 297ac06127Sopenharmony_ci// location inside spans is a performance hit. 307ac06127Sopenharmony_ci// 317ac06127Sopenharmony_ci// "is_available" 327ac06127Sopenharmony_ci// Use proc_macro::is_available() to detect if the proc macro API is 337ac06127Sopenharmony_ci// available or needs to be polyfilled instead of trying to use the proc 347ac06127Sopenharmony_ci// macro API and catching a panic if it isn't available. Enabled on Rust 357ac06127Sopenharmony_ci// 1.57+. 367ac06127Sopenharmony_ci 377ac06127Sopenharmony_ciuse std::env; 387ac06127Sopenharmony_ciuse std::ffi::OsString; 397ac06127Sopenharmony_ciuse std::path::Path; 407ac06127Sopenharmony_ciuse std::process::{self, Command, Stdio}; 417ac06127Sopenharmony_ciuse std::str; 427ac06127Sopenharmony_ciuse std::u32; 437ac06127Sopenharmony_ci 447ac06127Sopenharmony_cifn main() { 457ac06127Sopenharmony_ci let rustc = rustc_minor_version().unwrap_or(u32::MAX); 467ac06127Sopenharmony_ci 477ac06127Sopenharmony_ci let docs_rs = env::var_os("DOCS_RS").is_some(); 487ac06127Sopenharmony_ci let semver_exempt = cfg!(procmacro2_semver_exempt) || docs_rs; 497ac06127Sopenharmony_ci if semver_exempt { 507ac06127Sopenharmony_ci // https://github.com/dtolnay/proc-macro2/issues/147 517ac06127Sopenharmony_ci println!("cargo:rustc-cfg=procmacro2_semver_exempt"); 527ac06127Sopenharmony_ci } 537ac06127Sopenharmony_ci 547ac06127Sopenharmony_ci if semver_exempt || cfg!(feature = "span-locations") { 557ac06127Sopenharmony_ci println!("cargo:rustc-cfg=span_locations"); 567ac06127Sopenharmony_ci } 577ac06127Sopenharmony_ci 587ac06127Sopenharmony_ci if rustc < 57 { 597ac06127Sopenharmony_ci println!("cargo:rustc-cfg=no_is_available"); 607ac06127Sopenharmony_ci } 617ac06127Sopenharmony_ci 627ac06127Sopenharmony_ci if rustc < 66 { 637ac06127Sopenharmony_ci println!("cargo:rustc-cfg=no_source_text"); 647ac06127Sopenharmony_ci } 657ac06127Sopenharmony_ci 667ac06127Sopenharmony_ci if !cfg!(feature = "proc-macro") { 677ac06127Sopenharmony_ci println!("cargo:rerun-if-changed=build.rs"); 687ac06127Sopenharmony_ci return; 697ac06127Sopenharmony_ci } 707ac06127Sopenharmony_ci 717ac06127Sopenharmony_ci println!("cargo:rerun-if-changed=build/probe.rs"); 727ac06127Sopenharmony_ci 737ac06127Sopenharmony_ci let proc_macro_span; 747ac06127Sopenharmony_ci let consider_rustc_bootstrap; 757ac06127Sopenharmony_ci if compile_probe(false) { 767ac06127Sopenharmony_ci // This is a nightly or dev compiler, so it supports unstable features 777ac06127Sopenharmony_ci // regardless of RUSTC_BOOTSTRAP. No need to rerun build script if 787ac06127Sopenharmony_ci // RUSTC_BOOTSTRAP is changed. 797ac06127Sopenharmony_ci proc_macro_span = true; 807ac06127Sopenharmony_ci consider_rustc_bootstrap = false; 817ac06127Sopenharmony_ci } else if let Some(rustc_bootstrap) = env::var_os("RUSTC_BOOTSTRAP") { 827ac06127Sopenharmony_ci if compile_probe(true) { 837ac06127Sopenharmony_ci // This is a stable or beta compiler for which the user has set 847ac06127Sopenharmony_ci // RUSTC_BOOTSTRAP to turn on unstable features. Rerun build script 857ac06127Sopenharmony_ci // if they change it. 867ac06127Sopenharmony_ci proc_macro_span = true; 877ac06127Sopenharmony_ci consider_rustc_bootstrap = true; 887ac06127Sopenharmony_ci } else if rustc_bootstrap == "1" { 897ac06127Sopenharmony_ci // This compiler does not support the proc macro Span API in the 907ac06127Sopenharmony_ci // form that proc-macro2 expects. No need to pay attention to 917ac06127Sopenharmony_ci // RUSTC_BOOTSTRAP. 927ac06127Sopenharmony_ci proc_macro_span = false; 937ac06127Sopenharmony_ci consider_rustc_bootstrap = false; 947ac06127Sopenharmony_ci } else { 957ac06127Sopenharmony_ci // This is a stable or beta compiler for which RUSTC_BOOTSTRAP is 967ac06127Sopenharmony_ci // set to restrict the use of unstable features by this crate. 977ac06127Sopenharmony_ci proc_macro_span = false; 987ac06127Sopenharmony_ci consider_rustc_bootstrap = true; 997ac06127Sopenharmony_ci } 1007ac06127Sopenharmony_ci } else { 1017ac06127Sopenharmony_ci // Without RUSTC_BOOTSTRAP, this compiler does not support the proc 1027ac06127Sopenharmony_ci // macro Span API in the form that proc-macro2 expects, but try again if 1037ac06127Sopenharmony_ci // the user turns on unstable features. 1047ac06127Sopenharmony_ci proc_macro_span = false; 1057ac06127Sopenharmony_ci consider_rustc_bootstrap = true; 1067ac06127Sopenharmony_ci } 1077ac06127Sopenharmony_ci 1087ac06127Sopenharmony_ci if proc_macro_span || !semver_exempt { 1097ac06127Sopenharmony_ci println!("cargo:rustc-cfg=wrap_proc_macro"); 1107ac06127Sopenharmony_ci } 1117ac06127Sopenharmony_ci 1127ac06127Sopenharmony_ci if proc_macro_span { 1137ac06127Sopenharmony_ci println!("cargo:rustc-cfg=proc_macro_span"); 1147ac06127Sopenharmony_ci } 1157ac06127Sopenharmony_ci 1167ac06127Sopenharmony_ci if semver_exempt && proc_macro_span { 1177ac06127Sopenharmony_ci println!("cargo:rustc-cfg=super_unstable"); 1187ac06127Sopenharmony_ci } 1197ac06127Sopenharmony_ci 1207ac06127Sopenharmony_ci if consider_rustc_bootstrap { 1217ac06127Sopenharmony_ci println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP"); 1227ac06127Sopenharmony_ci } 1237ac06127Sopenharmony_ci} 1247ac06127Sopenharmony_ci 1257ac06127Sopenharmony_cifn compile_probe(rustc_bootstrap: bool) -> bool { 1267ac06127Sopenharmony_ci if env::var_os("RUSTC_STAGE").is_some() { 1277ac06127Sopenharmony_ci // We are running inside rustc bootstrap. This is a highly non-standard 1287ac06127Sopenharmony_ci // environment with issues such as: 1297ac06127Sopenharmony_ci // 1307ac06127Sopenharmony_ci // https://github.com/rust-lang/cargo/issues/11138 1317ac06127Sopenharmony_ci // https://github.com/rust-lang/rust/issues/114839 1327ac06127Sopenharmony_ci // 1337ac06127Sopenharmony_ci // Let's just not use nightly features here. 1347ac06127Sopenharmony_ci return false; 1357ac06127Sopenharmony_ci } 1367ac06127Sopenharmony_ci 1377ac06127Sopenharmony_ci let rustc = cargo_env_var("RUSTC"); 1387ac06127Sopenharmony_ci let out_dir = cargo_env_var("OUT_DIR"); 1397ac06127Sopenharmony_ci let probefile = Path::new("build").join("probe.rs"); 1407ac06127Sopenharmony_ci 1417ac06127Sopenharmony_ci // Make sure to pick up Cargo rustc configuration. 1427ac06127Sopenharmony_ci let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") { 1437ac06127Sopenharmony_ci let mut cmd = Command::new(wrapper); 1447ac06127Sopenharmony_ci // The wrapper's first argument is supposed to be the path to rustc. 1457ac06127Sopenharmony_ci cmd.arg(rustc); 1467ac06127Sopenharmony_ci cmd 1477ac06127Sopenharmony_ci } else { 1487ac06127Sopenharmony_ci Command::new(rustc) 1497ac06127Sopenharmony_ci }; 1507ac06127Sopenharmony_ci 1517ac06127Sopenharmony_ci if !rustc_bootstrap { 1527ac06127Sopenharmony_ci cmd.env_remove("RUSTC_BOOTSTRAP"); 1537ac06127Sopenharmony_ci } 1547ac06127Sopenharmony_ci 1557ac06127Sopenharmony_ci cmd.stderr(Stdio::null()) 1567ac06127Sopenharmony_ci .arg("--edition=2021") 1577ac06127Sopenharmony_ci .arg("--crate-name=proc_macro2") 1587ac06127Sopenharmony_ci .arg("--crate-type=lib") 1597ac06127Sopenharmony_ci .arg("--emit=dep-info,metadata") 1607ac06127Sopenharmony_ci .arg("--out-dir") 1617ac06127Sopenharmony_ci .arg(out_dir) 1627ac06127Sopenharmony_ci .arg(probefile); 1637ac06127Sopenharmony_ci 1647ac06127Sopenharmony_ci if let Some(target) = env::var_os("TARGET") { 1657ac06127Sopenharmony_ci cmd.arg("--target").arg(target); 1667ac06127Sopenharmony_ci } 1677ac06127Sopenharmony_ci 1687ac06127Sopenharmony_ci // If Cargo wants to set RUSTFLAGS, use that. 1697ac06127Sopenharmony_ci if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { 1707ac06127Sopenharmony_ci if !rustflags.is_empty() { 1717ac06127Sopenharmony_ci for arg in rustflags.split('\x1f') { 1727ac06127Sopenharmony_ci cmd.arg(arg); 1737ac06127Sopenharmony_ci } 1747ac06127Sopenharmony_ci } 1757ac06127Sopenharmony_ci } 1767ac06127Sopenharmony_ci 1777ac06127Sopenharmony_ci match cmd.status() { 1787ac06127Sopenharmony_ci Ok(status) => status.success(), 1797ac06127Sopenharmony_ci Err(_) => false, 1807ac06127Sopenharmony_ci } 1817ac06127Sopenharmony_ci} 1827ac06127Sopenharmony_ci 1837ac06127Sopenharmony_cifn rustc_minor_version() -> Option<u32> { 1847ac06127Sopenharmony_ci let rustc = cargo_env_var("RUSTC"); 1857ac06127Sopenharmony_ci let output = Command::new(rustc).arg("--version").output().ok()?; 1867ac06127Sopenharmony_ci let version = str::from_utf8(&output.stdout).ok()?; 1877ac06127Sopenharmony_ci let mut pieces = version.split('.'); 1887ac06127Sopenharmony_ci if pieces.next() != Some("rustc 1") { 1897ac06127Sopenharmony_ci return None; 1907ac06127Sopenharmony_ci } 1917ac06127Sopenharmony_ci pieces.next()?.parse().ok() 1927ac06127Sopenharmony_ci} 1937ac06127Sopenharmony_ci 1947ac06127Sopenharmony_cifn cargo_env_var(key: &str) -> OsString { 1957ac06127Sopenharmony_ci env::var_os(key).unwrap_or_else(|| { 1967ac06127Sopenharmony_ci eprintln!( 1977ac06127Sopenharmony_ci "Environment variable ${} is not set during execution of build script", 1987ac06127Sopenharmony_ci key, 1997ac06127Sopenharmony_ci ); 2007ac06127Sopenharmony_ci process::exit(1); 2017ac06127Sopenharmony_ci }) 2027ac06127Sopenharmony_ci} 203