-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathbuild.rs
118 lines (102 loc) · 3.88 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::env;
use std::process::Command;
use std::str;
fn main() {
// Avoid unnecessary re-building.
println!("cargo:rerun-if-changed=build.rs");
let (rustc_minor_ver, is_nightly) = rustc_minor_nightly().expect("Failed to get rustc version");
let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok();
let libc_ci = env::var("LIBC_CI").is_ok();
// The ABI of libc used by libstd is backward compatible with FreeBSD 10.
// The ABI of libc from crates.io is backward compatible with FreeBSD 11.
//
// On CI, we detect the actual FreeBSD version and match its ABI exactly,
// running tests to ensure that the ABI is correct.
match which_freebsd() {
Some(10) if libc_ci || rustc_dep_of_std => {
println!("cargo:rustc-cfg=freebsd10")
}
Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"),
Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"),
Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"),
Some(14) if libc_ci => println!("cargo:rustc-cfg=freebsd14"),
Some(_) | None => println!("cargo:rustc-cfg=freebsd11"),
}
// On CI: deny all warnings
if libc_ci {
println!("cargo:rustc-cfg=libc_deny_warnings");
}
if rustc_minor_ver >= 51 || rustc_dep_of_std {
println!("cargo:rustc-cfg=libc_ptr_addr_of");
}
// #[thread_local] is currently unstable
if rustc_dep_of_std {
println!("cargo:rustc-cfg=libc_thread_local");
}
// Rust >= 1.62.0 allows to use `const_extern_fn` for "Rust" and "C".
if rustc_minor_ver >= 62 {
println!("cargo:rustc-cfg=libc_const_extern_fn");
} else {
// Rust < 1.62.0 requires a crate feature and feature gate.
if const_extern_fn_cargo_feature {
if !is_nightly || rustc_minor_ver < 40 {
panic!("const-extern-fn requires a nightly compiler >= 1.40");
}
println!("cargo:rustc-cfg=libc_const_extern_fn_unstable");
println!("cargo:rustc-cfg=libc_const_extern_fn");
}
}
}
fn rustc_minor_nightly() -> Option<(u32, bool)> {
macro_rules! otry {
($e:expr) => {
match $e {
Some(e) => e,
None => return None,
}
};
}
let rustc = otry!(env::var_os("RUSTC"));
let output = otry!(Command::new(rustc).arg("--version").output().ok());
let version = otry!(str::from_utf8(&output.stdout).ok());
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
let minor = pieces.next();
// If `rustc` was built from a tarball, its version string
// will have neither a git hash nor a commit date
// (e.g. "rustc 1.39.0"). Treat this case as non-nightly,
// since a nightly build should either come from CI
// or a git checkout
let nightly_raw = otry!(pieces.next()).split('-').nth(1);
let nightly = nightly_raw
.map(|raw| raw.starts_with("dev") || raw.starts_with("nightly"))
.unwrap_or(false);
let minor = otry!(otry!(minor).parse().ok());
Some((minor, nightly))
}
fn which_freebsd() -> Option<i32> {
let output = std::process::Command::new("freebsd-version").output().ok();
if output.is_none() {
return None;
}
let output = output.unwrap();
if !output.status.success() {
return None;
}
let stdout = String::from_utf8(output.stdout).ok();
if stdout.is_none() {
return None;
}
let stdout = stdout.unwrap();
match &stdout {
s if s.starts_with("10") => Some(10),
s if s.starts_with("11") => Some(11),
s if s.starts_with("12") => Some(12),
s if s.starts_with("13") => Some(13),
s if s.starts_with("14") => Some(14),
_ => None,
}
}