blob: 2689473520834b4b9cf68a513a9afd811a836541 [file] [log] [blame]
David Tolnay17eb0702019-01-05 12:23:17 -08001// rustc-cfg emitted by the build script:
2//
David Tolnay17eb0702019-01-05 12:23:17 -08003// "use_proc_macro"
4// Link to extern crate proc_macro. Available on any compiler and any target
5// except wasm32. Requires "proc-macro" Cargo cfg to be enabled (default is
6// enabled). On wasm32 we never link to proc_macro even if "proc-macro" cfg
7// is enabled.
8//
9// "wrap_proc_macro"
10// Wrap types from libproc_macro rather than polyfilling the whole API.
11// Enabled on rustc 1.29+ as long as procmacro2_semver_exempt is not set,
12// because we can't emulate the unstable API without emulating everything
13// else. Also enabled unconditionally on nightly, in which case the
14// procmacro2_semver_exempt surface area is implemented by using the
15// nightly-only proc_macro API.
16//
David Tolnayb455dd72019-04-28 13:50:51 -070017// "proc_macro_span"
18// Enable non-dummy behavior of Span::start and Span::end methods which
19// requires an unstable compiler feature. Enabled when building with
20// nightly, unless `-Z allow-feature` in RUSTFLAGS disallows unstable
21// features.
Wim Looman099db2a2019-04-28 11:55:09 +020022//
David Tolnay17eb0702019-01-05 12:23:17 -080023// "super_unstable"
24// Implement the semver exempt API in terms of the nightly-only proc_macro
25// API. Enabled when using procmacro2_semver_exempt on a nightly compiler.
David Tolnay3b1f7d22019-01-28 12:22:11 -080026//
27// "span_locations"
28// Provide methods Span::start and Span::end which give the line/column
29// location of a token. Enabled by procmacro2_semver_exempt or the
30// "span-locations" Cargo cfg. This is behind a cfg because tracking
31// location inside spans is a performance hit.
David Tolnay17eb0702019-01-05 12:23:17 -080032
Alex Crichton53548482018-08-11 21:54:05 -070033use std::env;
Alex Crichtonce0904d2018-08-27 17:29:49 -070034use std::process::Command;
35use std::str;
Alex Crichton53548482018-08-11 21:54:05 -070036
37fn main() {
38 println!("cargo:rerun-if-changed=build.rs");
39
40 let target = env::var("TARGET").unwrap();
41
David Tolnay17eb0702019-01-05 12:23:17 -080042 let version = match rustc_version() {
43 Some(version) => version,
Alex Crichtonce0904d2018-08-27 17:29:49 -070044 None => return,
45 };
46
David Tolnay17eb0702019-01-05 12:23:17 -080047 let semver_exempt = cfg!(procmacro2_semver_exempt);
48 if semver_exempt {
49 // https://github.com/alexcrichton/proc-macro2/issues/147
50 println!("cargo:rustc-cfg=procmacro2_semver_exempt");
David Tolnaye839e4f2018-09-06 09:36:43 -070051 }
52
David Tolnay3b1f7d22019-01-28 12:22:11 -080053 if semver_exempt || cfg!(feature = "span-locations") {
54 println!("cargo:rustc-cfg=span_locations");
55 }
56
57 if !enable_use_proc_macro(&target) {
58 return;
59 }
60
61 println!("cargo:rustc-cfg=use_proc_macro");
62
David Tolnay17eb0702019-01-05 12:23:17 -080063 // Rust 1.29 stabilized the necessary APIs in the `proc_macro` crate
64 if version.nightly || version.minor >= 29 && !semver_exempt {
65 println!("cargo:rustc-cfg=wrap_proc_macro");
66 }
67
David Tolnayce12a482019-04-28 13:56:13 -070068 if version.nightly && feature_allowed("proc_macro_span") {
David Tolnayb455dd72019-04-28 13:50:51 -070069 println!("cargo:rustc-cfg=proc_macro_span");
David Tolnay17eb0702019-01-05 12:23:17 -080070 }
71
72 if semver_exempt && version.nightly {
73 println!("cargo:rustc-cfg=super_unstable");
74 }
Alex Crichton53548482018-08-11 21:54:05 -070075}
76
Alex Crichtonce0904d2018-08-27 17:29:49 -070077fn enable_use_proc_macro(target: &str) -> bool {
Alex Crichton53548482018-08-11 21:54:05 -070078 // wasm targets don't have the `proc_macro` crate, disable this feature.
79 if target.contains("wasm32") {
Alex Crichtonce0904d2018-08-27 17:29:49 -070080 return false;
Alex Crichton53548482018-08-11 21:54:05 -070081 }
82
Alex Crichton53548482018-08-11 21:54:05 -070083 // Otherwise, only enable it if our feature is actually enabled.
Alex Crichtonce0904d2018-08-27 17:29:49 -070084 cfg!(feature = "proc-macro")
85}
86
David Tolnay17eb0702019-01-05 12:23:17 -080087struct RustcVersion {
88 minor: u32,
89 nightly: bool,
90}
91
92fn rustc_version() -> Option<RustcVersion> {
Alex Crichtonce0904d2018-08-27 17:29:49 -070093 macro_rules! otry {
David Tolnay2ff99ce2018-09-01 09:40:51 -070094 ($e:expr) => {
95 match $e {
96 Some(e) => e,
97 None => return None,
98 }
99 };
Alex Crichton53548482018-08-11 21:54:05 -0700100 }
David Tolnay17eb0702019-01-05 12:23:17 -0800101
Alex Crichtonce0904d2018-08-27 17:29:49 -0700102 let rustc = otry!(env::var_os("RUSTC"));
103 let output = otry!(Command::new(rustc).arg("--version").output().ok());
104 let version = otry!(str::from_utf8(&output.stdout).ok());
David Tolnay17eb0702019-01-05 12:23:17 -0800105 let nightly = version.contains("nightly");
Alex Crichtonce0904d2018-08-27 17:29:49 -0700106 let mut pieces = version.split('.');
107 if pieces.next() != Some("rustc 1") {
108 return None;
109 }
David Tolnay17eb0702019-01-05 12:23:17 -0800110 let minor = otry!(pieces.next());
111 let minor = otry!(minor.parse().ok());
112
113 Some(RustcVersion {
114 minor: minor,
115 nightly: nightly,
116 })
Alex Crichton53548482018-08-11 21:54:05 -0700117}
Wim Looman099db2a2019-04-28 11:55:09 +0200118
David Tolnayce12a482019-04-28 13:56:13 -0700119fn feature_allowed(feature: &str) -> bool {
120 // Recognized formats:
121 //
122 // -Z allow-features=feature1,feature2
123 //
124 // -Zallow-features=feature1,feature2
125
Wim Looman099db2a2019-04-28 11:55:09 +0200126 if let Some(rustflags) = env::var_os("RUSTFLAGS") {
David Tolnayce12a482019-04-28 13:56:13 -0700127 for mut flag in rustflags.to_string_lossy().split(' ') {
128 if flag.starts_with("-Z") {
129 flag = &flag["-Z".len()..];
130 }
131 if flag.starts_with("allow-features=") {
132 flag = &flag["allow-features=".len()..];
133 return flag.split(',').any(|allowed| allowed == feature);
Wim Looman099db2a2019-04-28 11:55:09 +0200134 }
135 }
136 }
David Tolnayce12a482019-04-28 13:56:13 -0700137
138 // No allow-features= flag, allowed by default.
139 true
Wim Looman099db2a2019-04-28 11:55:09 +0200140}