|
1 | 1 | #![deny(warnings)]
|
2 | 2 |
|
3 |
| -use std::{env, error::Error}; |
| 3 | +use std::{ |
| 4 | + env, |
| 5 | + error::Error, |
| 6 | + fs, |
| 7 | + path::Path, |
| 8 | + process::{Command, ExitStatus, Stdio}, |
| 9 | +}; |
4 | 10 |
|
5 | 11 | use rustc_version::Channel;
|
6 | 12 |
|
@@ -89,5 +95,63 @@ fn main() -> Result<(), Box<dyn Error>> {
|
89 | 95 | println!("cargo:rustc-cfg=unstable_channel");
|
90 | 96 | }
|
91 | 97 |
|
| 98 | + match compile_probe(ARM_LLSC_PROBE) { |
| 99 | + Some(status) if status.success() => println!("cargo:rustc-cfg=arm_llsc"), |
| 100 | + _ => {} |
| 101 | + } |
| 102 | + |
92 | 103 | Ok(())
|
93 | 104 | }
|
| 105 | + |
| 106 | +const ARM_LLSC_PROBE: &str = r#" |
| 107 | +#![no_std] |
| 108 | +
|
| 109 | +// `no_mangle` forces codegen, which makes llvm check the contents of the `asm!` macro |
| 110 | +#[no_mangle] |
| 111 | +unsafe fn asm() { |
| 112 | + core::arch::asm!("clrex"); |
| 113 | +} |
| 114 | +"#; |
| 115 | + |
| 116 | +// this function was taken from anyhow v1.0.63 build script |
| 117 | +// https://crates.io/crates/anyhow/1.0.63 (last visited 2022-09-02) |
| 118 | +// the code is licensed under 'MIT or APACHE-2.0' |
| 119 | +fn compile_probe(source: &str) -> Option<ExitStatus> { |
| 120 | + let rustc = env::var_os("RUSTC")?; |
| 121 | + let out_dir = env::var_os("OUT_DIR")?; |
| 122 | + let probefile = Path::new(&out_dir).join("probe.rs"); |
| 123 | + fs::write(&probefile, source).ok()?; |
| 124 | + |
| 125 | + // Make sure to pick up Cargo rustc configuration. |
| 126 | + let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER") { |
| 127 | + let mut cmd = Command::new(wrapper); |
| 128 | + // The wrapper's first argument is supposed to be the path to rustc. |
| 129 | + cmd.arg(rustc); |
| 130 | + cmd |
| 131 | + } else { |
| 132 | + Command::new(rustc) |
| 133 | + }; |
| 134 | + |
| 135 | + cmd.stderr(Stdio::null()) |
| 136 | + .arg("--edition=2018") |
| 137 | + .arg("--crate-name=probe") |
| 138 | + .arg("--crate-type=lib") |
| 139 | + .arg("--out-dir") |
| 140 | + .arg(out_dir) |
| 141 | + .arg(probefile); |
| 142 | + |
| 143 | + if let Some(target) = env::var_os("TARGET") { |
| 144 | + cmd.arg("--target").arg(target); |
| 145 | + } |
| 146 | + |
| 147 | + // If Cargo wants to set RUSTFLAGS, use that. |
| 148 | + if let Ok(rustflags) = env::var("CARGO_ENCODED_RUSTFLAGS") { |
| 149 | + if !rustflags.is_empty() { |
| 150 | + for arg in rustflags.split('\x1f') { |
| 151 | + cmd.arg(arg); |
| 152 | + } |
| 153 | + } |
| 154 | + } |
| 155 | + |
| 156 | + cmd.status().ok() |
| 157 | +} |
0 commit comments