From b7651325eb3863c9869b7c684b1a4d9401544091 Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Mon, 3 Feb 2014 22:54:09 -0800
Subject: [PATCH] Build compiler-rt and link it to all crates, similarly to
 morestack.

---
 .gitmodules               |  2 +-
 Makefile.in               |  3 ++-
 mk/clean.mk               |  3 +++
 mk/crates.mk              |  2 +-
 mk/install.mk             |  2 ++
 mk/rt.mk                  | 31 +++++++++++++++++++++++++++++++
 mk/target.mk              |  6 ++++++
 mk/tests.mk               |  1 +
 src/librustc/back/link.rs | 17 ++++++++++++++---
 9 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/.gitmodules b/.gitmodules
index 85b637380a8..597086229b8 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -11,4 +11,4 @@
 	url = https://github.com/rust-lang/gyp.git
 [submodule "src/compiler-rt"]
 	path = src/compiler-rt
-	url = https://github.com/vadimcn/compiler-rt.git
+	url = https://github.com/rust-lang/compiler-rt.git
diff --git a/Makefile.in b/Makefile.in
index d0a7c5402e8..1130ab53d5d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -355,7 +355,8 @@ endif
 # Prerequisites for using the stageN compiler to build target artifacts
 TSREQ$(1)_T_$(2)_H_$(3) = \
 	$$(HSREQ$(1)_H_$(3)) \
-	$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
+	$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a \
+	$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a
 
 # Prerequisites for a working stageN compiler and libraries, for a specific
 # target
diff --git a/mk/clean.mk b/mk/clean.mk
index edd0554195b..002db59ad38 100644
--- a/mk/clean.mk
+++ b/mk/clean.mk
@@ -54,6 +54,7 @@ clean-generic-$(2)-$(1):
 	         $(1)/rt \
 		 $(1)/test \
 		 $(1)/stage* \
+		 -type f \(           \
          -name '*.[odasS]' -o \
          -name '*.so' -o      \
          -name '*.dylib' -o   \
@@ -62,6 +63,7 @@ clean-generic-$(2)-$(1):
          -name '*.dll' -o     \
          -name '*.def' -o     \
          -name '*.bc'         \
+         \)                   \
          | xargs rm -f
 	$(Q)find $(1)\
          -name '*.dSYM'       \
@@ -96,6 +98,7 @@ clean$(1)_T_$(2)_H_$(3):						       \
 	    $$(foreach crate,$$(CRATES),clean$(1)_T_$(2)_H_$(3)-lib-$$(crate))  \
 	    $$(foreach tool,$$(TOOLS),clean$(1)_T_$(2)_H_$(3)-tool-$$(tool))
 	$$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a
+	$$(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
 
diff --git a/mk/crates.mk b/mk/crates.mk
index d137e5e7775..d7365a827b7 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -55,7 +55,7 @@ HOST_CRATES := syntax rustc rustdoc fourcc
 CRATES := $(TARGET_CRATES) $(HOST_CRATES)
 TOOLS := compiletest rustdoc rustc
 
-DEPS_std := native:rustrt
+DEPS_std := native:rustrt native:compiler-rt
 DEPS_extra := std term sync serialize getopts collections
 DEPS_green := std
 DEPS_rustuv := std native:uv native:uv_support
diff --git a/mk/install.mk b/mk/install.mk
index 73c8f2cf8c3..156a545e1ad 100644
--- a/mk/install.mk
+++ b/mk/install.mk
@@ -96,6 +96,7 @@ install-target-$(1)-host-$(2):						\
 		$$(call INSTALL_LIB,$$(call CFG_LIB_GLOB_$(1),$$(crate)));\
 		$$(call INSTALL_LIB,$$(call CFG_RLIB_GLOB,$$(crate)));)
 	$$(Q)$$(call INSTALL_LIB,libmorestack.a)
+	$$(Q)$$(call INSTALL_LIB,libcompiler-rt.a)
 
 endef
 
@@ -110,6 +111,7 @@ install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
 	$$(Q)$$(foreach crate,$$(TARGET_CRATES),\
 	    $$(call INSTALL_LIB,$$(call CFG_RLIB_GLOB,$$(crate)));)
 	$$(Q)$$(call INSTALL_LIB,libmorestack.a)
+	$$(Q)$$(call INSTALL_LIB,libcompiler-rt.a)
 endef
 
 $(foreach target,$(CFG_TARGET), \
diff --git a/mk/rt.mk b/mk/rt.mk
index f2226b1ae3e..ebb1f83398e 100644
--- a/mk/rt.mk
+++ b/mk/rt.mk
@@ -217,6 +217,37 @@ $$(LIBUV_DIR_$(1))/Release/libuv.a: $$(LIBUV_DEPS) $$(LIBUV_MAKEFILE_$(1)) \
 
 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
+
+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_LIB_$(1)): $$(COMPRT_DEPS)
+	@$$(call E, make: compiler-rt)
+	$$(Q)$$(MAKE) -C "$(S)src/compiler-rt" \
+		ProjSrcRoot="$(S)src/compiler-rt" \
+		ProjObjRoot="$$(abspath $$(COMPRT_BUILD_DIR_$(1)))" \
+		CC="$$(CC_$(1))" \
+		AR="$$(AR_$(1))" \
+		RANLIB="$$(AR_$(1)) s" \
+		CFLAGS="$$(CFG_GCCISH_CFLAGS_$(1))" \
+		TargetTriple=$(1) \
+		triple-runtime
+	$$(Q)cp $$(COMPRT_BUILD_DIR_$(1))/triple/runtime/libcompiler_rt.a $$(COMPRT_LIB_$(1))
+
 endef
 
 # Instantiate template for all stages/targets
diff --git a/mk/target.mk b/mk/target.mk
index 461e09da625..03569cb8b67 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -138,6 +138,12 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/:
 $$(TLIB$(1)_T_$(2)_H_$(3))/:
 	mkdir -p $$@
 
+$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a: \
+	    $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),compiler-rt) \
+	    | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
+	@$$(call E, cp: $$@)
+	$$(Q)cp $$< $$@
+
 $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \
 	    $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),morestack) \
 	    | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP)
diff --git a/mk/tests.mk b/mk/tests.mk
index 5f7566ef6d5..c2b298dbb9c 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -262,6 +262,7 @@ tidy:
 		| grep '^$(S)src/gyp' -v \
 		| grep '^$(S)src/etc' -v \
 		| grep '^$(S)src/doc' -v \
+		| grep '^$(S)src/compiler-rt' -v \
 		| xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py
 
 endif
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index d6abc7b6954..fa06f8d94aa 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -1003,6 +1003,7 @@ fn link_rlib(sess: Session,
 fn link_staticlib(sess: Session, obj_filename: &Path, out_filename: &Path) {
     let mut a = link_rlib(sess, None, obj_filename, out_filename);
     a.add_native_library("morestack").unwrap();
+    a.add_native_library("compiler-rt").unwrap();
 
     let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
     for &(cnum, ref path) in crates.iter() {
@@ -1130,6 +1131,19 @@ fn link_args(sess: Session,
         args.push(~"-shared-libgcc");
     }
 
+    if sess.targ_cfg.os == abi::OsAndroid {
+        // Many of the symbols defined in compiler-rt are also defined in libgcc.
+        // Android linker doesn't like that by default.
+        args.push(~"-Wl,--allow-multiple-definition");
+    }
+
+    // Stack growth requires statically linking a __morestack function
+    args.push(~"-lmorestack");
+    // compiler-rt contains implementations of low-level LLVM helpers
+    // It should go before platform and user libraries, so it has first dibs
+    // at resolving symbols that also appear in libgcc.
+    args.push(~"-lcompiler-rt");
+
     add_local_native_libraries(&mut args, sess);
     add_upstream_rust_crates(&mut args, sess, dylib, tmpdir);
     add_upstream_native_libraries(&mut args, sess);
@@ -1157,9 +1171,6 @@ fn link_args(sess: Session,
                        ~"-L/usr/local/lib/gcc44"]);
     }
 
-    // Stack growth requires statically linking a __morestack function
-    args.push(~"-lmorestack");
-
     // FIXME (#2397): At some point we want to rpath our guesses as to
     // where extern libraries might live, based on the
     // addl_lib_search_paths