clean$(1)_T_$(2)_H_$(3): \
$$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate)) \
$$(foreach tool,$$(TOOLS) $$(DEBUGGER_BIN_SCRIPTS_ALL),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
- $$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/librun_pass_stage* # For unix
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/run_pass_stage* # For windows
TARGET_CRATES := libc std term \
getopts collections test rand \
- core alloc \
+ compiler_builtins core alloc \
rustc_unicode rustc_bitflags \
alloc_system alloc_jemalloc \
panic_abort panic_unwind unwind
TOOLS := compiletest rustdoc rustc rustbook error_index_generator
DEPS_core :=
+DEPS_compiler_builtins := core
DEPS_alloc := core libc alloc_system
DEPS_alloc_system := core libc
DEPS_alloc_jemalloc := core libc native:jemalloc
DEPS_panic_unwind := libc alloc unwind
DEPS_unwind := libc
+RUSTFLAGS_compiler_builtins := -lstatic=compiler-rt
+
# FIXME(stage0): change this to just `RUSTFLAGS_panic_abort := ...`
RUSTFLAGS1_panic_abort := -C panic=abort
RUSTFLAGS2_panic_abort := -C panic=abort
RUSTFLAGS3_panic_abort := -C panic=abort
-DEPS_std := core libc rand alloc collections rustc_unicode \
+DEPS_std := core libc rand alloc collections compiler_builtins rustc_unicode \
native:backtrace \
alloc_system panic_abort panic_unwind unwind
DEPS_arena := std
TOOL_SOURCE_rustbook := $(S)src/tools/rustbook/main.rs
TOOL_SOURCE_error_index_generator := $(S)src/tools/error_index_generator/main.rs
+ONLY_RLIB_compiler_builtins := 1
ONLY_RLIB_core := 1
ONLY_RLIB_libc := 1
ONLY_RLIB_alloc := 1
TSREQ$(1)_T_$(2)_H_$(3) = \
$$(HSREQ$(1)_H_$(3)) \
$$(foreach obj,$$(REQUIRED_OBJECTS_$(2)),\
- $$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj))
+ $$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj)) \
+ $$(TLIB0_T_$(2)_H_$(3))/libcompiler-rt.a
+# ^ This copies `libcompiler-rt.a` to the stage0 sysroot
+# ^ TODO(stage0) update this to not copy `libcompiler-rt.a` to stage0
# Prerequisites for a working stageN compiler and libraries, for a specific
# target
define ADD_INSTALLED_OBJECTS
INSTALLED_OBJECTS_$(1) += $$(CFG_INSTALLED_OBJECTS_$(1))
REQUIRED_OBJECTS_$(1) += $$(CFG_THIRD_PARTY_OBJECTS_$(1))
- INSTALLED_OBJECTS_$(1) += $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
- REQUIRED_OBJECTS_$(1) += $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
endef
$(foreach target,$(CFG_TARGET), \
################################################################################
NATIVE_LIBS := hoedown miniz rust_test_helpers
+# A macro to add a generic implementation of intrinsics iff a arch optimized implementation is not
+# already in the list.
+# $(1) is the target
+# $(2) is the intrinsic
+define ADD_INTRINSIC
+ ifeq ($$(findstring X,$$(foreach intrinsic,$$(COMPRT_OBJS_$(1)),$$(if $$(findstring $(2),$$(intrinsic)),X,))),)
+ COMPRT_OBJS_$(1) += $(2)
+ endif
+endef
+
# $(1) is the target triple
define NATIVE_LIBRARIES
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
-# 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
-
-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 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
+# We must avoid compiling both a generic implementation (e.g. `floatdidf.c) and an arch optimized
+# implementation (e.g. `x86_64/floatdidf.S) of the same symbol (e.g. `floatdidf) because that causes
+# linker errors. To avoid that, we first add all the arch optimized implementations and then add the
+# generic implementations if and only if its arch optimized version is not already in the list. This
+# last part is handled by the ADD_INTRINSIC macro.
-
-ifeq ($$(findstring windows,$(1)),)
-COMPRT_OBJS_$(1) += emutls.o
-endif
+COMPRT_OBJS_$(1) :=
ifeq ($$(findstring msvc,$(1)),)
-
-ifeq ($$(findstring freebsd,$(1)),)
-COMPRT_OBJS_$(1) += gcc_personality_v0.o
-endif
-
-COMPRT_OBJS_$(1) += emutls.o
-
ifeq ($$(findstring x86_64,$(1)),x86_64)
COMPRT_OBJS_$(1) += \
x86_64/chkstk.o \
arm/unordsf2vfp.o
endif
+$(foreach intrinsic,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,
+ $(call ADD_INTRINSIC,$(1),$(intrinsic)))
+
+ifeq ($$(findstring ios,$(1)),)
+$(foreach intrinsic,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,
+ $(call ADD_INTRINSIC,$(1),$(intrinsic)))
+endif
+
+ifeq ($$(findstring apple,$(1)),apple)
+$(foreach intrinsic,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,
+ $(call ADD_INTRINSIC,$(1),$(intrinsic)))
+endif
+
+ifeq ($$(findstring windows,$(1)),)
+$(call ADD_INTRINSIC,$(1),emutls.o)
+endif
+
+ifeq ($$(findstring msvc,$(1)),)
+
+ifeq ($$(findstring freebsd,$(1)),)
+$(call ADD_INTRINSIC,$(1),gcc_personality_v0.o)
+endif
+
+$(call ADD_INTRINSIC,$(1),emutls.o)
+endif
+
ifeq ($$(findstring aarch64,$(1)),aarch64)
-COMPRT_OBJS_$(1) += \
- comparetf2.o \
+$(foreach intrinsic,comparetf2.o \
extenddftf2.o \
extendsftf2.o \
fixtfdi.o \
floatunsitf.o \
multc3.o \
trunctfdf2.o \
- trunctfsf2.o
+ trunctfsf2.o,
+ $(call ADD_INTRINSIC,$(1),$(intrinsic)))
endif
ifeq ($$(findstring msvc,$(1)),msvc)
let out = build.out.join(host);
- rm_rf(build, &out.join("compiler-rt"));
rm_rf(build, &out.join("doc"));
for stage in 0..4 {
println!("Building stage{} std artifacts ({} -> {})", compiler.stage,
compiler.host, target);
- // Move compiler-rt into place as it'll be required by the compiler when
- // building the standard library to link the dylib of libstd
let libdir = build.sysroot_libdir(compiler, target);
let _ = fs::remove_dir_all(&libdir);
t!(fs::create_dir_all(&libdir));
- copy(&build.compiler_rt_built.borrow()[target],
- &libdir.join(staticlib("compiler-rt", target)));
+ // FIXME(stage0) remove this `if` after the next snapshot
+ // The stage0 compiler still passes the `-lcompiler-rt` flag to the linker but now `bootstrap`
+ // never builds a `libcopmiler-rt.a`! We'll fill the hole by simply copying stage0's
+ // `libcompiler-rt.a` to where the stage1's one is expected (though we could as well just use
+ // an empty `.a` archive). Note that the symbols of that stage0 `libcompiler-rt.a` won't make
+ // it to the final binary because now `libcore.rlib` also contains the symbols that
+ // `libcompiler-rt.a` provides. Since that rlib appears first in the linker arguments, its
+ // symbols are used instead of `libcompiler-rt.a`'s.
+ if compiler.stage == 0 {
+ let rtlib = &staticlib("compiler-rt", target);
+ let src = build.rustc.parent().unwrap().parent().unwrap().join("lib").join("rustlib")
+ .join(target).join("lib").join(rtlib);
+ copy(&src, &libdir.join(rtlib));
+ }
// Some platforms have startup objects that may be required to produce the
// libstd dynamic library, for example.
// If we're linking one compiler host's output into another, then we weren't
// called from the `std` method above. In that case we clean out what's
- // already there and then also link compiler-rt into place.
+ // already there.
if host != compiler.host {
let _ = fs::remove_dir_all(&libdir);
t!(fs::create_dir_all(&libdir));
- copy(&build.compiler_rt_built.borrow()[target],
- &libdir.join(staticlib("compiler-rt", target)));
}
add_to_sysroot(&out_dir, &libdir);
extern crate toml;
extern crate regex;
-use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
// Runtime state filled in later on
cc: HashMap<String, (gcc::Tool, Option<PathBuf>)>,
cxx: HashMap<String, gcc::Tool>,
- compiler_rt_built: RefCell<HashMap<String, PathBuf>>,
}
/// The various "modes" of invoking Cargo.
package_vers: String::new(),
cc: HashMap::new(),
cxx: HashMap::new(),
- compiler_rt_built: RefCell::new(HashMap::new()),
gdb_version: None,
lldb_version: None,
lldb_python_dir: None,
Llvm { _dummy } => {
native::llvm(self, target.target);
}
- CompilerRt { _dummy } => {
- native::compiler_rt(self, target.target);
- }
TestHelpers { _dummy } => {
native::test_helpers(self, target.target);
}
}
}
- /// Root output directory for compiler-rt compiled for `target`
- fn compiler_rt_out(&self, target: &str) -> PathBuf {
- self.out.join(target).join("compiler-rt")
- }
-
/// Root output directory for rust_test_helpers library compiled for
/// `target`
fn test_helpers_out(&self, target: &str) -> PathBuf {
use gcc;
use Build;
-use util::{staticlib, up_to_date};
+use util::up_to_date;
/// Compile LLVM for `target`.
pub fn llvm(build: &Build, target: &str) {
panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
}
-/// Compiles the `compiler-rt` library, or at least the builtins part of it.
-///
-/// 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 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 mut cfg = gcc::Config::new();
- cfg.cargo_metadata(false)
- .out_dir(&build_dir)
- .target(target)
- .host(&build.config.build)
- .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 {
- // 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 {
- if !target.contains("freebsd") {
- 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
- }
- cfg.compile("libcompiler-rt.a");
-}
-
/// Compiles the `rust_test_helpers.c` library which we used in various
/// `run-pass` test suites for ABI testing.
pub fn test_helpers(build: &Build, target: &str) {
// There aren't really any parameters to this, but empty structs
// with braces are unstable so we just pick something that works.
(llvm, Llvm { _dummy: () }),
- (compiler_rt, CompilerRt { _dummy: () }),
(test_helpers, TestHelpers { _dummy: () }),
(debugger_scripts, DebuggerScripts { stage: u32 }),
vec![self.libstd(compiler)]
}
Source::Libstd { compiler } => {
- vec![self.compiler_rt(()),
- self.rustc(compiler.stage).target(compiler.host)]
+ vec![self.rustc(compiler.stage).target(compiler.host)]
}
Source::LibrustcLink { compiler, host } => {
vec![self.librustc(compiler),
vec![self.libstd(compiler),
self.target(host).rustc(compiler.stage)]
}
- Source::CompilerRt { _dummy } => Vec::new(),
Source::Llvm { _dummy } => Vec::new(),
Source::TestHelpers { _dummy } => Vec::new(),
Source::DebuggerScripts { stage: _ } => Vec::new(),
--- /dev/null
+[package]
+authors = ["The Rust Project Developers"]
+build = "build.rs"
+name = "compiler_builtins"
+version = "0.0.0"
+
+[lib]
+name = "compiler_builtins"
+path = "lib.rs"
+
+[dependencies]
+core = { path = "../libcore" }
+
+[build-dependencies]
+gcc = "0.3.27"
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Compiles the `compiler-rt` library, or at least the builtins part of it.
+//!
+//! 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.
+
+extern crate gcc;
+
+use std::collections::BTreeMap;
+use std::env;
+use std::path::Path;
+
+struct Sources {
+ // SYMBOL -> PATH TO SOURCE
+ map: BTreeMap<&'static str, &'static str>,
+}
+
+impl Sources {
+ fn new() -> Sources {
+ Sources { map: BTreeMap::new() }
+ }
+
+ fn extend(&mut self, sources: &[&'static str]) {
+ // NOTE Some intrinsics have both a generic implementation (e.g. `floatdidf.c`) and an arch
+ // optimized implementation (`x86_64/floatdidf.c`). In those cases, we keep the arch
+ // optimized implementation and discard the generic implementation. If we don't and keep
+ // both implementations, the linker will yell at us about duplicate symbols!
+ for &src in sources {
+ let symbol = Path::new(src).file_stem().unwrap().to_str().unwrap();
+ if src.contains("/") {
+ // Arch-optimized implementation (preferred)
+ self.map.insert(symbol, src);
+ } else {
+ // Generic implementation
+ if !self.map.contains_key(symbol) {
+ self.map.insert(symbol, src);
+ }
+ }
+ }
+ }
+}
+
+fn main() {
+ let target = env::var("TARGET").unwrap();
+ let cfg = &mut gcc::Config::new();
+
+ 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 {
+ // 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 = Sources::new();
+ sources.extend(&["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(&["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(&["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.extend(&["emutls.c"]);
+ }
+
+ if target.contains("msvc") {
+ if target.contains("x86_64") {
+ sources.extend(&["x86_64/floatdidf.c", "x86_64/floatdisf.c", "x86_64/floatdixf.c"]);
+ }
+ } else {
+ if !target.contains("freebsd") {
+ sources.extend(&["gcc_personality_v0.c"]);
+ }
+
+ if target.contains("x86_64") {
+ sources.extend(&["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(&["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(&["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(&["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(&["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(&["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"]);
+ }
+
+ for src in sources.map.values() {
+ cfg.file(Path::new("../compiler-rt/lib/builtins").join(src));
+ }
+
+ cfg.compile("libcompiler-rt.a");
+}
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![cfg_attr(not(stage0), feature(compiler_builtins))]
+#![no_std]
+#![cfg_attr(not(stage0), compiler_builtins)]
+
+#![crate_name = "compiler_builtins"]
+#![crate_type = "rlib"]
fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool;
fn is_allocator(&self, cnum: ast::CrateNum) -> bool;
fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool;
+ fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool;
fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy;
fn extern_crate(&self, cnum: ast::CrateNum) -> Option<ExternCrate>;
fn crate_attrs(&self, cnum: ast::CrateNum) -> Vec<ast::Attribute>;
fn is_explicitly_linked(&self, cnum: ast::CrateNum) -> bool { bug!("is_explicitly_linked") }
fn is_allocator(&self, cnum: ast::CrateNum) -> bool { bug!("is_allocator") }
fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool { bug!("is_panic_runtime") }
+ fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool { bug!("is_compiler_builtins") }
fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy {
bug!("panic_strategy")
}
dynamic_linking: false,
executables: true,
exe_suffix: ".js".to_string(),
- no_compiler_rt: true,
linker_is_gnu: true,
allow_asm: false,
obj_is_bitcode: true,
dynamic_linking: false,
executables: true,
exe_suffix: ".pexe".to_string(),
- no_compiler_rt: false,
linker_is_gnu: true,
allow_asm: false,
max_atomic_width: 32,
pub allows_weak_linkage: bool,
/// Whether the linker support rpaths or not. Defaults to false.
pub has_rpath: bool,
- /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM
- /// will emit references to the functions that compiler-rt provides.
- pub no_compiler_rt: bool,
/// Whether to disable linking to the default libraries, typically corresponds
/// to `-nodefaultlibs`. Defaults to true.
pub no_default_libraries: bool,
linker_is_gnu: false,
allows_weak_linkage: true,
has_rpath: false,
- no_compiler_rt: false,
no_default_libraries: true,
position_independent_executables: false,
pre_link_objects_exe: Vec::new(),
key!(linker_is_gnu, bool);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
- key!(no_compiler_rt, bool);
key!(no_default_libraries, bool);
key!(position_independent_executables, bool);
key!(archive_format);
target_option_val!(linker_is_gnu);
target_option_val!(allows_weak_linkage);
target_option_val!(has_rpath);
- target_option_val!(no_compiler_rt);
target_option_val!(no_default_libraries);
target_option_val!(position_independent_executables);
target_option_val!(archive_format);
self.get_crate_data(cnum).is_panic_runtime()
}
+ fn is_compiler_builtins(&self, cnum: ast::CrateNum) -> bool {
+ self.get_crate_data(cnum).is_compiler_builtins()
+ }
+
fn panic_strategy(&self, cnum: ast::CrateNum) -> PanicStrategy {
self.get_crate_data(cnum).panic_strategy()
}
attr::contains_name(&attrs, "needs_panic_runtime")
}
+ pub fn is_compiler_builtins(&self) -> bool {
+ let attrs = decoder::get_crate_attributes(self.data());
+ attr::contains_name(&attrs, "compiler_builtins")
+ }
+
pub fn panic_strategy(&self) -> PanicStrategy {
decoder::get_panic_strategy(self.data())
}
fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
tempdir: &Path) {
let mut ab = link_rlib(sess, None, objects, out_filename, tempdir);
- if !sess.target.target.options.no_compiler_rt {
- ab.add_native_library("compiler-rt");
- }
-
let mut all_native_libs = vec![];
each_linked_rlib(sess, &mut |cnum, path| {
let mut linker = trans.linker_info.to_linker(&mut cmd, &sess);
link_args(&mut *linker, sess, crate_type, tmpdir,
objects, out_filename, outputs);
- if !sess.target.target.options.no_compiler_rt {
- linker.link_staticlib("compiler-rt");
- }
}
cmd.args(&sess.target.target.options.late_link_args);
for obj in &sess.target.target.options.post_link_objects {
// symbols from the dylib.
let src = sess.cstore.used_crate_source(cnum);
match data[cnum as usize - 1] {
+ // We must always link the `compiler_builtins` crate statically. Even if it was already
+ // "included" in a dylib (e.g. `libstd` when `-C prefer-dynamic` is used)
+ _ if sess.cstore.is_compiler_builtins(cnum) => {
+ add_static_crate(cmd, sess, tmpdir, crate_type,
+ &src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum))
+ }
Linkage::NotLinked |
Linkage::IncludedFromDylib => {}
Linkage::Static => {
core = { path = "../libcore" }
libc = { path = "../rustc/libc_shim" }
rand = { path = "../librand" }
+compiler_builtins = { path = "../libcompiler_builtins" }
rustc_unicode = { path = "../librustc_unicode" }
unwind = { path = "../libunwind" }
#[cfg(stage0)]
extern crate alloc_system;
+// compiler-rt intrinsics
+extern crate compiler_builtins;
+
// Make std testable by not duplicating lang items and other globals. See #2912
#[cfg(test)] extern crate std as realstd;
// elide `'static` lifetimes in `static`s and `const`s
(active, static_in_const, "1.13.0", Some(35897)),
+
+ // Used to identify the `compiler_builtins` crate
+ // rustc internal
+ (active, compiler_builtins, "1.13.0", None),
);
declare_features! (
libcore functions that are inlined \
across crates and will never be stable",
cfg_fn!(rustc_attrs))),
+ ("compiler_builtins", Whitelisted, Gated("compiler_builtins",
+ "the `#[compiler_builtins]` attribute is used to \
+ identify the `compiler_builtins` crate which \
+ contains compiler-rt intrinsics and will never be \
+ stable",
+ cfg_fn!(compiler_builtins))),
("allow_internal_unstable", Normal, Gated("allow_internal_unstable",
EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
"rustc_unicode 0.0.0",
]
+[[package]]
+name = "compiler_builtins"
+version = "0.0.0"
+dependencies = [
+ "core 0.0.0",
+ "gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "core"
version = "0.0.0"
"alloc_system 0.0.0",
"build_helper 0.1.0",
"collections 0.0.0",
+ "compiler_builtins 0.0.0",
"core 0.0.0",
"gcc 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.0.0",
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![compiler_builtins] //~ ERROR the `#[compiler_builtins]` attribute is
+
+fn main() {}
+