From ee6011fc71e02485f2dffcc25be64631c2008775 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 16 Jul 2016 15:08:25 -0700 Subject: [PATCH] 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 --- mk/rt.mk | 428 +++++++++++++++++++++++++++--------- src/bootstrap/Cargo.lock | 11 +- src/bootstrap/Cargo.toml | 2 +- src/bootstrap/native.rs | 457 ++++++++++++++++++++++++++++++++------- src/bootstrap/step.rs | 4 +- src/bootstrap/util.rs | 5 +- 6 files changed, 724 insertions(+), 183 deletions(-) diff --git a/mk/rt.mk b/mk/rt.mk index 8113b68380744..067721fab4fa8 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -223,147 +223,373 @@ endif # compiler-rt ################################################################################ -ifdef CFG_ENABLE_FAST_MAKE -COMPRT_DEPS := $(S)/.gitmodules -else -COMPRT_DEPS := $(wildcard \ - $(S)src/compiler-rt/* \ - $(S)src/compiler-rt/*/* \ - $(S)src/compiler-rt/*/*/* \ - $(S)src/compiler-rt/*/*/*/*) -endif - -# compiler-rt's build system is a godawful mess. Here we figure out -# the ridiculous platform-specific values and paths necessary to get -# useful artifacts out of it. +# Everything below is a manual compilation of compiler-rt, disregarding its +# build system. See comments in `src/bootstrap/native.rs` for more information. COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt) COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1)) COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt -COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1))) +# GENERIC_SOURCES in CMakeLists.txt +COMPRT_OBJS_$(1) := \ + absvdi2.o \ + absvsi2.o \ + adddf3.o \ + addsf3.o \ + addvdi3.o \ + addvsi3.o \ + apple_versioning.o \ + ashldi3.o \ + ashrdi3.o \ + clear_cache.o \ + clzdi2.o \ + clzsi2.o \ + cmpdi2.o \ + comparedf2.o \ + comparesf2.o \ + ctzdi2.o \ + ctzsi2.o \ + divdc3.o \ + divdf3.o \ + divdi3.o \ + divmoddi4.o \ + divmodsi4.o \ + divsc3.o \ + divsf3.o \ + divsi3.o \ + divxc3.o \ + extendsfdf2.o \ + extendhfsf2.o \ + ffsdi2.o \ + fixdfdi.o \ + fixdfsi.o \ + fixsfdi.o \ + fixsfsi.o \ + fixunsdfdi.o \ + fixunsdfsi.o \ + fixunssfdi.o \ + fixunssfsi.o \ + fixunsxfdi.o \ + fixunsxfsi.o \ + fixxfdi.o \ + floatdidf.o \ + floatdisf.o \ + floatdixf.o \ + floatsidf.o \ + floatsisf.o \ + floatundidf.o \ + floatundisf.o \ + floatundixf.o \ + floatunsidf.o \ + floatunsisf.o \ + int_util.o \ + lshrdi3.o \ + moddi3.o \ + modsi3.o \ + muldc3.o \ + muldf3.o \ + muldi3.o \ + mulodi4.o \ + mulosi4.o \ + muloti4.o \ + mulsc3.o \ + mulsf3.o \ + mulvdi3.o \ + mulvsi3.o \ + mulxc3.o \ + negdf2.o \ + negdi2.o \ + negsf2.o \ + negvdi2.o \ + negvsi2.o \ + paritydi2.o \ + paritysi2.o \ + popcountdi2.o \ + popcountsi2.o \ + powidf2.o \ + powisf2.o \ + powixf2.o \ + subdf3.o \ + subsf3.o \ + subvdi3.o \ + subvsi3.o \ + truncdfhf2.o \ + truncdfsf2.o \ + truncsfhf2.o \ + ucmpdi2.o \ + udivdi3.o \ + udivmoddi4.o \ + udivmodsi4.o \ + udivsi3.o \ + umoddi3.o \ + umodsi3.o -# All this is to figure out the path to the compiler-rt bin -ifeq ($$(findstring windows-msvc,$(1)),windows-msvc) -COMPRT_DIR_$(1) := windows/Release -COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1))) +ifeq ($$(findstring ios,$(1)),) +COMPRT_OBJS_$(1) += \ + absvti2.o \ + addtf3.o \ + addvti3.o \ + ashlti3.o \ + ashrti3.o \ + clzti2.o \ + cmpti2.o \ + ctzti2.o \ + divtf3.o \ + divti3.o \ + ffsti2.o \ + fixdfti.o \ + fixsfti.o \ + fixunsdfti.o \ + fixunssfti.o \ + fixunsxfti.o \ + fixxfti.o \ + floattidf.o \ + floattisf.o \ + floattixf.o \ + floatuntidf.o \ + floatuntisf.o \ + floatuntixf.o \ + lshrti3.o \ + modti3.o \ + multf3.o \ + multi3.o \ + mulvti3.o \ + negti2.o \ + negvti2.o \ + parityti2.o \ + popcountti2.o \ + powitf2.o \ + subtf3.o \ + subvti3.o \ + trampoline_setup.o \ + ucmpti2.o \ + udivmodti4.o \ + udivti3.o \ + umodti3.o endif -ifeq ($$(findstring windows-gnu,$(1)),windows-gnu) -COMPRT_DIR_$(1) := windows -COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1)) +ifeq ($$(findstring apple,$(1)),apple) +COMPRT_OBJS_$(1) += \ + atomic_flag_clear.o \ + atomic_flag_clear_explicit.o \ + atomic_flag_test_and_set.o \ + atomic_flag_test_and_set_explicit.o \ + atomic_signal_fence.o \ + atomic_thread_fence.o endif -ifeq ($$(findstring darwin,$(1)),darwin) -COMPRT_DIR_$(1) := builtins -COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx + +ifeq ($$(findstring windows,$(1)),) +COMPRT_OBJS_$(1) += emutls.o endif -ifeq ($$(findstring ios,$(1)),ios) -COMPRT_DIR_$(1) := builtins -COMPRT_ARCH_$(1) := $$(patsubst armv7s,armv7em,$$(COMPRT_ARCH_$(1))) -COMPRT_LIB_NAME_$(1) := clang_rt.hard_pic_$$(COMPRT_ARCH_$(1))_macho_embedded -ifeq ($$(COMPRT_ARCH_$(1)),aarch64) -COMPRT_LIB_NAME_$(1) := clang_rt.builtins_arm64_ios +ifeq ($$(findstring msvc,$(1)),) +COMPRT_OBJS_$(1) += gcc_personality_v0.o +COMPRT_OBJS_$(1) += emutls.o + +ifeq ($$(findstring x86_64,$(1)),x86_64) +COMPRT_OBJS_$(1) += \ + x86_64/chkstk.o \ + x86_64/chkstk2.o \ + x86_64/floatdidf.o \ + x86_64/floatdisf.o \ + x86_64/floatdixf.o \ + x86_64/floatundidf.o \ + x86_64/floatundisf.o \ + x86_64/floatundixf.o endif -COMPRT_DEFINES_$(1) := -DCOMPILER_RT_ENABLE_IOS=ON + +ifeq ($$(findstring i686,$$(patsubts i%86,i686,$(1))),i686) +COMPRT_OBJS_$(1) += \ + i386/ashldi3.o \ + i386/ashrdi3.o \ + i386/chkstk.o \ + i386/chkstk2.o \ + i386/divdi3.o \ + i386/floatdidf.o \ + i386/floatdisf.o \ + i386/floatdixf.o \ + i386/floatundidf.o \ + i386/floatundisf.o \ + i386/floatundixf.o \ + i386/lshrdi3.o \ + i386/moddi3.o \ + i386/muldi3.o \ + i386/udivdi3.o \ + i386/umoddi3.o endif -ifndef COMPRT_DIR_$(1) -# NB: FreeBSD and NetBSD output to "linux"... -COMPRT_DIR_$(1) := linux -COMPRT_ARCH_$(1) := $$(patsubst i586,i386,$$(COMPRT_ARCH_$(1))) +else -ifeq ($$(findstring android,$(1)),android) -ifeq ($$(findstring arm,$$(COMPRT_ARCH_$(1))),arm) -COMPRT_ARCH_$(1) := armhf -endif +ifeq ($$(findstring x86_64,$(1)),x86_64) +COMPRT_OBJS_$(1) += \ + x86_64/floatdidf.o \ + x86_64/floatdisf.o \ + x86_64/floatdixf.o endif -ifeq ($$(findstring eabihf,$(1)),eabihf) -ifeq ($$(findstring armv7,$(1)),) -COMPRT_LIB_NAME_$(1) := clang_rt.builtins-armhf -endif endif -ifndef COMPRT_LIB_NAME_$(1) -COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1)) +# Generic ARM sources, nothing compiles on iOS though +ifeq ($$(findstring arm,$(1)),arm) +ifeq ($$(findstring ios,$(1)),) +COMPRT_OBJS_$(1) += \ + arm/aeabi_cdcmp.o \ + arm/aeabi_cdcmpeq_check_nan.o \ + arm/aeabi_cfcmp.o \ + arm/aeabi_cfcmpeq_check_nan.o \ + arm/aeabi_dcmp.o \ + arm/aeabi_div0.o \ + arm/aeabi_drsub.o \ + arm/aeabi_fcmp.o \ + arm/aeabi_frsub.o \ + arm/aeabi_idivmod.o \ + arm/aeabi_ldivmod.o \ + arm/aeabi_memcmp.o \ + arm/aeabi_memcpy.o \ + arm/aeabi_memmove.o \ + arm/aeabi_memset.o \ + arm/aeabi_uidivmod.o \ + arm/aeabi_uldivmod.o \ + arm/bswapdi2.o \ + arm/bswapsi2.o \ + arm/clzdi2.o \ + arm/clzsi2.o \ + arm/comparesf2.o \ + arm/divmodsi4.o \ + arm/divsi3.o \ + arm/modsi3.o \ + arm/switch16.o \ + arm/switch32.o \ + arm/switch8.o \ + arm/switchu8.o \ + arm/sync_synchronize.o \ + arm/udivmodsi4.o \ + arm/udivsi3.o \ + arm/umodsi3.o endif endif - -ifeq ($$(findstring windows-gnu,$(1)),windows-gnu) -COMPRT_LIB_FILE_$(1) := lib$$(COMPRT_LIB_NAME_$(1)).a +# Thumb sources +ifeq ($$(findstring armv7,$(1)),armv7) +COMPRT_OBJS_$(1) += \ + arm/sync_fetch_and_add_4.o \ + arm/sync_fetch_and_add_8.o \ + arm/sync_fetch_and_and_4.o \ + arm/sync_fetch_and_and_8.o \ + arm/sync_fetch_and_max_4.o \ + arm/sync_fetch_and_max_8.o \ + arm/sync_fetch_and_min_4.o \ + arm/sync_fetch_and_min_8.o \ + arm/sync_fetch_and_nand_4.o \ + arm/sync_fetch_and_nand_8.o \ + arm/sync_fetch_and_or_4.o \ + arm/sync_fetch_and_or_8.o \ + arm/sync_fetch_and_sub_4.o \ + arm/sync_fetch_and_sub_8.o \ + arm/sync_fetch_and_umax_4.o \ + arm/sync_fetch_and_umax_8.o \ + arm/sync_fetch_and_umin_4.o \ + arm/sync_fetch_and_umin_8.o \ + arm/sync_fetch_and_xor_4.o \ + arm/sync_fetch_and_xor_8.o endif -ifeq ($$(findstring android,$(1)),android) -ifeq ($$(findstring arm,$(1)),arm) -COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))-android) -endif +# VFP sources +ifeq ($$(findstring eabihf,$(1)),eabihf) +COMPRT_OBJS_$(1) += \ + arm/adddf3vfp.o \ + arm/addsf3vfp.o \ + arm/divdf3vfp.o \ + arm/divsf3vfp.o \ + arm/eqdf2vfp.o \ + arm/eqsf2vfp.o \ + arm/extendsfdf2vfp.o \ + arm/fixdfsivfp.o \ + arm/fixsfsivfp.o \ + arm/fixunsdfsivfp.o \ + arm/fixunssfsivfp.o \ + arm/floatsidfvfp.o \ + arm/floatsisfvfp.o \ + arm/floatunssidfvfp.o \ + arm/floatunssisfvfp.o \ + arm/gedf2vfp.o \ + arm/gesf2vfp.o \ + arm/gtdf2vfp.o \ + arm/gtsf2vfp.o \ + arm/ledf2vfp.o \ + arm/lesf2vfp.o \ + arm/ltdf2vfp.o \ + arm/ltsf2vfp.o \ + arm/muldf3vfp.o \ + arm/mulsf3vfp.o \ + arm/negdf2vfp.o \ + arm/negsf2vfp.o \ + arm/nedf2vfp.o \ + arm/nesf2vfp.o \ + arm/restore_vfp_d8_d15_regs.o \ + arm/save_vfp_d8_d15_regs.o \ + arm/subdf3vfp.o \ + arm/subsf3vfp.o \ + arm/truncdfsf2vfp.o \ + arm/unorddf2vfp.o \ + arm/unordsf2vfp.o endif -ifndef COMPRT_LIB_FILE_$(1) -COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))) +ifeq ($$(findstring aarch64,$(1)),aarch64) +COMPRT_OBJS_$(1) += \ + comparetf2.o \ + extenddftf2.o \ + extendsftf2.o \ + fixtfdi.o \ + fixtfsi.o \ + fixtfti.o \ + fixunstfdi.o \ + fixunstfsi.o \ + fixunstfti.o \ + floatditf.o \ + floatsitf.o \ + floatunditf.o \ + floatunsitf.o \ + multc3.o \ + trunctfdf2.o \ + trunctfsf2.o endif -COMPRT_OUTPUT_$(1) := $$(COMPRT_BUILD_DIR_$(1))/lib/$$(COMPRT_DIR_$(1))/$$(COMPRT_LIB_FILE_$(1)) - -ifeq ($$(findstring windows-msvc,$(1)),windows-msvc) -COMPRT_BUILD_ARGS_$(1) := //v:m //nologo -COMPRT_BUILD_TARGET_$(1) := lib/builtins/builtins -COMPRT_BUILD_CC_$(1) := +ifeq ($$(findstring msvc,$(1)),msvc) +$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -Zl -D__func__=__FUNCTION__ else -COMPRT_BUILD_ARGS_$(1) := -ifndef COMPRT_BUILD_TARGET_$(1) -COMPRT_BUILD_TARGET_$(1) := $$(COMPRT_LIB_NAME_$(1)) +$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -fno-builtin -fvisibility=hidden \ + -fomit-frame-pointer -ffreestanding endif -COMPRT_BUILD_CC_$(1) := -DCMAKE_C_COMPILER=$$(call FIND_COMPILER,$$(CC_$(1))) \ - -DCMAKE_CXX_COMPILER=$$(call FIND_COMPILER,$$(CXX_$(1))) -ifeq ($$(findstring ios,$(1)),) -COMPRT_BUILD_CC_$(1) := $$(COMPRT_BUILD_CC_$(1)) \ - -DCMAKE_C_FLAGS="$$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error" -endif +COMPRT_OBJS_$(1) := $$(COMPRT_OBJS_$(1):%=$$(COMPRT_BUILD_DIR_$(1))/%) + +$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.c + @mkdir -p $$(@D) + @$$(call E, compile: $$@) + $$(Q)$$(call CFG_COMPILE_C_$(1),$$@,$$<) + +$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.S \ + $$(LLVM_CONFIG_$$(CFG_BUILD)) + @mkdir -p $$(@D) + @$$(call E, compile: $$@) + $$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<) +ifeq ($$(findstring msvc,$(1)),msvc) +$$(COMPRT_BUILD_DIR_$(1))/%.o: \ + export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1))) endif ifeq ($$(findstring emscripten,$(1)),emscripten) - # FIXME: emscripten doesn't use compiler-rt and can't build it without # further hacks -$$(COMPRT_LIB_$(1)): - touch $$@ - -else - -$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD)) - @$$(call E, cmake: compiler-rt) - $$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1)) - $$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1)) - $$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \ - $$(CFG_CMAKE) "$(S)src/compiler-rt" \ - -DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \ - -DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \ - -DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \ - -DCOMPILER_RT_BUILD_SANITIZERS=OFF \ - -DCOMPILER_RT_BUILD_EMUTLS=OFF \ - $$(COMPRT_DEFINES_$(1)) \ - $$(COMPRT_BUILD_CC_$(1)) \ - -G"$$(CFG_CMAKE_GENERATOR)" -ifneq ($$(CFG_NINJA),) - $$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \ - --target $$(COMPRT_BUILD_TARGET_$(1)) \ - --config $$(LLVM_BUILD_CONFIG_MODE) \ - -- $$(COMPRT_BUILD_ARGS_$(1)) -else - $$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \ - --target $$(COMPRT_BUILD_TARGET_$(1)) \ - --config $$(LLVM_BUILD_CONFIG_MODE) \ - -- $$(COMPRT_BUILD_ARGS_$(1)) $$(MFLAGS) +COMPRT_OBJS_$(1) := endif - $$(Q)cp "$$(COMPRT_OUTPUT_$(1))" $$@ -endif +$$(COMPRT_LIB_$(1)): $$(COMPRT_OBJS_$(1)) + @$$(call E, link: $$@) + $$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^ ################################################################################ # libbacktrace diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 39c7a37501121..1290f2a404b22 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 cde4a825be1fb..02746034cca69 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 83e9393fbaef7..05ecbc0cadaa9 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 82ae70d22ca06..1ce8c73123244 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 3ef7f8cab2d1b..b5230132bcb66 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -103,7 +103,10 @@ pub fn add_lib_path(path: Vec, 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 {