|
|
@ -8,6 +8,13 @@ |
|
|
|
// OUT_DIR
|
|
|
|
// Directory where generated files should be placed.
|
|
|
|
//
|
|
|
|
// TARGET
|
|
|
|
// Target triple provided by Cargo.
|
|
|
|
//
|
|
|
|
// CRETONNE_TARGETS (Optional)
|
|
|
|
// A setting for conditional compilation of isa targets. Possible values can be "native" or
|
|
|
|
// known isa targets separated by ','.
|
|
|
|
//
|
|
|
|
// The build script expects to be run from the directory where this build.rs file lives. The
|
|
|
|
// current directory is used to find the sources.
|
|
|
|
|
|
|
@ -17,6 +24,22 @@ use std::process; |
|
|
|
|
|
|
|
fn main() { |
|
|
|
let out_dir = env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set"); |
|
|
|
let target_triple = env::var("TARGET").expect("The TARGET environment variable must be set"); |
|
|
|
let cretonne_targets = env::var("CRETONNE_TARGETS").ok(); |
|
|
|
let cretonne_targets = cretonne_targets.as_ref().map(|s| s.as_ref()); |
|
|
|
|
|
|
|
// Configure isa targets cfg.
|
|
|
|
match isa_targets(cretonne_targets, &target_triple) { |
|
|
|
Ok(isa_targets) => { |
|
|
|
for isa in &isa_targets { |
|
|
|
println!("cargo:rustc-cfg=build_{}", isa.name()); |
|
|
|
} |
|
|
|
} |
|
|
|
Err(err) => { |
|
|
|
eprintln!("Error: {}", err); |
|
|
|
process::exit(1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
println!("Build script generating files in {}", out_dir); |
|
|
|
|
|
|
@ -45,3 +68,84 @@ fn main() { |
|
|
|
process::exit(status.code().unwrap()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Represents known ISA target.
|
|
|
|
#[derive(Copy, Clone)] |
|
|
|
enum Isa { |
|
|
|
Riscv, |
|
|
|
Intel, |
|
|
|
Arm32, |
|
|
|
Arm64, |
|
|
|
} |
|
|
|
|
|
|
|
impl Isa { |
|
|
|
/// Creates isa target using name.
|
|
|
|
fn new(name: &str) -> Option<Self> { |
|
|
|
Isa::all() |
|
|
|
.iter() |
|
|
|
.cloned() |
|
|
|
.filter(|isa| isa.name() == name) |
|
|
|
.next() |
|
|
|
} |
|
|
|
|
|
|
|
/// Creates isa target from arch.
|
|
|
|
fn from_arch(arch: &str) -> Option<Isa> { |
|
|
|
Isa::all() |
|
|
|
.iter() |
|
|
|
.cloned() |
|
|
|
.filter(|isa| isa.is_arch_applicable(arch)) |
|
|
|
.next() |
|
|
|
} |
|
|
|
|
|
|
|
/// Returns all supported isa targets.
|
|
|
|
fn all() -> [Isa; 4] { |
|
|
|
[Isa::Riscv, Isa::Intel, Isa::Arm32, Isa::Arm64] |
|
|
|
} |
|
|
|
|
|
|
|
/// Returns name of the isa target.
|
|
|
|
fn name(&self) -> &'static str { |
|
|
|
match *self { |
|
|
|
Isa::Riscv => "riscv", |
|
|
|
Isa::Intel => "intel", |
|
|
|
Isa::Arm32 => "arm32", |
|
|
|
Isa::Arm64 => "arm64", |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Checks if arch is applicable for the isa target.
|
|
|
|
fn is_arch_applicable(&self, arch: &str) -> bool { |
|
|
|
match *self { |
|
|
|
Isa::Riscv => arch == "riscv", |
|
|
|
Isa::Intel => ["x86_64", "i386", "i586", "i686"].contains(&arch), |
|
|
|
Isa::Arm32 => arch.starts_with("arm") || arch.starts_with("thumb"), |
|
|
|
Isa::Arm64 => arch == "aarch64", |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// Returns isa targets to configure conditional compilation.
|
|
|
|
fn isa_targets(cretonne_targets: Option<&str>, target_triple: &str) -> Result<Vec<Isa>, String> { |
|
|
|
match cretonne_targets { |
|
|
|
Some("native") => { |
|
|
|
Isa::from_arch(target_triple.split('-').next().unwrap()) |
|
|
|
.map(|isa| vec![isa]) |
|
|
|
.ok_or_else(|| { |
|
|
|
format!("no supported isa found for target triple `{}`", |
|
|
|
target_triple) |
|
|
|
}) |
|
|
|
} |
|
|
|
Some(targets) => { |
|
|
|
let unknown_isa_targets = targets |
|
|
|
.split(',') |
|
|
|
.filter(|target| Isa::new(target).is_none()) |
|
|
|
.collect::<Vec<_>>(); |
|
|
|
let isa_targets = targets.split(',').flat_map(Isa::new).collect::<Vec<_>>(); |
|
|
|
match (unknown_isa_targets.is_empty(), isa_targets.is_empty()) { |
|
|
|
(true, true) => Ok(Isa::all().to_vec()), |
|
|
|
(true, _) => Ok(isa_targets), |
|
|
|
(_, _) => Err(format!("unknown isa targets: `{}`", unknown_isa_targets.join(", "))), |
|
|
|
} |
|
|
|
} |
|
|
|
None => Ok(Isa::all().to_vec()), |
|
|
|
} |
|
|
|
} |
|
|
|