1#[path = "../libm/configure.rs"]2mod configure;34use std::env;56use configure::{Config, Library, set_cfg};78fn main() {9 let cfg = Config::from_env(Library::CompilerBuiltins);10 let llvm_target = &cfg.target_triple_split;1112 // Work around building as part of `builtins-shim`: if only `build.rs` is used, Cargo always13 // considers the build dirty because `builtins-shim/build.rs` does not exist. If only14 // `../c-b/build.rs` is used, the same may happen if not built in the workspace.15 // Note: this may be `None` if CARGO_MANIFEST_DIR doesn't end in a directory name (e.g. ".")16 if let Some(dir) = cfg.manifest_dir.file_name()17 && dir == "builtins-shim"18 {19 println!("cargo::rerun-if-changed=../compiler-builtins/build.rs");20 } else {21 println!("cargo::rerun-if-changed=build.rs");22 }2324 println!("cargo::rerun-if-changed=../libm/configure.rs");2526 configure::emit(&cfg);27 configure_check_cfg();2829 let cwd = env::current_dir().unwrap();30 println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display());3132 // Forcibly enable memory intrinsics on wasm & SGX as we don't have a libc to33 // provide them.34 if (cfg.target_triple.contains("wasm") && !cfg.target_triple.contains("wasi"))35 || (cfg.target_triple.contains("sgx") && cfg.target_triple.contains("fortanix"))36 || cfg.target_triple.contains("-none")37 || cfg.target_triple.contains("nvptx")38 || cfg.target_triple.contains("uefi")39 || cfg.target_triple.contains("xous")40 {41 println!("cargo:rustc-cfg=feature=\"mem\"");42 }4344 // These targets have hardware unaligned access support.45 let mem_unaligned = cfg.target_arch.contains("x86_64")46 || cfg.target_arch.contains("x86")47 || cfg.target_arch.contains("aarch64")48 || cfg.target_arch.contains("bpf");49 set_cfg("mem_unaligned", mem_unaligned);5051 // Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This52 // includes the old androideabi. It is deprecated but it is available as a53 // rustc target (arm-linux-androideabi).54 let kernel_user_helpers = llvm_target[0] == "armv4t"55 || llvm_target[0] == "armv5te"56 || cfg.target_triple == "arm-linux-androideabi";57 set_cfg("kernel_user_helpers", kernel_user_helpers);5859 let mut maybe_build_c = true;6061 // Emscripten's runtime includes all the builtins62 if cfg.target_os == "emscripten" {63 maybe_build_c = false;64 }6566 // OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source67 if cfg.target_os == "openbsd" {68 println!("cargo:rustc-link-search=native=/usr/lib");69 println!("cargo:rustc-link-lib=compiler_rt");70 maybe_build_c = false;71 }7273 // Everything is LLVM bitcode, not compatible with mixed C/Rust74 if cfg.target_arch.contains("nvptx") {75 maybe_build_c = false;76 }7778 // Build missing intrinsics from compiler-rt C source code. If we're79 // mangling names though we assume that we're also in test mode so we don't80 // build anything and we rely on the upstream implementation of compiler-rt81 // functions82 if cfg!(feature = "unmangled-names") && cfg!(feature = "c") && maybe_build_c {83 #[cfg(feature = "c")]84 c::compile(&cfg);85 }86}8788/// Emit directives for features we expect to support that aren't in `Cargo.toml`.89///90/// These are mostly cfg elements emitted by this `build.rs`.91fn configure_check_cfg() {92 // Functions where we can set the "optimized-c" flag93 const HAS_OPTIMIZED_C: &[&str] = &[94 "__ashldi3",95 "__ashlsi3",96 "__ashrdi3",97 "__ashrsi3",98 "__bswapsi2",99 "__bswapdi2",100 "__bswapti2",101 "__divdi3",102 "__divsi3",103 "__divmoddi4",104 "__divmodsi4",105 "__divmodsi4",106 "__divmodti4",107 "__lshrdi3",108 "__lshrsi3",109 "__moddi3",110 "__modsi3",111 "__muldi3",112 "__udivdi3",113 "__udivmoddi4",114 "__udivmodsi4",115 "__udivsi3",116 "__umoddi3",117 "__umodsi3",118 ];119120 // Build a list of all aarch64 atomic operation functions121 let mut aarch_atomic = Vec::new();122 for aarch_op in ["cas", "ldadd", "ldclr", "ldeor", "ldset", "swp"] {123 let op_sizes = if aarch_op == "cas" {124 [1, 2, 4, 8, 16].as_slice()125 } else {126 [1, 2, 4, 8].as_slice()127 };128129 for op_size in op_sizes {130 for ordering in ["relax", "acq", "rel", "acq_rel"] {131 aarch_atomic.push(format!("__aarch64_{aarch_op}{op_size}_{ordering}"));132 }133 }134 }135136 for fn_name in HAS_OPTIMIZED_C137 .iter()138 .copied()139 .chain(aarch_atomic.iter().map(|s| s.as_str()))140 {141 println!("cargo::rustc-check-cfg=cfg({fn_name}, values(\"optimized-c\"))",);142 }143144 // Rustc is unaware of sparc target features, but this does show up from145 // `rustc --print target-features --target sparc64-unknown-linux-gnu`.146 println!("cargo::rustc-check-cfg=cfg(target_feature, values(\"vis3\"))");147}148149#[cfg(feature = "c")]150mod c {151 use std::collections::{BTreeMap, HashSet};152 use std::env;153 use std::fs::{self, File};154 use std::io::Write;155 use std::path::{Path, PathBuf};156157 use super::Config;158159 struct Sources {160 // SYMBOL -> PATH TO SOURCE161 map: BTreeMap<&'static str, &'static str>,162 }163164 impl Sources {165 fn new() -> Sources {166 Sources {167 map: BTreeMap::new(),168 }169 }170171 fn extend(&mut self, sources: &[(&'static str, &'static str)]) {172 // NOTE Some intrinsics have both a generic implementation (e.g.173 // `floatdidf.c`) and an arch optimized implementation174 // (`x86_64/floatdidf.c`). In those cases, we keep the arch optimized175 // implementation and discard the generic implementation. If we don't176 // and keep both implementations, the linker will yell at us about177 // duplicate symbols!178 for (symbol, src) in sources {179 if src.contains("/") {180 // Arch-optimized implementation (preferred)181 self.map.insert(symbol, src);182 } else {183 // Generic implementation184 if !self.map.contains_key(symbol) {185 self.map.insert(symbol, src);186 }187 }188 }189 }190191 fn remove(&mut self, symbols: &[&str]) {192 for symbol in symbols {193 self.map.remove(*symbol).unwrap();194 }195 }196 }197198 /// Compile intrinsics from the compiler-rt C source code199 pub fn compile(cfg: &Config) {200 let llvm_target = &cfg.target_triple_split;201 let mut consider_float_intrinsics = true;202 let build = &mut cc::Build::new();203204 // AArch64 GCCs exit with an error condition when they encounter any kind of floating point205 // code if the `nofp` and/or `nosimd` compiler flags have been set.206 //207 // Therefore, evaluate if those flags are present and set a boolean that causes any208 // compiler-rt intrinsics that contain floating point source to be excluded for this target.209 if cfg.target_arch == "aarch64" {210 let cflags_key = String::from("CFLAGS_") + &(cfg.target_triple.replace("-", "_"));211 if let Ok(cflags_value) = env::var(cflags_key) {212 if cflags_value.contains("+nofp") || cflags_value.contains("+nosimd") {213 consider_float_intrinsics = false;214 }215 }216 }217218 // `compiler-rt` requires `COMPILER_RT_HAS_FLOAT16` to be defined to make it use the219 // `_Float16` type for `f16` intrinsics. This shouldn't matter as all existing `f16`220 // intrinsics have been ported to Rust in `compiler-builtins` as C compilers don't221 // support `_Float16` on all targets (whereas Rust does). However, define the macro222 // anyway to prevent issues like rust#118813 and rust#123885 silently reoccuring if more223 // `f16` intrinsics get accidentally added here in the future.224 build.define("COMPILER_RT_HAS_FLOAT16", None);225226 build.warnings(false);227228 if cfg.target_env == "msvc" {229 // Don't pull in extra libraries on MSVC230 build.flag("/Zl");231232 // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP233 build.define("__func__", Some("__FUNCTION__"));234 } else {235 // Turn off various features of gcc and such, mostly copying236 // compiler-rt's build system already237 build.flag("-fno-builtin");238 build.flag("-fvisibility=hidden");239 build.flag("-ffreestanding");240 // Avoid the following warning appearing once **per file**:241 // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]242 //243 // Note that compiler-rt's build system also checks244 //245 // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`246 //247 // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.248 build.flag_if_supported("-fomit-frame-pointer");249 build.define("VISIBILITY_HIDDEN", None);250251 if let "aarch64" | "arm64ec" = cfg.target_arch.as_str() {252 // FIXME(llvm20): Older GCCs on A64 fail to build with253 // -Werror=implicit-function-declaration due to a compiler-rt bug.254 // With a newer LLVM we should be able to enable the flag everywhere.255 // https://github.com/llvm/llvm-project/commit/8aa9d6206ce55bdaaf422839c351fbd63f033b89256 } else {257 // Avoid implicitly creating references to undefined functions258 build.flag("-Werror=implicit-function-declaration");259 }260 }261262 // int_util.c tries to include stdlib.h if `_WIN32` is defined,263 // which it is when compiling UEFI targets with clang. This is264 // at odds with compiling with `-ffreestanding`, as the header265 // may be incompatible or not present. Create a minimal stub266 // header to use instead.267 if cfg.target_os == "uefi" {268 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());269 let include_dir = out_dir.join("include");270 if !include_dir.exists() {271 fs::create_dir(&include_dir).unwrap();272 }273 fs::write(include_dir.join("stdlib.h"), "#include <stddef.h>").unwrap();274 build.flag(&format!("-I{}", include_dir.to_str().unwrap()));275 }276277 let mut sources = Sources::new();278 sources.extend(&[279 ("__absvdi2", "absvdi2.c"),280 ("__absvsi2", "absvsi2.c"),281 ("__addvdi3", "addvdi3.c"),282 ("__addvsi3", "addvsi3.c"),283 ("__cmpdi2", "cmpdi2.c"),284 ("__int_util", "int_util.c"),285 ("__mulvdi3", "mulvdi3.c"),286 ("__mulvsi3", "mulvsi3.c"),287 ("__negdi2", "negdi2.c"),288 ("__negvdi2", "negvdi2.c"),289 ("__negvsi2", "negvsi2.c"),290 ("__paritydi2", "paritydi2.c"),291 ("__paritysi2", "paritysi2.c"),292 ("__popcountdi2", "popcountdi2.c"),293 ("__popcountsi2", "popcountsi2.c"),294 ("__subvdi3", "subvdi3.c"),295 ("__subvsi3", "subvsi3.c"),296 ("__ucmpdi2", "ucmpdi2.c"),297 ]);298299 if consider_float_intrinsics {300 sources.extend(&[301 ("__divdc3", "divdc3.c"),302 ("__divsc3", "divsc3.c"),303 ("__muldc3", "muldc3.c"),304 ("__mulsc3", "mulsc3.c"),305 ("__negdf2", "negdf2.c"),306 ("__negsf2", "negsf2.c"),307 ]);308 }309310 // On iOS and 32-bit OSX these are all just empty intrinsics, no need to311 // include them.312 if cfg.target_vendor != "apple" || cfg.target_arch != "x86" {313 sources.extend(&[314 ("__absvti2", "absvti2.c"),315 ("__addvti3", "addvti3.c"),316 ("__cmpti2", "cmpti2.c"),317 ("__ffsti2", "ffsti2.c"),318 ("__mulvti3", "mulvti3.c"),319 ("__negti2", "negti2.c"),320 ("__parityti2", "parityti2.c"),321 ("__popcountti2", "popcountti2.c"),322 ("__subvti3", "subvti3.c"),323 ("__ucmpti2", "ucmpti2.c"),324 ]);325326 if consider_float_intrinsics {327 sources.extend(&[("__negvti2", "negvti2.c")]);328 }329 }330331 if cfg.target_vendor == "apple" {332 sources.extend(&[333 ("atomic_flag_clear", "atomic_flag_clear.c"),334 ("atomic_flag_clear_explicit", "atomic_flag_clear_explicit.c"),335 ("atomic_flag_test_and_set", "atomic_flag_test_and_set.c"),336 (337 "atomic_flag_test_and_set_explicit",338 "atomic_flag_test_and_set_explicit.c",339 ),340 ("atomic_signal_fence", "atomic_signal_fence.c"),341 ("atomic_thread_fence", "atomic_thread_fence.c"),342 ]);343 }344345 if cfg.target_env != "msvc" {346 if cfg.target_arch == "x86" {347 sources.extend(&[348 ("__ashldi3", "i386/ashldi3.S"),349 ("__ashrdi3", "i386/ashrdi3.S"),350 ("__divdi3", "i386/divdi3.S"),351 ("__lshrdi3", "i386/lshrdi3.S"),352 ("__moddi3", "i386/moddi3.S"),353 ("__muldi3", "i386/muldi3.S"),354 ("__udivdi3", "i386/udivdi3.S"),355 ("__umoddi3", "i386/umoddi3.S"),356 ]);357 }358 }359360 if cfg.target_arch == "arm" && cfg.target_vendor != "apple" && cfg.target_env != "msvc" {361 sources.extend(&[362 ("__aeabi_div0", "arm/aeabi_div0.c"),363 ("__aeabi_drsub", "arm/aeabi_drsub.c"),364 ("__aeabi_frsub", "arm/aeabi_frsub.c"),365 ("__bswapdi2", "arm/bswapdi2.S"),366 ("__bswapsi2", "arm/bswapsi2.S"),367 ("__divmodsi4", "arm/divmodsi4.S"),368 ("__divsi3", "arm/divsi3.S"),369 ("__modsi3", "arm/modsi3.S"),370 ("__switch16", "arm/switch16.S"),371 ("__switch32", "arm/switch32.S"),372 ("__switch8", "arm/switch8.S"),373 ("__switchu8", "arm/switchu8.S"),374 ("__sync_synchronize", "arm/sync_synchronize.S"),375 ("__udivmodsi4", "arm/udivmodsi4.S"),376 ("__udivsi3", "arm/udivsi3.S"),377 ("__umodsi3", "arm/umodsi3.S"),378 ]);379380 if cfg.target_os == "freebsd" {381 sources.extend(&[("__clear_cache", "clear_cache.c")]);382 }383384 // First of all aeabi_cdcmp and aeabi_cfcmp are never called by LLVM.385 // Second are little-endian only, so build fail on big-endian targets.386 // Temporally workaround: exclude these files for big-endian targets.387 if !llvm_target[0].starts_with("thumbeb") && !llvm_target[0].starts_with("armeb") {388 sources.extend(&[389 ("__aeabi_cdcmp", "arm/aeabi_cdcmp.S"),390 ("__aeabi_cdcmpeq_check_nan", "arm/aeabi_cdcmpeq_check_nan.c"),391 ("__aeabi_cfcmp", "arm/aeabi_cfcmp.S"),392 ("__aeabi_cfcmpeq_check_nan", "arm/aeabi_cfcmpeq_check_nan.c"),393 ]);394 }395 }396397 if llvm_target[0] == "armv7" {398 sources.extend(&[399 ("__sync_fetch_and_add_4", "arm/sync_fetch_and_add_4.S"),400 ("__sync_fetch_and_add_8", "arm/sync_fetch_and_add_8.S"),401 ("__sync_fetch_and_and_4", "arm/sync_fetch_and_and_4.S"),402 ("__sync_fetch_and_and_8", "arm/sync_fetch_and_and_8.S"),403 ("__sync_fetch_and_max_4", "arm/sync_fetch_and_max_4.S"),404 ("__sync_fetch_and_max_8", "arm/sync_fetch_and_max_8.S"),405 ("__sync_fetch_and_min_4", "arm/sync_fetch_and_min_4.S"),406 ("__sync_fetch_and_min_8", "arm/sync_fetch_and_min_8.S"),407 ("__sync_fetch_and_nand_4", "arm/sync_fetch_and_nand_4.S"),408 ("__sync_fetch_and_nand_8", "arm/sync_fetch_and_nand_8.S"),409 ("__sync_fetch_and_or_4", "arm/sync_fetch_and_or_4.S"),410 ("__sync_fetch_and_or_8", "arm/sync_fetch_and_or_8.S"),411 ("__sync_fetch_and_sub_4", "arm/sync_fetch_and_sub_4.S"),412 ("__sync_fetch_and_sub_8", "arm/sync_fetch_and_sub_8.S"),413 ("__sync_fetch_and_umax_4", "arm/sync_fetch_and_umax_4.S"),414 ("__sync_fetch_and_umax_8", "arm/sync_fetch_and_umax_8.S"),415 ("__sync_fetch_and_umin_4", "arm/sync_fetch_and_umin_4.S"),416 ("__sync_fetch_and_umin_8", "arm/sync_fetch_and_umin_8.S"),417 ("__sync_fetch_and_xor_4", "arm/sync_fetch_and_xor_4.S"),418 ("__sync_fetch_and_xor_8", "arm/sync_fetch_and_xor_8.S"),419 ]);420 }421422 if llvm_target.last().unwrap().ends_with("eabihf") {423 if !llvm_target[0].starts_with("thumbv7em")424 && !llvm_target[0].starts_with("thumbv8m.main")425 {426 // The FPU option chosen for these architectures in cc-rs, ie:427 // -mfpu=fpv4-sp-d16 for thumbv7em428 // -mfpu=fpv5-sp-d16 for thumbv8m.main429 // do not support double precision floating points conversions so the files430 // that include such instructions are not included for these targets.431 sources.extend(&[432 ("__fixdfsivfp", "arm/fixdfsivfp.S"),433 ("__fixunsdfsivfp", "arm/fixunsdfsivfp.S"),434 ("__floatsidfvfp", "arm/floatsidfvfp.S"),435 ("__floatunssidfvfp", "arm/floatunssidfvfp.S"),436 ]);437 }438439 sources.extend(&[440 ("__fixsfsivfp", "arm/fixsfsivfp.S"),441 ("__fixunssfsivfp", "arm/fixunssfsivfp.S"),442 ("__floatsisfvfp", "arm/floatsisfvfp.S"),443 ("__floatunssisfvfp", "arm/floatunssisfvfp.S"),444 ("__floatunssisfvfp", "arm/floatunssisfvfp.S"),445 ("__restore_vfp_d8_d15_regs", "arm/restore_vfp_d8_d15_regs.S"),446 ("__save_vfp_d8_d15_regs", "arm/save_vfp_d8_d15_regs.S"),447 ("__negdf2vfp", "arm/negdf2vfp.S"),448 ("__negsf2vfp", "arm/negsf2vfp.S"),449 ]);450 }451452 if (cfg.target_arch == "aarch64" || cfg.target_arch == "arm64ec")453 && consider_float_intrinsics454 {455 sources.extend(&[456 ("__fe_getround", "fp_mode.c"),457 ("__fe_raise_inexact", "fp_mode.c"),458 ]);459460 if cfg.target_os != "windows" && cfg.target_os != "cygwin" {461 sources.extend(&[("__multc3", "multc3.c")]);462 }463 }464465 if cfg.target_arch == "mips" || cfg.target_arch == "riscv32" || cfg.target_arch == "riscv64"466 {467 sources.extend(&[("__bswapsi2", "bswapsi2.c")]);468 }469470 if cfg.target_arch == "mips64" {471 sources.extend(&[("__fe_getround", "fp_mode.c")]);472 }473474 if cfg.target_arch == "loongarch64" {475 sources.extend(&[("__fe_getround", "fp_mode.c")]);476 }477478 // Remove the assembly implementations that won't compile for the target479 if llvm_target[0] == "thumbv6m"480 || llvm_target[0] == "thumbv8m.base"481 || cfg.target_os == "uefi"482 {483 let mut to_remove = Vec::new();484 for (k, v) in sources.map.iter() {485 if v.ends_with(".S") {486 to_remove.push(*k);487 }488 }489 sources.remove(&to_remove);490 }491492 if llvm_target[0] == "thumbv7m" || llvm_target[0] == "thumbv7em" {493 sources.remove(&["__aeabi_cdcmp", "__aeabi_cfcmp"]);494 }495496 // Android and Cygwin uses emulated TLS so we need a runtime support function.497 if cfg.target_os == "android" || cfg.target_os == "cygwin" {498 sources.extend(&[("__emutls_get_address", "emutls.c")]);499 }500501 // Work around a bug in the NDK headers (fixed in502 // https://r.android.com/2038949 which will be released in a future503 // NDK version) by providing a definition of LONG_BIT.504 if cfg.target_os == "android" {505 build.define("LONG_BIT", "(8 * sizeof(long))");506 }507508 // OpenHarmony also uses emulated TLS.509 if cfg.target_env == "ohos" {510 sources.extend(&[("__emutls_get_address", "emutls.c")]);511 }512513 // Optionally, link against a prebuilt llvm compiler-rt containing the builtins514 // library. Only the builtins library is required. On many platforms, this is515 // available as a library named libclang_rt.builtins.a.516 let link_against_prebuilt_rt = env::var_os("LLVM_COMPILER_RT_LIB").is_some();517518 // When compiling the C code we require the user to tell us where the519 // source code is, and this is largely done so when we're compiling as520 // part of rust-lang/rust we can use the same llvm-project repository as521 // rust-lang/rust.522 let root = match env::var_os("RUST_COMPILER_RT_ROOT") {523 Some(s) => PathBuf::from(s),524 // If a prebuild libcompiler-rt is provided, set a valid525 // path to simplify later logic. Nothing should be compiled.526 None if link_against_prebuilt_rt => PathBuf::new(),527 None => {528 panic!(529 "RUST_COMPILER_RT_ROOT is not set. You may need to run \530 `ci/download-compiler-rt.sh`."531 );532 }533 };534 if !link_against_prebuilt_rt && !root.exists() {535 panic!("RUST_COMPILER_RT_ROOT={} does not exist", root.display());536 }537538 // Support deterministic builds by remapping the __FILE__ prefix if the539 // compiler supports it. This fixes the nondeterminism caused by the540 // use of that macro in lib/builtins/int_util.h in compiler-rt.541 build.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display()));542543 // Include out-of-line atomics for aarch64, which are all generated by supplying different544 // sets of flags to the same source file.545 // Note: Out-of-line aarch64 atomics are not supported by the msvc toolchain (#430) and546 // on uefi.547 let src_dir = root.join("lib/builtins");548 if cfg.target_arch == "aarch64" && cfg.target_env != "msvc" && cfg.target_os != "uefi" {549 // See below for why we're building these as separate libraries.550 build_aarch64_out_of_line_atomics_libraries(&src_dir, build, link_against_prebuilt_rt);551552 // Some run-time CPU feature detection is necessary, as well.553 let cpu_model_src = if src_dir.join("cpu_model.c").exists() {554 "cpu_model.c"555 } else {556 "cpu_model/aarch64.c"557 };558 sources.extend(&[("__aarch64_have_lse_atomics", cpu_model_src)]);559 }560561 let mut added_sources = HashSet::new();562 for (sym, src) in sources.map.iter() {563 let src = src_dir.join(src);564 if !link_against_prebuilt_rt && added_sources.insert(src.clone()) {565 build.file(&src);566 println!("cargo:rerun-if-changed={}", src.display());567 }568 println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);569 }570571 if link_against_prebuilt_rt {572 let rt_builtins_ext = PathBuf::from(env::var_os("LLVM_COMPILER_RT_LIB").unwrap());573 if !rt_builtins_ext.exists() {574 panic!(575 "LLVM_COMPILER_RT_LIB={} does not exist",576 rt_builtins_ext.display()577 );578 }579 if let Some(dir) = rt_builtins_ext.parent() {580 println!("cargo::rustc-link-search=native={}", dir.display());581 }582 if let Some(lib) = rt_builtins_ext.file_name() {583 println!(584 "cargo::rustc-link-lib=static:+verbatim={}",585 lib.to_str().unwrap()586 );587 }588 } else {589 build.compile("libcompiler-rt.a");590 }591 }592593 fn build_aarch64_out_of_line_atomics_libraries(594 builtins_dir: &Path,595 cfg: &mut cc::Build,596 link_against_prebuilt_rt: bool,597 ) {598 let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());599 let outlined_atomics_file = builtins_dir.join("aarch64").join("lse.S");600 if !link_against_prebuilt_rt {601 println!("cargo:rerun-if-changed={}", outlined_atomics_file.display());602 }603604 cfg.include(&builtins_dir);605606 for instruction_type in &["cas", "swp", "ldadd", "ldclr", "ldeor", "ldset"] {607 for size in &[1, 2, 4, 8, 16] {608 if *size == 16 && *instruction_type != "cas" {609 continue;610 }611612 for (model_number, model_name) in613 &[(1, "relax"), (2, "acq"), (3, "rel"), (4, "acq_rel")]614 {615 let sym = format!("__aarch64_{}{}_{}", instruction_type, size, model_name);616 println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);617618 if link_against_prebuilt_rt {619 continue;620 }621622 // The original compiler-rt build system compiles the same623 // source file multiple times with different compiler624 // options. Here we do something slightly different: we625 // create multiple .S files with the proper #defines and626 // then include the original file.627 //628 // This is needed because the cc crate doesn't allow us to629 // override the name of object files and libtool requires630 // all objects in an archive to have unique names.631 let path =632 out_dir.join(format!("lse_{}{}_{}.S", instruction_type, size, model_name));633 let mut file = File::create(&path).unwrap();634 writeln!(file, "#define L_{}", instruction_type).unwrap();635 writeln!(file, "#define SIZE {}", size).unwrap();636 writeln!(file, "#define MODEL {}", model_number).unwrap();637 writeln!(638 file,639 "#include \"{}\"",640 outlined_atomics_file.canonicalize().unwrap().display()641 )642 .unwrap();643 drop(file);644 cfg.file(path);645 }646 }647 }648 }649}
Findings
✓ No findings reported for this file.