diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2016-07-16 15:08:25 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2016-07-20 13:22:20 -0700 |
| commit | ee6011fc71e02485f2dffcc25be64631c2008775 (patch) | |
| tree | 4a466b19d777614f9ca63c72b32626261f288c16 /src/bootstrap | |
| parent | b45c15eccaeca39099db3c8028e7a73e5caf6503 (diff) | |
| download | rust-ee6011fc71e02485f2dffcc25be64631c2008775.tar.gz rust-ee6011fc71e02485f2dffcc25be64631c2008775.zip | |
mk: Stop using cmake for compiler-rt
The compiler-rt build system has been a never ending cause of pain for Rust unfortunately: * The build system is very difficult to invoke and configure to only build compiler-rt, especially across platforms. * The standard build system doesn't actually do what we want, not working for some of our platforms and requiring a significant number of patches on our end which are difficult to apply when updating compiler-rt. * Compiling compiler-rt requires LLVM to be compiled, which... is a big dependency! This also means that over time compiler-rt is not guaranteed to build against older versions of LLVM (or newer versions), and we often want to work with multiple versions of LLVM simultaneously. The makefiles and rustbuild already know how to compile C code, the code here is far from the *only* C code we're compiling. This patch jettisons all logic to work with compiler-rt's build system and just goes straight to the source. We just list all files manually (copied from compiler-rt's lib/builtins/CMakeLists.txt) and compile them into an archive. It's likely that this means we'll fail to pick up new files when we upgrade compiler-rt, but that seems like a much less significant cost to pay than what we're currently paying. cc #34400, first steps towards that
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/Cargo.lock | 11 | ||||
| -rw-r--r-- | src/bootstrap/Cargo.toml | 2 | ||||
| -rw-r--r-- | src/bootstrap/native.rs | 457 | ||||
| -rw-r--r-- | src/bootstrap/step.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/util.rs | 5 |
5 files changed, 397 insertions, 82 deletions
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 39c7a375011..1290f2a404b 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -5,7 +5,7 @@ dependencies = [ "build_helper 0.1.0", "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -25,7 +25,7 @@ name = "cmake" version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -38,7 +38,12 @@ dependencies = [ [[package]] name = "gcc" -version = "0.3.26" +version = "0.3.31" +source = "git+https://github.com/alexcrichton/gcc-rs#b8e2400883f1a2749b323354dad372cdd1c838c7" + +[[package]] +name = "gcc" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index cde4a825be1..02746034cca 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -29,6 +29,6 @@ getopts = "0.2" rustc-serialize = "0.3" winapi = "0.2" kernel32-sys = "0.2" -gcc = "0.3.17" +gcc = { git = "https://github.com/alexcrichton/gcc-rs" } libc = "0.2" md5 = "0.1" diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 83e9393fbae..05ecbc0cada 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -133,86 +133,395 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) { /// Compiles the `compiler-rt` library, or at least the builtins part of it. /// -/// This uses the CMake build system and an existing LLVM build directory to -/// compile the project. +/// Note that while compiler-rt has a build system associated with it, we +/// specifically don't use it here. The compiler-rt build system, written in +/// CMake, is actually *very* difficult to work with in terms of getting it to +/// compile on all the relevant platforms we want it to compile on. In the end +/// it became so much pain to work with local patches, work around the oddities +/// of the build system, etc, that we're just building everything by hand now. +/// +/// In general compiler-rt is just a bunch of intrinsics that are in practice +/// *very* stable. We just need to make sure that all the relevant functions and +/// such are compiled somewhere and placed in an object file somewhere. +/// Eventually, these should all be written in Rust! +/// +/// So below you'll find a listing of every single file in the compiler-rt repo +/// that we're compiling. We just reach in and compile with the `gcc` crate +/// which should have all the relevant flags and such already configured. +/// +/// The risk here is that if we update compiler-rt we may need to compile some +/// new intrinsics, but to be honest we surely don't use all of the intrinsics +/// listed below today so the likelihood of us actually needing a new intrinsic +/// is quite low. The failure case is also just that someone reports a link +/// error (if any) and then we just add it to the list. Overall, that cost is +/// far far less than working with compiler-rt's build system over time. pub fn compiler_rt(build: &Build, target: &str) { - let dst = build.compiler_rt_out(target); - let arch = target.split('-').next().unwrap(); - let mode = if build.config.rust_optimize {"Release"} else {"Debug"}; + let build_dir = build.compiler_rt_out(target); + let output = build_dir.join(staticlib("compiler-rt", target)); + build.compiler_rt_built.borrow_mut().insert(target.to_string(), + output.clone()); + t!(fs::create_dir_all(&build_dir)); - let build_llvm_config = build.llvm_config(&build.config.build); - let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt")); - cfg.target(target) + let mut cfg = gcc::Config::new(); + cfg.cargo_metadata(false) + .out_dir(&build_dir) + .target(target) .host(&build.config.build) - .out_dir(&dst) - .profile(mode) - .define("LLVM_CONFIG_PATH", build_llvm_config) - .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target) - .define("COMPILER_RT_BUILD_SANITIZERS", "OFF") - .define("COMPILER_RT_BUILD_EMUTLS", "OFF") - // inform about c/c++ compilers, the c++ compiler isn't actually used but - // it's needed to get the initial configure to work on all platforms. - .define("CMAKE_C_COMPILER", build.cc(target)) - .define("CMAKE_CXX_COMPILER", build.cc(target)); - - let (dir, build_target, libname) = if target.contains("linux") || - target.contains("freebsd") || - target.contains("netbsd") { - let os_extra = if target.contains("android") && target.contains("arm") { - "-android" - } else { - "" - }; - let builtins_arch = match arch { - "i586" => "i386", - "arm" | "armv7" if target.contains("android") => "armhf", - "arm" if target.contains("eabihf") => "armhf", - _ => arch, - }; - let target = format!("clang_rt.builtins-{}", builtins_arch); - ("linux".to_string(), - target.clone(), - format!("{}{}", target, os_extra)) - } else if target.contains("apple-darwin") { - let builtins_arch = match arch { - "i686" => "i386", - _ => arch, - }; - let target = format!("clang_rt.builtins_{}_osx", builtins_arch); - ("builtins".to_string(), target.clone(), target) - } else if target.contains("apple-ios") { - cfg.define("COMPILER_RT_ENABLE_IOS", "ON"); - let target = match arch { - "armv7s" => "hard_pic_armv7em_macho_embedded".to_string(), - "aarch64" => "builtins_arm64_ios".to_string(), - _ => format!("hard_pic_{}_macho_embedded", arch), - }; - ("builtins".to_string(), target.clone(), target) - } else if target.contains("windows-gnu") { - let target = format!("clang_rt.builtins-{}", arch); - ("windows".to_string(), target.clone(), target) - } else if target.contains("windows-msvc") { - let builtins_arch = match arch { - "i586" | "i686" => "i386", - _ => arch, - }; - (format!("windows/{}", mode), - "lib/builtins/builtins".to_string(), - format!("clang_rt.builtins-{}", builtins_arch)) + .opt_level(2) + .debug(false); + + if target.contains("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 { - panic!("can't get os from target: {}", target) - }; - let output = dst.join("build/lib").join(dir) - .join(staticlib(&libname, target)); - build.compiler_rt_built.borrow_mut().insert(target.to_string(), - output.clone()); - if fs::metadata(&output).is_ok() { + // 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("-fomit-frame-pointer"); + cfg.flag("-ffreestanding"); + } + + let mut sources = vec![ + "absvdi2.c", + "absvsi2.c", + "adddf3.c", + "addsf3.c", + "addvdi3.c", + "addvsi3.c", + "apple_versioning.c", + "ashldi3.c", + "ashrdi3.c", + "clear_cache.c", + "clzdi2.c", + "clzsi2.c", + "cmpdi2.c", + "comparedf2.c", + "comparesf2.c", + "ctzdi2.c", + "ctzsi2.c", + "divdc3.c", + "divdf3.c", + "divdi3.c", + "divmoddi4.c", + "divmodsi4.c", + "divsc3.c", + "divsf3.c", + "divsi3.c", + "divxc3.c", + "extendsfdf2.c", + "extendhfsf2.c", + "ffsdi2.c", + "fixdfdi.c", + "fixdfsi.c", + "fixsfdi.c", + "fixsfsi.c", + "fixunsdfdi.c", + "fixunsdfsi.c", + "fixunssfdi.c", + "fixunssfsi.c", + "fixunsxfdi.c", + "fixunsxfsi.c", + "fixxfdi.c", + "floatdidf.c", + "floatdisf.c", + "floatdixf.c", + "floatsidf.c", + "floatsisf.c", + "floatundidf.c", + "floatundisf.c", + "floatundixf.c", + "floatunsidf.c", + "floatunsisf.c", + "int_util.c", + "lshrdi3.c", + "moddi3.c", + "modsi3.c", + "muldc3.c", + "muldf3.c", + "muldi3.c", + "mulodi4.c", + "mulosi4.c", + "muloti4.c", + "mulsc3.c", + "mulsf3.c", + "mulvdi3.c", + "mulvsi3.c", + "mulxc3.c", + "negdf2.c", + "negdi2.c", + "negsf2.c", + "negvdi2.c", + "negvsi2.c", + "paritydi2.c", + "paritysi2.c", + "popcountdi2.c", + "popcountsi2.c", + "powidf2.c", + "powisf2.c", + "powixf2.c", + "subdf3.c", + "subsf3.c", + "subvdi3.c", + "subvsi3.c", + "truncdfhf2.c", + "truncdfsf2.c", + "truncsfhf2.c", + "ucmpdi2.c", + "udivdi3.c", + "udivmoddi4.c", + "udivmodsi4.c", + "udivsi3.c", + "umoddi3.c", + "umodsi3.c", + ]; + + if !target.contains("ios") { + sources.extend(vec![ + "absvti2.c", + "addtf3.c", + "addvti3.c", + "ashlti3.c", + "ashrti3.c", + "clzti2.c", + "cmpti2.c", + "ctzti2.c", + "divtf3.c", + "divti3.c", + "ffsti2.c", + "fixdfti.c", + "fixsfti.c", + "fixunsdfti.c", + "fixunssfti.c", + "fixunsxfti.c", + "fixxfti.c", + "floattidf.c", + "floattisf.c", + "floattixf.c", + "floatuntidf.c", + "floatuntisf.c", + "floatuntixf.c", + "lshrti3.c", + "modti3.c", + "multf3.c", + "multi3.c", + "mulvti3.c", + "negti2.c", + "negvti2.c", + "parityti2.c", + "popcountti2.c", + "powitf2.c", + "subtf3.c", + "subvti3.c", + "trampoline_setup.c", + "ucmpti2.c", + "udivmodti4.c", + "udivti3.c", + "umodti3.c", + ]); + } + + if target.contains("apple") { + sources.extend(vec![ + "atomic_flag_clear.c", + "atomic_flag_clear_explicit.c", + "atomic_flag_test_and_set.c", + "atomic_flag_test_and_set_explicit.c", + "atomic_signal_fence.c", + "atomic_thread_fence.c", + ]); + } + + if !target.contains("windows") { + sources.push("emutls.c"); + } + + if target.contains("msvc") { + if target.contains("x86_64") { + sources.extend(vec![ + "x86_64/floatdidf.c", + "x86_64/floatdisf.c", + "x86_64/floatdixf.c", + ]); + } + } else { + sources.push("gcc_personality_v0.c"); + + if target.contains("x86_64") { + sources.extend(vec![ + "x86_64/chkstk.S", + "x86_64/chkstk2.S", + "x86_64/floatdidf.c", + "x86_64/floatdisf.c", + "x86_64/floatdixf.c", + "x86_64/floatundidf.S", + "x86_64/floatundisf.S", + "x86_64/floatundixf.S", + ]); + } + + if target.contains("i386") || + target.contains("i586") || + target.contains("i686") { + sources.extend(vec![ + "i386/ashldi3.S", + "i386/ashrdi3.S", + "i386/chkstk.S", + "i386/chkstk2.S", + "i386/divdi3.S", + "i386/floatdidf.S", + "i386/floatdisf.S", + "i386/floatdixf.S", + "i386/floatundidf.S", + "i386/floatundisf.S", + "i386/floatundixf.S", + "i386/lshrdi3.S", + "i386/moddi3.S", + "i386/muldi3.S", + "i386/udivdi3.S", + "i386/umoddi3.S", + ]); + } + } + + if target.contains("arm") && !target.contains("ios") { + sources.extend(vec![ + "arm/aeabi_cdcmp.S", + "arm/aeabi_cdcmpeq_check_nan.c", + "arm/aeabi_cfcmp.S", + "arm/aeabi_cfcmpeq_check_nan.c", + "arm/aeabi_dcmp.S", + "arm/aeabi_div0.c", + "arm/aeabi_drsub.c", + "arm/aeabi_fcmp.S", + "arm/aeabi_frsub.c", + "arm/aeabi_idivmod.S", + "arm/aeabi_ldivmod.S", + "arm/aeabi_memcmp.S", + "arm/aeabi_memcpy.S", + "arm/aeabi_memmove.S", + "arm/aeabi_memset.S", + "arm/aeabi_uidivmod.S", + "arm/aeabi_uldivmod.S", + "arm/bswapdi2.S", + "arm/bswapsi2.S", + "arm/clzdi2.S", + "arm/clzsi2.S", + "arm/comparesf2.S", + "arm/divmodsi4.S", + "arm/divsi3.S", + "arm/modsi3.S", + "arm/switch16.S", + "arm/switch32.S", + "arm/switch8.S", + "arm/switchu8.S", + "arm/sync_synchronize.S", + "arm/udivmodsi4.S", + "arm/udivsi3.S", + "arm/umodsi3.S", + ]); + } + + if target.contains("armv7") { + sources.extend(vec![ + "arm/sync_fetch_and_add_4.S", + "arm/sync_fetch_and_add_8.S", + "arm/sync_fetch_and_and_4.S", + "arm/sync_fetch_and_and_8.S", + "arm/sync_fetch_and_max_4.S", + "arm/sync_fetch_and_max_8.S", + "arm/sync_fetch_and_min_4.S", + "arm/sync_fetch_and_min_8.S", + "arm/sync_fetch_and_nand_4.S", + "arm/sync_fetch_and_nand_8.S", + "arm/sync_fetch_and_or_4.S", + "arm/sync_fetch_and_or_8.S", + "arm/sync_fetch_and_sub_4.S", + "arm/sync_fetch_and_sub_8.S", + "arm/sync_fetch_and_umax_4.S", + "arm/sync_fetch_and_umax_8.S", + "arm/sync_fetch_and_umin_4.S", + "arm/sync_fetch_and_umin_8.S", + "arm/sync_fetch_and_xor_4.S", + "arm/sync_fetch_and_xor_8.S", + ]); + } + + if target.contains("eabihf") { + sources.extend(vec![ + "arm/adddf3vfp.S", + "arm/addsf3vfp.S", + "arm/divdf3vfp.S", + "arm/divsf3vfp.S", + "arm/eqdf2vfp.S", + "arm/eqsf2vfp.S", + "arm/extendsfdf2vfp.S", + "arm/fixdfsivfp.S", + "arm/fixsfsivfp.S", + "arm/fixunsdfsivfp.S", + "arm/fixunssfsivfp.S", + "arm/floatsidfvfp.S", + "arm/floatsisfvfp.S", + "arm/floatunssidfvfp.S", + "arm/floatunssisfvfp.S", + "arm/gedf2vfp.S", + "arm/gesf2vfp.S", + "arm/gtdf2vfp.S", + "arm/gtsf2vfp.S", + "arm/ledf2vfp.S", + "arm/lesf2vfp.S", + "arm/ltdf2vfp.S", + "arm/ltsf2vfp.S", + "arm/muldf3vfp.S", + "arm/mulsf3vfp.S", + "arm/negdf2vfp.S", + "arm/negsf2vfp.S", + "arm/nedf2vfp.S", + "arm/nesf2vfp.S", + "arm/restore_vfp_d8_d15_regs.S", + "arm/save_vfp_d8_d15_regs.S", + "arm/subdf3vfp.S", + "arm/subsf3vfp.S", + "arm/truncdfsf2vfp.S", + "arm/unorddf2vfp.S", + "arm/unordsf2vfp.S", + ]); + } + + if target.contains("aarch64") { + sources.extend(vec![ + "comparetf2.c", + "extenddftf2.c", + "extendsftf2.c", + "fixtfdi.c", + "fixtfsi.c", + "fixtfti.c", + "fixunstfdi.c", + "fixunstfsi.c", + "fixunstfti.c", + "floatditf.c", + "floatsitf.c", + "floatunditf.c", + "floatunsitf.c", + "multc3.c", + "trunctfdf2.c", + "trunctfsf2.c", + ]); + } + + let mut out_of_date = false; + for src in sources { + let src = build.src.join("src/compiler-rt/lib/builtins").join(src); + out_of_date = out_of_date || !up_to_date(&src, &output); + cfg.file(src); + } + if !out_of_date { return } - let _ = fs::remove_dir_all(&dst); - t!(fs::create_dir_all(&dst)); - cfg.build_target(&build_target); - cfg.build(); + cfg.compile("libcompiler-rt.a"); } /// Compiles the `rust_test_helpers.c` library which we used in various diff --git a/src/bootstrap/step.rs b/src/bootstrap/step.rs index 82ae70d22ca..1ce8c731232 100644 --- a/src/bootstrap/step.rs +++ b/src/bootstrap/step.rs @@ -347,9 +347,7 @@ impl<'a> Step<'a> { vec![self.libstd(compiler), self.target(host).rustc(compiler.stage)] } - Source::CompilerRt { _dummy } => { - vec![self.llvm(()).target(&build.config.build)] - } + Source::CompilerRt { _dummy } => Vec::new(), Source::Llvm { _dummy } => Vec::new(), Source::TestHelpers { _dummy } => Vec::new(), Source::DebuggerScripts { stage: _ } => Vec::new(), diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 3ef7f8cab2d..b5230132bcb 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -103,7 +103,10 @@ pub fn add_lib_path(path: Vec<PathBuf>, cmd: &mut Command) { /// Uses last-modified time checks to verify this. pub fn up_to_date(src: &Path, dst: &Path) -> bool { let threshold = mtime(dst); - let meta = t!(fs::metadata(src)); + let meta = match fs::metadata(src) { + Ok(meta) => meta, + Err(e) => panic!("source {:?} failed to get metadata: {}", src, e), + }; if meta.is_dir() { dir_up_to_date(src, &threshold) } else { |
