forked from rust-embedded/heapless
-
Notifications
You must be signed in to change notification settings - Fork 1
/
build.rs
157 lines (135 loc) · 4.7 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#![deny(warnings)]
use std::{
env,
error::Error,
fs,
path::Path,
process::{Command, ExitStatus, Stdio},
};
use rustc_version::Channel;
fn main() -> Result<(), Box<dyn Error>> {
let target = env::var("TARGET")?;
if target.starts_with("thumbv6m-") {
println!("cargo:rustc-cfg=armv6m");
} else if target.starts_with("thumbv7m-") {
println!("cargo:rustc-cfg=armv7m");
} else if target.starts_with("thumbv7em-") {
println!("cargo:rustc-cfg=armv7m");
} else if target.starts_with("armv7r-") | target.starts_with("armebv7r-") {
println!("cargo:rustc-cfg=armv7r");
} else if target.starts_with("thumbv8m.base") {
println!("cargo:rustc-cfg=armv8m_base");
} else if target.starts_with("thumbv8m.main") {
println!("cargo:rustc-cfg=armv8m_main");
} else if target.starts_with("armv7-") | target.starts_with("armv7a-") {
println!("cargo:rustc-cfg=armv7a");
}
let is_avr = env::var("CARGO_CFG_TARGET_ARCH").as_deref() == Ok("avr");
// built-in targets with no atomic / CAS support as of nightly-2022-01-13
// AND not supported by the atomic-polyfill crate
// see the `no-atomics.sh` / `no-cas.sh` script sitting next to this file
if is_avr {
// lacks cas
} else {
match &target[..] {
"avr-unknown-gnu-atmega328"
| "bpfeb-unknown-none"
| "bpfel-unknown-none"
| "msp430-none-elf"
// | "riscv32i-unknown-none-elf" // supported by atomic-polyfill
// | "riscv32imc-unknown-none-elf" // supported by atomic-polyfill
| "thumbv4t-none-eabi"
// | "thumbv6m-none-eabi" // supported by atomic-polyfill
=> {}
_ => {
println!("cargo:rustc-cfg=has_cas");
}
}
};
if is_avr {
// lacks atomics
} else {
match &target[..] {
"msp430-none-elf"
// | "riscv32i-unknown-none-elf" // supported by atomic-polyfill
// | "riscv32imc-unknown-none-elf" // supported by atomic-polyfill
=> {}
_ => {
println!("cargo:rustc-cfg=has_atomics");
}
}
};
// Let the code know if it should use atomic-polyfill or not, and what aspects
// of polyfill it requires
if is_avr {
println!("cargo:rustc-cfg=full_atomic_polyfill");
println!("cargo:rustc-cfg=cas_atomic_polyfill");
} else {
match &target[..] {
"riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => {
println!("cargo:rustc-cfg=full_atomic_polyfill");
println!("cargo:rustc-cfg=cas_atomic_polyfill");
}
"thumbv6m-none-eabi" => {
println!("cargo:rustc-cfg=cas_atomic_polyfill");
}
_ => {}
}
}
if !matches!(
rustc_version::version_meta().unwrap().channel,
Channel::Stable | Channel::Beta
) {
println!("cargo:rustc-cfg=unstable_channel");
}
match compile_probe(ARM_LLSC_PROBE) {
Some(status) if status.success() => println!("cargo:rustc-cfg=arm_llsc"),
_ => {}
}
Ok(())
}
const ARM_LLSC_PROBE: &str = r#"
#![no_std]
// `no_mangle` forces codegen, which makes llvm check the contents of the `asm!` macro
#[no_mangle]
unsafe fn asm() {
core::arch::asm!("clrex");
}
"#;
// this function was taken from anyhow v1.0.63 build script
// https://crates.io/crates/anyhow/1.0.63 (last visited 2022-09-02)
// the code is licensed under 'MIT or APACHE-2.0'
fn compile_probe(source: &str) -> Option<ExitStatus> {
let rustc = env::var_os("RUSTC")?;
let out_dir = env::var_os("OUT_DIR")?;
let probefile = Path::new(&out_dir).join("probe.rs");
fs::write(&probefile, source).ok()?;
// Make sure to pick up Cargo rustc configuration.
let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") {
let mut cmd = Command::new(wrapper);
// The wrapper's first argument is supposed to be the path to rustc.
cmd.arg(rustc);
cmd
} else {
Command::new(rustc)
};
cmd.stderr(Stdio::null())
.arg("--edition=2018")
.arg("--crate-name=probe")
.arg("--crate-type=lib")
.arg("--out-dir")
.arg(out_dir)
.arg(probefile);
if let Some(target) = env::var_os("TARGET") {
cmd.arg("--target").arg(target);
}
// If Cargo wants to set RUSTFLAGS, use that.
if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") {
if !rustflags.is_empty() {
for arg in rustflags.split('\x1f') {
cmd.arg(arg);
}
}
}
cmd.status().ok()
}