提交 b1363a73 编写于 作者: B bors 提交者: GitHub

Auto merge of #35021 - japaric:rustc-builtins, r=alexcrichton

crate-ify compiler-rt into compiler-builtins

libcompiler-rt.a is dead, long live libcompiler-builtins.rlib

This commit moves the logic that used to build libcompiler-rt.a into a
compiler-builtins crate on top of the core crate and below the std crate.
This new crate still compiles the compiler-rt instrinsics using gcc-rs
but produces an .rlib instead of a static library.

Also, with this commit rustc no longer passes -lcompiler-rt to the
linker. This effectively makes the "no-compiler-rt" field of target
specifications a no-op. Users of `no_std` will have to explicitly add
the compiler-builtins crate to their crate dependency graph *if* they
need the compiler-rt intrinsics - this is a [breaking-change]. Users
of the `std` have to do nothing extra as the std crate depends
on compiler-builtins.

Finally, this a step towards lazy compilation of std with Cargo as the
compiler-rt intrinsics can now be built by Cargo instead of having to
be supplied by the user by some other method.

closes #34400

---

r? @alexcrichton
......@@ -102,7 +102,6 @@ define CLEAN_TARGET_STAGE_N
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
......
......@@ -51,7 +51,7 @@
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
......@@ -65,6 +65,7 @@ HOST_CRATES := syntax syntax_ext proc_macro syntax_pos $(RUSTC_CRATES) rustdoc f
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
......@@ -77,12 +78,14 @@ DEPS_panic_abort := libc alloc
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
......@@ -153,6 +156,7 @@ TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
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
......
......@@ -455,7 +455,10 @@ endif
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))/$$(call CFG_STATIC_LIB_NAME_$(2),compiler-rt)
# ^ 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
......
......@@ -102,8 +102,6 @@ include $(wildcard $(CFG_SRC_DIR)mk/cfg/*.mk)
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), \
......
......@@ -37,6 +37,16 @@
################################################################################
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
......@@ -230,167 +240,15 @@ 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
# 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 \
......@@ -540,9 +398,166 @@ COMPRT_OBJS_$(1) += \
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
endif
ifeq ($$(findstring aarch64,$(1)),aarch64)
COMPRT_OBJS_$(1) += \
comparetf2.o \
$(foreach intrinsic,comparetf2.o \
extenddftf2.o \
extendsftf2.o \
fixtfdi.o \
......@@ -557,7 +572,8 @@ COMPRT_OBJS_$(1) += \
floatunsitf.o \
multc3.o \
trunctfdf2.o \
trunctfsf2.o
trunctfsf2.o,
$(call ADD_INTRINSIC,$(1),$(intrinsic)))
endif
ifeq ($$(findstring msvc,$(1)),msvc)
......
......@@ -28,7 +28,6 @@ pub fn clean(build: &Build) {
let out = build.out.join(host);
rm_rf(build, &out.join("compiler-rt"));
rm_rf(build, &out.join("doc"));
for stage in 0..4 {
......
......@@ -35,13 +35,23 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
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.
......@@ -83,12 +93,10 @@ pub fn std_link(build: &Build,
// 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);
......
......@@ -28,7 +28,6 @@
extern crate toml;
extern crate regex;
use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
use std::fs::{self, File};
......@@ -131,7 +130,6 @@ pub struct Build {
// 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.
......@@ -198,7 +196,6 @@ pub fn new(flags: Flags, config: Config) -> Build {
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,
......@@ -252,9 +249,6 @@ pub fn build(&mut self) {
Llvm { _dummy } => {
native::llvm(self, target.target);
}
CompilerRt { _dummy } => {
native::compiler_rt(self, target.target);
}
TestHelpers { _dummy } => {
native::test_helpers(self, target.target);
}
......@@ -839,11 +833,6 @@ fn llvm_filecheck(&self, target: &str) -> PathBuf {
}
}
/// 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 {
......
......@@ -27,7 +27,7 @@
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) {
......@@ -131,401 +131,6 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
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) {
......
......@@ -82,7 +82,6 @@ pub struct Step<'a> {
// 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 }),
......@@ -334,8 +333,7 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
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),
......@@ -348,7 +346,6 @@ pub fn deps(&self, build: &'a Build) -> Vec<Step<'a>> {
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(),
......
......@@ -23,7 +23,7 @@
/// Returns the `name` as the filename of a static library for `target`.
pub fn staticlib(name: &str, target: &str) -> String {
if target.contains("windows-msvc") {
if target.contains("windows") {
format!("{}.lib", name)
} else {
format!("lib{}.a", name)
......
[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"
// 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");
}
// 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)]
#![unstable(feature = "compiler_builtins_lib",
reason = "internal implementation detail of rustc right now",
issue = "0")]
#![crate_name = "compiler_builtins"]
#![crate_type = "rlib"]
#![feature(staged_api)]
......@@ -210,6 +210,7 @@ fn dylib_dependency_formats(&self, cnum: ast::CrateNum)
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>;
......@@ -405,6 +406,7 @@ fn is_staged_api(&self, cnum: ast::CrateNum) -> bool { bug!("is_staged_api") }
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")
}
......
......@@ -18,7 +18,6 @@ pub fn target() -> Result<Target, String> {
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,
......
......@@ -22,7 +22,6 @@ pub fn target() -> TargetResult {
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,
......
......@@ -306,9 +306,6 @@ pub struct TargetOptions {
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,
......@@ -381,7 +378,6 @@ fn default() -> TargetOptions {
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(),
......@@ -524,7 +520,6 @@ pub fn from_json(obj: Json) -> TargetResult {
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);
......@@ -667,7 +662,6 @@ fn to_json(&self) -> Json {
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);
......
......@@ -346,6 +346,10 @@ fn is_panic_runtime(&self, cnum: ast::CrateNum) -> bool
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()
}
......
......@@ -340,6 +340,11 @@ pub fn needs_panic_runtime(&self) -> bool {
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())
}
......
......@@ -573,10 +573,6 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
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| {
......@@ -640,9 +636,6 @@ fn link_natively(sess: &Session,
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 {
......@@ -933,17 +926,24 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
// crates.
let deps = sess.cstore.used_crates(LinkagePreference::RequireDynamic);
let mut compiler_builtins = None;
for &(cnum, _) in &deps {
// We may not pass all crates through to the linker. Some crates may
// appear statically in an existing dylib, meaning we'll pick up all the
// symbols from the dylib.
let src = sess.cstore.used_crate_source(cnum);
match data[cnum as usize - 1] {
// compiler-builtins are always placed last to ensure that they're
// linked correctly.
_ if sess.cstore.is_compiler_builtins(cnum) => {
assert!(compiler_builtins.is_none());
compiler_builtins = Some(cnum);
}
Linkage::NotLinked |
Linkage::IncludedFromDylib => {}
Linkage::Static => {
add_static_crate(cmd, sess, tmpdir, crate_type,
&src.rlib.unwrap().0, sess.cstore.is_no_builtins(cnum))
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
}
Linkage::Dynamic => {
add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
......@@ -951,6 +951,13 @@ fn add_upstream_rust_crates(cmd: &mut Linker,
}
}
// 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 let Some(cnum) = compiler_builtins {
add_static_crate(cmd, sess, tmpdir, crate_type, cnum);
}
// Converts a library file-stem into a cc -l argument
fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
if stem.starts_with("lib") && !config.target.options.is_like_windows {
......@@ -996,8 +1003,9 @@ fn add_static_crate(cmd: &mut Linker,
sess: &Session,
tmpdir: &Path,
crate_type: config::CrateType,
cratepath: &Path,
is_a_no_builtins_crate: bool) {
cnum: ast::CrateNum) {
let src = sess.cstore.used_crate_source(cnum);
let cratepath = &src.rlib.unwrap().0;
if !sess.lto() && crate_type != config::CrateTypeDylib {
cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
return
......@@ -1021,7 +1029,13 @@ fn add_static_crate(cmd: &mut Linker,
}
let canonical = f.replace("-", "_");
let canonical_name = name.replace("-", "_");
if sess.lto() && !is_a_no_builtins_crate &&
// If we're performing LTO and this is a rust-generated object
// file, then we don't need the object file as it's part of the
// LTO module. Note that `#![no_builtins]` is excluded from LTO,
// though, so we let that object file slide.
if sess.lto() &&
!sess.cstore.is_no_builtins(cnum) &&
canonical.starts_with(&canonical_name) &&
canonical.ends_with(".o") {
let num = &f[name.len()..f.len() - 2];
......@@ -1033,13 +1047,23 @@ fn add_static_crate(cmd: &mut Linker,
any_objects = true;
}
if any_objects {
archive.build();
if crate_type == config::CrateTypeDylib {
cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
} else {
cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
}
if !any_objects {
return
}
archive.build();
// If we're creating a dylib, then we need to include the
// whole of each object in our archive into that artifact. This is
// because a `dylib` can be reused as an intermediate artifact.
//
// Note, though, that we don't want to include the whole of a
// compiler-builtins crate (e.g. compiler-rt) because it'll get
// repeatedly linked anyway.
if crate_type == config::CrateTypeDylib &&
!sess.cstore.is_compiler_builtins(cnum) {
cmd.link_whole_rlib(&fix_windows_verbatim_for_gcc(&dst));
} else {
cmd.link_rlib(&fix_windows_verbatim_for_gcc(&dst));
}
});
}
......
......@@ -19,6 +19,7 @@ collections = { path = "../libcollections" }
core = { path = "../libcore" }
libc = { path = "../rustc/libc_shim" }
rand = { path = "../librand" }
compiler_builtins = { path = "../libcompiler_builtins" }
rustc_unicode = { path = "../librustc_unicode" }
unwind = { path = "../libunwind" }
......
......@@ -224,6 +224,7 @@
#![feature(char_internals)]
#![feature(collections)]
#![feature(collections_bound)]
#![feature(compiler_builtins_lib)]
#![feature(const_fn)]
#![feature(core_float)]
#![feature(core_intrinsics)]
......@@ -322,6 +323,9 @@
#[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;
......
......@@ -298,6 +298,10 @@ pub fn new() -> Features {
// 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! (
......@@ -537,6 +541,12 @@ fn f(features: &Features) -> bool {
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,
......
......@@ -43,6 +43,14 @@ dependencies = [
"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"
......@@ -100,6 +108,7 @@ dependencies = [
"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",
......
// 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() {}
......@@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, libc)]
#![feature(lang_items, libc, compiler_builtins_lib)]
#![crate_type = "dylib"]
#![no_std]
extern crate libc;
extern crate compiler_builtins;
#[no_mangle]
pub extern fn bar() {}
......
......@@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, libc)]
#![feature(lang_items, libc, compiler_builtins_lib)]
#![no_std]
#![crate_type = "dylib"]
extern crate libc;
extern crate compiler_builtins;
#[no_mangle]
pub extern fn foo() {}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册