blob: 6c0112153c9c5f293f887ad367187e733a9a17bf [file] [log] [blame]
David Tolnay17eb0702019-01-05 12:23:17 -08001// rustc-cfg emitted by the build script:
2//
3// "u128"
4// Include u128 and i128 constructors for proc_macro2::Literal. Enabled on
5// any compiler 1.26+.
6//
7// "use_proc_macro"
8// Link to extern crate proc_macro. Available on any compiler and any target
9// except wasm32. Requires "proc-macro" Cargo cfg to be enabled (default is
10// enabled). On wasm32 we never link to proc_macro even if "proc-macro" cfg
11// is enabled.
12//
13// "wrap_proc_macro"
14// Wrap types from libproc_macro rather than polyfilling the whole API.
15// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set,
16// because we can't emulate the unstable API without emulating everything
17// else. Also enabled unconditionally on nightly, in which case the
18// procmacro2_semver_exempt surface area is implemented by using the
19// nightly-only proc_macro API.
20//
21// "slow_extend"
22// Fallback when `impl Extend for TokenStream` is not available. These impls
23// were added one version later than the rest of the proc_macro token API.
24// Enabled on rustc 1.29 only.
25//
26// "nightly"
David Tolnay40bbb1c2019-01-19 19:43:55 -080027// Enable the Span::unwrap method. This is to support proc_macro_span and
David Tolnay17eb0702019-01-05 12:23:17 -080028// proc_macro_diagnostic use on the nightly channel without requiring the
29// semver exemption opt-in. Enabled when building with nightly.
30//
31// "super_unstable"
32// Implement the semver exempt API in terms of the nightly-only proc_macro
33// API. Enabled when using procmacro2_semver_exempt on a nightly compiler.
David Tolnay3b1f7d22019-01-28 12:22:11 -080034//
35// "span_locations"
36// Provide methods Span::start and Span::end which give the line/column
37// location of a token. Enabled by procmacro2_semver_exempt or the
38// "span-locations" Cargo cfg. This is behind a cfg because tracking
39// location inside spans is a performance hit.
David Tolnay17eb0702019-01-05 12:23:17 -080040
Alex Crichton53548482018-08-11 21:54:05 -070041use std::env;
Alex Crichtonce0904d2018-08-27 17:29:49 -070042use std::process::Command;
43use std::str;
Alex Crichton53548482018-08-11 21:54:05 -070044
45fn main() {
46 println!("cargo:rerun-if-changed=build.rs");
47
48 let target = env::var("TARGET").unwrap();
49
David Tolnay17eb0702019-01-05 12:23:17 -080050 let version = match rustc_version() {
51 Some(version) => version,
Alex Crichtonce0904d2018-08-27 17:29:49 -070052 None => return,
53 };
54
David Tolnay17eb0702019-01-05 12:23:17 -080055 if version.minor >= 26 {
Alex Crichton69385662018-11-08 06:30:04 -080056 println!("cargo:rustc-cfg=u128");
57 }
58
David Tolnay17eb0702019-01-05 12:23:17 -080059 let semver_exempt = cfg!(procmacro2_semver_exempt);
60 if semver_exempt {
61 // https://github.com/alexcrichton/proc-macro2/issues/147
62 println!("cargo:rustc-cfg=procmacro2_semver_exempt");
David Tolnaye839e4f2018-09-06 09:36:43 -070063 }
64
David Tolnay3b1f7d22019-01-28 12:22:11 -080065 if semver_exempt || cfg!(feature = "span-locations") {
66 println!("cargo:rustc-cfg=span_locations");
67 }
68
69 if !enable_use_proc_macro(&target) {
70 return;
71 }
72
73 println!("cargo:rustc-cfg=use_proc_macro");
74
David Tolnay17eb0702019-01-05 12:23:17 -080075 // Rust 1.29 stabilized the necessary APIs in the `proc_macro` crate
76 if version.nightly || version.minor >= 29 && !semver_exempt {
77 println!("cargo:rustc-cfg=wrap_proc_macro");
78 }
79
80 if version.minor == 29 {
David Tolnaye839e4f2018-09-06 09:36:43 -070081 println!("cargo:rustc-cfg=slow_extend");
Alex Crichtonce0904d2018-08-27 17:29:49 -070082 }
David Tolnay17eb0702019-01-05 12:23:17 -080083
84 if version.nightly {
85 println!("cargo:rustc-cfg=nightly");
86 }
87
88 if semver_exempt && version.nightly {
89 println!("cargo:rustc-cfg=super_unstable");
90 }
Alex Crichton53548482018-08-11 21:54:05 -070091}
92
Alex Crichtonce0904d2018-08-27 17:29:49 -070093fn enable_use_proc_macro(target: &str) -> bool {
Alex Crichton53548482018-08-11 21:54:05 -070094 // wasm targets don't have the `proc_macro` crate, disable this feature.
95 if target.contains("wasm32") {
Alex Crichtonce0904d2018-08-27 17:29:49 -070096 return false;
Alex Crichton53548482018-08-11 21:54:05 -070097 }
98
Alex Crichton53548482018-08-11 21:54:05 -070099 // Otherwise, only enable it if our feature is actually enabled.
Alex Crichtonce0904d2018-08-27 17:29:49 -0700100 cfg!(feature = "proc-macro")
101}
102
David Tolnay17eb0702019-01-05 12:23:17 -0800103struct RustcVersion {
104 minor: u32,
105 nightly: bool,
106}
107
108fn rustc_version() -> Option<RustcVersion> {
Alex Crichtonce0904d2018-08-27 17:29:49 -0700109 macro_rules! otry {
David Tolnay2ff99ce2018-09-01 09:40:51 -0700110 ($e:expr) => {
111 match $e {
112 Some(e) => e,
113 None => return None,
114 }
115 };
Alex Crichton53548482018-08-11 21:54:05 -0700116 }
David Tolnay17eb0702019-01-05 12:23:17 -0800117
Alex Crichtonce0904d2018-08-27 17:29:49 -0700118 let rustc = otry!(env::var_os("RUSTC"));
119 let output = otry!(Command::new(rustc).arg("--version").output().ok());
120 let version = otry!(str::from_utf8(&output.stdout).ok());
David Tolnay17eb0702019-01-05 12:23:17 -0800121 let nightly = version.contains("nightly");
Alex Crichtonce0904d2018-08-27 17:29:49 -0700122 let mut pieces = version.split('.');
123 if pieces.next() != Some("rustc 1") {
124 return None;
125 }
David Tolnay17eb0702019-01-05 12:23:17 -0800126 let minor = otry!(pieces.next());
127 let minor = otry!(minor.parse().ok());
128
129 Some(RustcVersion {
130 minor: minor,
131 nightly: nightly,
132 })
Alex Crichton53548482018-08-11 21:54:05 -0700133}