From 2965a3cc33b9505c90092cd438130c61024706f2 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Mon, 20 May 2019 19:43:36 -0700 Subject: [PATCH 1/6] Support linking against system clang libs --- Cargo.toml | 7 ++- build.rs | 130 ++++++++++++++++++++++++++++++------------- testcrate/Cargo.toml | 2 + 3 files changed, 99 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0705dbd9..b489fa7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,12 @@ default = ["compiler-builtins"] # Enable compilation of C code in compiler-rt, filling in some more optimized # implementations and also filling in unimplemented intrinsics -c = ["cc"] +c-vendor = ["cc"] + +# Link against system clang_rt.* libraries. LLVM_CONFIG must be set. +c-system = [] + +c = ["c-vendor"] # Flag this library as the unstable compiler-builtins lib compiler-builtins = [] diff --git a/build.rs b/build.rs index b520b624..3d90808d 100644 --- a/build.rs +++ b/build.rs @@ -40,7 +40,7 @@ fn main() { // mangling names though we assume that we're also in test mode so we don't // build anything and we rely on the upstream implementation of compiler-rt // functions - if !cfg!(feature = "mangled-names") && cfg!(feature = "c") { + if !cfg!(feature = "mangled-names") && cfg!(any(feature = "c-vendor", feature = "c-system")) { // Don't use a C compiler for these targets: // // * wasm32 - clang 8 for wasm is somewhat hard to come by and it's @@ -50,8 +50,10 @@ fn main() { // compiler nor is cc-rs ready for compilation to riscv (at this // time). This can probably be removed in the future if !target.contains("wasm32") && !target.contains("nvptx") && !target.starts_with("riscv") { - #[cfg(feature = "c")] - c::compile(&llvm_target); + #[cfg(feature = "c-vendor")] + c_vendor::compile(&llvm_target); + #[cfg(feature = "c-system")] + c_system::compile(&llvm_target); } } @@ -73,17 +75,14 @@ fn main() { } } -#[cfg(feature = "c")] -mod c { - extern crate cc; - +#[cfg(any(feature = "c-vendor", feature = "c-system"))] +mod sources { use std::collections::BTreeMap; use std::env; - use std::path::PathBuf; - struct Sources { + pub struct Sources { // SYMBOL -> PATH TO SOURCE - map: BTreeMap<&'static str, &'static str>, + pub map: BTreeMap<&'static str, &'static str>, } impl Sources { @@ -120,39 +119,11 @@ mod c { } } - /// Compile intrinsics from the compiler-rt C source code - pub fn compile(llvm_target: &[&str]) { + pub fn get_sources(llvm_target: &[&str]) -> Sources { let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_vendor = env::var("CARGO_CFG_TARGET_VENDOR").unwrap(); - let cfg = &mut cc::Build::new(); - - cfg.warnings(false); - - if target_env == "msvc" { - // Don't pull in extra libraries on MSVC - cfg.flag("/Zl"); - - // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP - cfg.define("__func__", Some("__FUNCTION__")); - } else { - // Turn off various features of gcc and such, mostly copying - // compiler-rt's build system already - cfg.flag("-fno-builtin"); - cfg.flag("-fvisibility=hidden"); - cfg.flag("-ffreestanding"); - // Avoid the following warning appearing once **per file**: - // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument] - // - // Note that compiler-rt's build system also checks - // - // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)` - // - // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19. - cfg.flag_if_supported("-fomit-frame-pointer"); - cfg.define("VISIBILITY_HIDDEN", None); - } let mut sources = Sources::new(); sources.extend(&[ @@ -414,6 +385,48 @@ mod c { sources.remove(&["__aeabi_cdcmp", "__aeabi_cfcmp"]); } + sources + } +} + +#[cfg(feature = "c-vendor")] +mod c_vendor { + extern crate cc; + + use std::env; + use std::path::PathBuf; + use sources; + + /// Compile intrinsics from the compiler-rt C source code + pub fn compile(llvm_target: &[&str]) { + let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap(); + let cfg = &mut cc::Build::new(); + cfg.warnings(false); + + if target_env == "msvc" { + // Don't pull in extra libraries on MSVC + cfg.flag("/Zl"); + + // Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP + cfg.define("__func__", Some("__FUNCTION__")); + } else { + // Turn off various features of gcc and such, mostly copying + // compiler-rt's build system already + cfg.flag("-fno-builtin"); + cfg.flag("-fvisibility=hidden"); + cfg.flag("-ffreestanding"); + // Avoid the following warning appearing once **per file**: + // clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument] + // + // Note that compiler-rt's build system also checks + // + // `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)` + // + // in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19. + cfg.flag_if_supported("-fomit-frame-pointer"); + cfg.define("VISIBILITY_HIDDEN", None); + } + // When compiling the C code we require the user to tell us where the // source code is, and this is largely done so when we're compiling as // part of rust-lang/rust we can use the same llvm-project repository as @@ -431,6 +444,7 @@ mod c { // use of that macro in lib/builtins/int_util.h in compiler-rt. cfg.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display())); + let sources = sources::get_sources(llvm_target); let src_dir = root.join("lib/builtins"); for (sym, src) in sources.map.iter() { let src = src_dir.join(src); @@ -442,3 +456,41 @@ mod c { cfg.compile("libcompiler-rt.a"); } } + +#[cfg(feature = "c-system")] +mod c_system { + use std::env; + use std::process::Command; + use std::str; + use sources; + + /// Link against system clang runtime libraries + pub fn compile(llvm_target: &[&str]) { + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + + let llvm_config = env::var("LLVM_CONFIG").expect("LLVM_CONFIG not set"); + let (subpath, libname) = match target_os.as_str() { + "linux" => ("linux", format!("clang_rt.builtins-{}", llvm_target[0])), + "macos" => ("darwin", "clang_rt.builtins_osx_dynamic".to_string()), + _ => panic!("unsupported target os: {}", target_os), + }; + let cmd = format!("ls -1d $({} --libdir)/clang/*/lib/{}", llvm_config, subpath); + let output = Command::new("sh") + .args(&["-ec", &cmd]) + .output() + .expect("failed to find clang lib dir"); + let status = output.status; + if !status.success() { + panic!(format!("failed to find clang lib dir: {:?}", status.code())); + } + for search_dir in str::from_utf8(&output.stdout).unwrap().lines() { + println!("cargo:rustc-link-search=native={}", search_dir); + } + println!("cargo:rustc-link-lib=static={}", libname); + + let sources = sources::get_sources(llvm_target); + for (sym, _src) in sources.map.iter() { + println!("cargo:rustc-cfg={}=\"optimized-c\"", sym); + } + } +} diff --git a/testcrate/Cargo.toml b/testcrate/Cargo.toml index 3b99b574..d86f551d 100644 --- a/testcrate/Cargo.toml +++ b/testcrate/Cargo.toml @@ -23,6 +23,8 @@ utest-macros = { git = "https://github.com/japaric/utest" } [features] c = ["compiler_builtins/c"] +c-vendor = ["compiler_builtins/c-vendor"] +c-system = ["compiler_builtins/c-system"] mem = ["compiler_builtins/mem"] mangled-names = ["compiler_builtins/mangled-names"] default = ["mangled-names"] From ec70931aa532353f877485703b2a51a8a2f4406a Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Sat, 25 May 2019 13:06:49 -0700 Subject: [PATCH 2/6] Support using clang as well --- Cargo.toml | 3 +- build.rs | 92 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 74 insertions(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b489fa7e..f4826160 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,8 @@ default = ["compiler-builtins"] # implementations and also filling in unimplemented intrinsics c-vendor = ["cc"] -# Link against system clang_rt.* libraries. LLVM_CONFIG must be set. +# Link against system clang_rt.* libraries. +# LLVM_CONFIG or CLANG (more reliable) must be set. c-system = [] c = ["c-vendor"] diff --git a/build.rs b/build.rs index 3d90808d..4c5d7dfe 100644 --- a/build.rs +++ b/build.rs @@ -460,33 +460,85 @@ mod c_vendor { #[cfg(feature = "c-system")] mod c_system { use std::env; - use std::process::Command; + use std::process::{Command, Output}; use std::str; + use std::path::Path; use sources; - /// Link against system clang runtime libraries - pub fn compile(llvm_target: &[&str]) { - let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); - - let llvm_config = env::var("LLVM_CONFIG").expect("LLVM_CONFIG not set"); - let (subpath, libname) = match target_os.as_str() { - "linux" => ("linux", format!("clang_rt.builtins-{}", llvm_target[0])), - "macos" => ("darwin", "clang_rt.builtins_osx_dynamic".to_string()), - _ => panic!("unsupported target os: {}", target_os), - }; - let cmd = format!("ls -1d $({} --libdir)/clang/*/lib/{}", llvm_config, subpath); - let output = Command::new("sh") - .args(&["-ec", &cmd]) - .output() - .expect("failed to find clang lib dir"); + fn success_output(err: &str, cmd: &mut Command) -> Output { + let output = cmd.output().expect(err); let status = output.status; if !status.success() { - panic!(format!("failed to find clang lib dir: {:?}", status.code())); + panic!("{}: {:?}", err, status.code()); } - for search_dir in str::from_utf8(&output.stdout).unwrap().lines() { - println!("cargo:rustc-link-search=native={}", search_dir); + output + } + + // This function recreates the logic of getArchNameForCompilerRTLib, + // defined in clang/lib/Driver/ToolChain.cpp. + fn get_arch_name_for_compiler_rtlib() -> String { + let target = env::var("TARGET").unwrap(); + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + let r = match target_arch.as_str() { + "arm" => if target.ends_with("eabihf") && target_os != "windows" { + "armhf" + } else { + "arm" + }, + "x86" => if target_os == "android" { + "i686" + } else { + "i386" + }, + _ => target_arch.as_str(), + }; + r.to_string() + } + + /// Link against system clang runtime libraries + pub fn compile(llvm_target: &[&str]) { + let target = env::var("TARGET").unwrap(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); + let compiler_rt_arch = get_arch_name_for_compiler_rtlib(); + + if let Ok(clang) = env::var("CLANG") { + let output = success_output( + "failed to find clang's compiler-rt", + Command::new(clang) + .arg(format!("--target={}", target)) + .arg("--rtlib=compiler-rt") + .arg("--print-libgcc-file-name"), + ); + let fullpath = Path::new(str::from_utf8(&output.stdout).unwrap()); + let libpath = fullpath.parent().unwrap().display(); + let libname = fullpath + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim_start_matches("lib"); + println!("cargo:rustc-link-search=native={}", libpath); + println!("cargo:rustc-link-lib=static={}", libname); + } else if let Ok(llvm_config) = env::var("LLVM_CONFIG") { + // fallback if clang is not installed + let (subpath, libname) = match target_os.as_str() { + "linux" => ("linux", format!("clang_rt.builtins-{}", &compiler_rt_arch)), + "macos" => ("darwin", "clang_rt.builtins_osx_dynamic".to_string()), + _ => panic!("unsupported target os: {}", target_os), + }; + let cmd = format!("ls -1d $({} --libdir)/clang/*/lib/{}", llvm_config, subpath); + let output = success_output( + "failed to find clang's lib dir", + Command::new("sh").args(&["-ec", &cmd]), + ); + for search_dir in str::from_utf8(&output.stdout).unwrap().lines() { + println!("cargo:rustc-link-search=native={}", search_dir); + } + println!("cargo:rustc-link-lib=static={}", libname); + } else { + panic!("neither CLANG nor LLVM_CONFIG could be read"); } - println!("cargo:rustc-link-lib=static={}", libname); let sources = sources::get_sources(llvm_target); for (sym, _src) in sources.map.iter() { From 940006d0c7f9b7f173d9c0bfba963218cc385912 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Sat, 24 Aug 2019 10:17:24 -0700 Subject: [PATCH 3/6] Only link when the arch is actually supported by builtins --- build.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/build.rs b/build.rs index 4c5d7dfe..a9d2d97e 100644 --- a/build.rs +++ b/build.rs @@ -474,6 +474,12 @@ mod c_system { output } + // This can be obtained by adding the line: + // message(STATUS "All builtin supported architectures: ${ALL_BUILTIN_SUPPORTED_ARCH}") + // to the bottom of compiler-rt/cmake/builtin-config-ix.cmake, then running + // cmake and looking at the output. + const ALL_SUPPORTED_ARCHES : &'static str = "i386;x86_64;arm;armhf;armv6m;armv7m;armv7em;armv7;armv7s;armv7k;aarch64;hexagon;mips;mipsel;mips64;mips64el;powerpc64;powerpc64le;riscv32;riscv64;wasm32;wasm64"; + // This function recreates the logic of getArchNameForCompilerRTLib, // defined in clang/lib/Driver/ToolChain.cpp. fn get_arch_name_for_compiler_rtlib() -> String { @@ -502,6 +508,10 @@ mod c_system { let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let compiler_rt_arch = get_arch_name_for_compiler_rtlib(); + if ALL_SUPPORTED_ARCHES.split(";").find(|x| *x == compiler_rt_arch) == None { + return; + } + if let Ok(clang) = env::var("CLANG") { let output = success_output( "failed to find clang's compiler-rt", From eeaa5d2b3d3552a31a62f32c470a2ab69dc91e45 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Fri, 30 Aug 2019 18:23:53 -0700 Subject: [PATCH 4/6] When using system clang libs, filter out duplicate symbols --- Cargo.toml | 3 +- build.rs | 83 ++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f4826160..15ad600c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ core = { version = "1.0.0", optional = true, package = 'rustc-std-workspace-core [build-dependencies] cc = { optional = true, version = "1.0" } +ar = { optional = true, version = "0.8" } [dev-dependencies] panic-handler = { path = 'crates/panic-handler' } @@ -46,7 +47,7 @@ c-vendor = ["cc"] # Link against system clang_rt.* libraries. # LLVM_CONFIG or CLANG (more reliable) must be set. -c-system = [] +c-system = ["ar"] c = ["c-vendor"] diff --git a/build.rs b/build.rs index a9d2d97e..0fd7c463 100644 --- a/build.rs +++ b/build.rs @@ -459,10 +459,15 @@ mod c_vendor { #[cfg(feature = "c-system")] mod c_system { + extern crate ar; + + use std::collections::HashMap; use std::env; + use std::fs::File; use std::process::{Command, Output}; use std::str; - use std::path::Path; + use std::path::{Path, PathBuf}; + use sources; fn success_output(err: &str, cmd: &mut Command) -> Output { @@ -502,17 +507,37 @@ mod c_system { r.to_string() } + fn find_library(dirs: I, libname: &str) -> Result> + where + I: Iterator + { + let mut paths = Vec::new(); + for dir in dirs { + let try_path = dir.join(format!("lib{}.a", libname)); + if try_path.exists() { + return Ok(try_path.to_path_buf()); + } else { + paths.push(format!("{:?}", try_path)) + } + } + Err(paths) + } + /// Link against system clang runtime libraries pub fn compile(llvm_target: &[&str]) { let target = env::var("TARGET").unwrap(); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let compiler_rt_arch = get_arch_name_for_compiler_rtlib(); + let out_dir = env::var("OUT_DIR").unwrap(); if ALL_SUPPORTED_ARCHES.split(";").find(|x| *x == compiler_rt_arch) == None { return; } - if let Ok(clang) = env::var("CLANG") { + println!("cargo:rerun-if-env-changed=CLANG"); + println!("cargo:rerun-if-env-changed=LLVM_CONFIG"); + + let fullpath = if let Ok(clang) = env::var("CLANG") { let output = success_output( "failed to find clang's compiler-rt", Command::new(clang) @@ -520,16 +545,8 @@ mod c_system { .arg("--rtlib=compiler-rt") .arg("--print-libgcc-file-name"), ); - let fullpath = Path::new(str::from_utf8(&output.stdout).unwrap()); - let libpath = fullpath.parent().unwrap().display(); - let libname = fullpath - .file_stem() - .unwrap() - .to_str() - .unwrap() - .trim_start_matches("lib"); - println!("cargo:rustc-link-search=native={}", libpath); - println!("cargo:rustc-link-lib=static={}", libname); + let path = str::from_utf8(&output.stdout).unwrap().trim_end(); + Path::new(path).to_path_buf() } else if let Ok(llvm_config) = env::var("LLVM_CONFIG") { // fallback if clang is not installed let (subpath, libname) = match target_os.as_str() { @@ -537,22 +554,52 @@ mod c_system { "macos" => ("darwin", "clang_rt.builtins_osx_dynamic".to_string()), _ => panic!("unsupported target os: {}", target_os), }; - let cmd = format!("ls -1d $({} --libdir)/clang/*/lib/{}", llvm_config, subpath); let output = success_output( - "failed to find clang's lib dir", - Command::new("sh").args(&["-ec", &cmd]), + "failed to find llvm-config's lib dir", + Command::new(llvm_config).arg("--libdir"), ); - for search_dir in str::from_utf8(&output.stdout).unwrap().lines() { - println!("cargo:rustc-link-search=native={}", search_dir); + let libdir = str::from_utf8(&output.stdout).unwrap().trim_end(); + let paths = std::fs::read_dir(Path::new(libdir).join("clang")).unwrap().map(|e| { + e.unwrap().path().join("lib").join(subpath) + }); + match find_library(paths, &libname) { + Ok(p) => p, + Err(paths) => panic!("failed to find llvm-config's compiler-rt: {}", paths.join(":")), } - println!("cargo:rustc-link-lib=static={}", libname); } else { panic!("neither CLANG nor LLVM_CONFIG could be read"); + }; + + let mut index = 0; + let mut files = HashMap::new(); + let mut orig = ar::Archive::new(File::open(&fullpath).unwrap()); + while let Some(entry_result) = orig.next_entry() { + let entry = entry_result.unwrap(); + let name = str::from_utf8(entry.header().identifier()).unwrap(); + files.insert(name.to_owned(), index); + index += 1; } let sources = sources::get_sources(llvm_target); + let mut new = ar::Builder::new(File::create(Path::new(&out_dir).join("libcompiler-rt.a")).unwrap()); for (sym, _src) in sources.map.iter() { + let &i = { + let sym_ = if sym.starts_with("__") { &sym[2..] } else { &sym }; + match files.get(&format!("{}.c.o", sym_)) { + Some(i) => i, + None => match files.get(&format!("{}.S.o", sym_)) { + Some(i) => i, + None => panic!("could not find expected symbol {} in {:?}", sym, &fullpath), + }, + } + }; + let mut entry = orig.jump_to_entry(i).unwrap(); + // TODO: ar really should have an append_entry to avoid the clone + new.append(&entry.header().clone(), &mut entry).unwrap(); println!("cargo:rustc-cfg={}=\"optimized-c\"", sym); } + + println!("cargo:rustc-link-search=native={}", out_dir); + println!("cargo:rustc-link-lib=static={}", "compiler-rt"); } } From e4384f6106b255307ee8085b82674e8d3a30c6c5 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Wed, 11 Sep 2019 23:04:14 -0700 Subject: [PATCH 5/6] Run rustfmt --- build.rs | 56 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/build.rs b/build.rs index 0fd7c463..abb544e5 100644 --- a/build.rs +++ b/build.rs @@ -393,9 +393,9 @@ mod sources { mod c_vendor { extern crate cc; + use sources; use std::env; use std::path::PathBuf; - use sources; /// Compile intrinsics from the compiler-rt C source code pub fn compile(llvm_target: &[&str]) { @@ -464,9 +464,9 @@ mod c_system { use std::collections::HashMap; use std::env; use std::fs::File; + use std::path::{Path, PathBuf}; use std::process::{Command, Output}; use std::str; - use std::path::{Path, PathBuf}; use sources; @@ -492,16 +492,20 @@ mod c_system { let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let r = match target_arch.as_str() { - "arm" => if target.ends_with("eabihf") && target_os != "windows" { - "armhf" - } else { - "arm" - }, - "x86" => if target_os == "android" { - "i686" - } else { - "i386" - }, + "arm" => { + if target.ends_with("eabihf") && target_os != "windows" { + "armhf" + } else { + "arm" + } + } + "x86" => { + if target_os == "android" { + "i686" + } else { + "i386" + } + } _ => target_arch.as_str(), }; r.to_string() @@ -509,7 +513,7 @@ mod c_system { fn find_library(dirs: I, libname: &str) -> Result> where - I: Iterator + I: Iterator, { let mut paths = Vec::new(); for dir in dirs { @@ -530,7 +534,11 @@ mod c_system { let compiler_rt_arch = get_arch_name_for_compiler_rtlib(); let out_dir = env::var("OUT_DIR").unwrap(); - if ALL_SUPPORTED_ARCHES.split(";").find(|x| *x == compiler_rt_arch) == None { + if ALL_SUPPORTED_ARCHES + .split(";") + .find(|x| *x == compiler_rt_arch) + == None + { return; } @@ -559,12 +567,15 @@ mod c_system { Command::new(llvm_config).arg("--libdir"), ); let libdir = str::from_utf8(&output.stdout).unwrap().trim_end(); - let paths = std::fs::read_dir(Path::new(libdir).join("clang")).unwrap().map(|e| { - e.unwrap().path().join("lib").join(subpath) - }); + let paths = std::fs::read_dir(Path::new(libdir).join("clang")) + .unwrap() + .map(|e| e.unwrap().path().join("lib").join(subpath)); match find_library(paths, &libname) { Ok(p) => p, - Err(paths) => panic!("failed to find llvm-config's compiler-rt: {}", paths.join(":")), + Err(paths) => panic!( + "failed to find llvm-config's compiler-rt: {}", + paths.join(":") + ), } } else { panic!("neither CLANG nor LLVM_CONFIG could be read"); @@ -581,10 +592,15 @@ mod c_system { } let sources = sources::get_sources(llvm_target); - let mut new = ar::Builder::new(File::create(Path::new(&out_dir).join("libcompiler-rt.a")).unwrap()); + let mut new = + ar::Builder::new(File::create(Path::new(&out_dir).join("libcompiler-rt.a")).unwrap()); for (sym, _src) in sources.map.iter() { let &i = { - let sym_ = if sym.starts_with("__") { &sym[2..] } else { &sym }; + let sym_ = if sym.starts_with("__") { + &sym[2..] + } else { + &sym + }; match files.get(&format!("{}.c.o", sym_)) { Some(i) => i, None => match files.get(&format!("{}.S.o", sym_)) { From ca5aece420b44e3e7dcd611f269a15a799486f25 Mon Sep 17 00:00:00 2001 From: Ximin Luo Date: Fri, 13 Sep 2019 01:20:23 -0700 Subject: [PATCH 6/6] Test the c-system feature in CI as well --- .../aarch64-unknown-linux-gnu/Dockerfile | 18 +++++++++++++++-- .../armv7-unknown-linux-gnueabihf/Dockerfile | 19 ++++++++++++++++-- ci/docker/i686-unknown-linux-gnu/Dockerfile | 4 +++- .../powerpc64le-unknown-linux-gnu/Dockerfile | 20 ++++++++++++++++--- ci/docker/x86_64-unknown-linux-gnu/Dockerfile | 2 +- ci/run.sh | 8 ++++++++ 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/ci/docker/aarch64-unknown-linux-gnu/Dockerfile index 9e2559f4..8d031d18 100644 --- a/ci/docker/aarch64-unknown-linux-gnu/Dockerfile +++ b/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -1,10 +1,24 @@ FROM ubuntu:18.04 -RUN apt-get update && \ +RUN dpkg --add-architecture arm64 && \ + sed -e "\,security.ubuntu.com/ubuntu,p;s,security.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -e "\,archive.ubuntu.com/ubuntu,p;s,archive.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -i /etc/apt/sources.list && \ + sed -e "\,security.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,archive.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,ports.ubuntu.com/ubuntu-ports,s.^deb .deb [ arch=arm64 ] .g" \ + -i /etc/apt/sources.list && \ + apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ gcc-aarch64-linux-gnu libc6-dev-arm64-cross \ - qemu-user-static + clang xz-utils \ + qemu-user-static && \ + cd /tmp && \ + apt-get download libclang-common-6.0-dev:arm64 && \ + ar xf libclang-common-6.0-dev_*_arm64.deb && \ + tar -C/ -xf data.tar.xz ."$(dirname $(clang -rtlib=compiler-rt --print-libgcc-file-name))" ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER=qemu-aarch64-static \ QEMU_LD_PREFIX=/usr/aarch64-linux-gnu \ + CLANG=clang \ RUST_TEST_THREADS=1 diff --git a/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile index 6617af15..478b57a5 100644 --- a/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile +++ b/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile @@ -1,9 +1,24 @@ FROM ubuntu:18.04 -RUN apt-get update && \ +RUN dpkg --add-architecture armhf && \ + sed -e "\,security.ubuntu.com/ubuntu,p;s,security.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -e "\,archive.ubuntu.com/ubuntu,p;s,archive.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -i /etc/apt/sources.list && \ + sed -e "\,security.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,archive.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,ports.ubuntu.com/ubuntu-ports,s.^deb .deb [ arch=armhf ] .g" \ + -i /etc/apt/sources.list && \ + apt-get update && \ apt-get install -y --no-install-recommends \ gcc libc6-dev ca-certificates \ - gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user-static + gcc-arm-linux-gnueabihf libc6-dev-armhf-cross \ + clang xz-utils \ + qemu-user-static && \ + cd /tmp && \ + apt-get download libclang-common-6.0-dev:armhf && \ + ar xf libclang-common-6.0-dev_*_armhf.deb && \ + tar -C/ -xf data.tar.xz ."$(dirname $(clang -rtlib=compiler-rt --print-libgcc-file-name))" ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER=qemu-arm-static \ QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf \ + CLANG=clang \ RUST_TEST_THREADS=1 diff --git a/ci/docker/i686-unknown-linux-gnu/Dockerfile b/ci/docker/i686-unknown-linux-gnu/Dockerfile index 5783e28e..9e3daab2 100644 --- a/ci/docker/i686-unknown-linux-gnu/Dockerfile +++ b/ci/docker/i686-unknown-linux-gnu/Dockerfile @@ -1,4 +1,6 @@ FROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc-multilib libc6-dev ca-certificates + gcc-multilib libc6-dev ca-certificates \ + clang +ENV CLANG=clang diff --git a/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile b/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile index 63ea9af9..9069eba7 100644 --- a/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile +++ b/ci/docker/powerpc64le-unknown-linux-gnu/Dockerfile @@ -1,13 +1,27 @@ FROM ubuntu:18.04 -RUN apt-get update && \ +RUN dpkg --add-architecture ppc64el && \ + sed -e "\,security.ubuntu.com/ubuntu,p;s,security.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -e "\,archive.ubuntu.com/ubuntu,p;s,archive.ubuntu.com/ubuntu,ports.ubuntu.com/ubuntu-ports,g" \ + -i /etc/apt/sources.list && \ + sed -e "\,security.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,archive.ubuntu.com/ubuntu,s.^deb .deb [ arch=amd64,i386 ] .g" \ + -e "\,ports.ubuntu.com/ubuntu-ports,s.^deb .deb [ arch=ppc64el ] .g" \ + -i /etc/apt/sources.list && \ + apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev qemu-user-static ca-certificates \ + gcc libc6-dev ca-certificates \ gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross \ - qemu-system-ppc + clang xz-utils \ + qemu-user-static qemu-system-ppc && \ + cd /tmp && \ + apt-get download libclang-common-6.0-dev:ppc64el && \ + ar xf libclang-common-6.0-dev_*_ppc64el.deb && \ + tar -C/ -xf data.tar.xz ."$(dirname $(clang -rtlib=compiler-rt --print-libgcc-file-name))" ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER=powerpc64le-linux-gnu-gcc \ CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \ QEMU_CPU=POWER8 \ QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \ + CLANG=clang \ RUST_TEST_THREADS=1 diff --git a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile index 98000f4e..27d3b78d 100644 --- a/ci/docker/x86_64-unknown-linux-gnu/Dockerfile +++ b/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -1,4 +1,4 @@ FROM ubuntu:18.04 RUN apt-get update && \ apt-get install -y --no-install-recommends \ - gcc libc6-dev ca-certificates + gcc libc6-dev ca-certificates clang diff --git a/ci/run.sh b/ci/run.sh index ae32806e..254f8da6 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -18,6 +18,10 @@ cargo build --target $1 cargo build --target $1 --release cargo build --target $1 --features c cargo build --target $1 --release --features c +if [ -n "$CLANG" -o -n "$LLVM_CONFIG" ]; then +cargo build --target $1 --features c-system +cargo build --target $1 --release --features c-system +fi PREFIX=$(echo $1 | sed -e 's/unknown-//')- case $1 in @@ -77,6 +81,10 @@ RUSTFLAGS="-C debug-assertions=no" $build_intrinsics RUSTFLAGS="-C debug-assertions=no" $build_intrinsics --release RUSTFLAGS="-C debug-assertions=no" $build_intrinsics --features c RUSTFLAGS="-C debug-assertions=no" $build_intrinsics --features c --release +if [ -n "$CLANG" -o -n "$LLVM_CONFIG" ]; then +RUSTFLAGS="-C debug-assertions=no" $build_intrinsics --features c-system +RUSTFLAGS="-C debug-assertions=no" $build_intrinsics --features c-system --release +fi # Verify that there are no undefined symbols to `panic` within our # implementations