diff --git a/decnumber-sys/Cargo.toml b/decnumber-sys/Cargo.toml index 76ca4ca..32321d5 100644 --- a/decnumber-sys/Cargo.toml +++ b/decnumber-sys/Cargo.toml @@ -20,3 +20,4 @@ version-sync = "0.9" [build-dependencies] cc = "1.0.50" +rustflags = "0.1.4" diff --git a/decnumber-sys/build.rs b/decnumber-sys/build.rs index 81ed464..b47ed53 100644 --- a/decnumber-sys/build.rs +++ b/decnumber-sys/build.rs @@ -7,7 +7,16 @@ use std::env; use std::fs; use std::path::{Path, PathBuf}; +/// Extracts the `target-cpu` from `CARGO_ENCODED_RUSTFLAGS`. +fn target_cpu() -> Option { + rustflags::from_env().find_map(|flag| match flag { + rustflags::Flag::Codegen { opt, value } if opt == "target-cpu" => value, + _ => None, + }) +} + fn main() { + let target = env::var("TARGET").unwrap(); let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let declitend = if cfg!(target_endian = "little") { @@ -15,7 +24,25 @@ fn main() { } else { "0" }; - cc::Build::new() + let mut build = cc::Build::new(); + + if let Some(target_cpu) = target_cpu() { + if target.contains("x86_64") { + build.flag_if_supported(&format!("-march={target_cpu}")); + + // The x86-64-vX targets are generic and do not support tuning. + if !target_cpu.starts_with("x86-64-v") { + build.flag_if_supported(&format!("-mtune={target_cpu}")); + } + } else if target.contains("aarch64") { + // The -mcpu argument is deprecated for x86 but supported for AArch64. + // + // See: https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html + build.flag_if_supported(&format!("-mcpu={target_cpu}")); + } + } + + build .define("DECLITEND", Some(declitend)) .file("decnumber/decimal128.c") .file("decnumber/decimal64.c")