about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRichard Diamond <wichard@vitalitystudios.com>2015-08-21 23:43:56 -0500
committerRichard Diamond <wichard@vitalitystudios.com>2015-12-13 15:05:43 -0600
commit7bd69f2248ce2635f3fc05f08d8a7944eed0016a (patch)
treeec6802421b3754c37226742c734fe365dc25076a
parent83eda080373285d3cbe4ca0ee280e4844c6422a3 (diff)
Better support for `--llvm-root`.
This handles cases when the LLVM used isn't configured will the 'usual'
targets. Also, cases where LLVM is shared are also handled (ie with
`LD_LIBRARY_PATH` etc).
-rwxr-xr-xconfigure10
-rw-r--r--mk/llvm.mk14
-rw-r--r--mk/main.mk15
-rw-r--r--mk/target.mk1
-rw-r--r--mk/tests.mk4
-rw-r--r--src/etc/maketest.py2
-rw-r--r--src/etc/mklldeps.py22
-rw-r--r--src/librustc_llvm/lib.rs32
-rw-r--r--src/librustc_trans/back/write.rs34
-rw-r--r--src/test/run-make/execution-engine/Makefile7
-rw-r--r--src/test/run-make/simd-ffi/Makefile21
-rw-r--r--src/test/run-make/tools.mk2
12 files changed, 115 insertions, 49 deletions
diff --git a/configure b/configure
index c505af5c4d3..4c5fa4aaa60 100755
--- a/configure
+++ b/configure
@@ -939,6 +939,13 @@ then
     putvar CFG_ENABLE_CLANG
 fi
 
+if [ -z "$CFG_DISABLE_LIBCPP" -a -n "$CFG_ENABLE_CLANG" ]
+then
+    CFG_USING_LIBCPP="1"
+else
+    CFG_USING_LIBCPP="0"
+fi
+
 # Same with jemalloc.  save the setting here.
 if [ -n "$CFG_DISABLE_JEMALLOC" ]
 then
@@ -1682,7 +1689,7 @@ do
         CXXFLAGS="$CXXFLAGS $LLVM_CXXFLAGS"
         LDFLAGS="$LDFLAGS $LLVM_LDFLAGS"
 
-        if [ -z "$CFG_DISABLE_LIBCPP" ] && [ -n "$CFG_USING_CLANG" ]; then
+        if [ "$CFG_USING_LIBCPP" != "0" ]; then
             LLVM_OPTS="$LLVM_OPTS --enable-libcpp"
         fi
 
@@ -1743,6 +1750,7 @@ putvar CFG_AARCH64_LINUX_ANDROID_NDK
 putvar CFG_ARM_LINUX_ANDROIDEABI_NDK
 putvar CFG_I686_LINUX_ANDROID_NDK
 putvar CFG_MANDIR
+putvar CFG_USING_LIBCPP
 
 # Avoid spurious warnings from clang by feeding it original source on
 # ccache-miss rather than preprocessed input.
diff --git a/mk/llvm.mk b/mk/llvm.mk
index b2a90f583f7..6d5e9169367 100644
--- a/mk/llvm.mk
+++ b/mk/llvm.mk
@@ -80,10 +80,16 @@ endif
 
 
 # LLVM linkage:
+# Note: Filter with llvm-config so that optional targets which aren't present
+# don't cause errors (ie PNaCl's target is only present within PNaCl's LLVM
+# fork).
 LLVM_LINKAGE_PATH_$(1):=$$(abspath $$(RT_OUTPUT_DIR_$(1))/llvmdeps.rs)
 $$(LLVM_LINKAGE_PATH_$(1)): $(S)src/etc/mklldeps.py $$(LLVM_CONFIG_$(1))
-	$(Q)$(CFG_PYTHON) "$$<" "$$@" "$$(LLVM_COMPONENTS)" "$$(CFG_ENABLE_LLVM_STATIC_STDCPP)" \
-		$$(LLVM_CONFIG_$(1)) "$(CFG_STDCPP_NAME)"
+	$(Q)$(CFG_PYTHON) "$$<" "$$@" "$$(filter $$(shell \
+				$$(LLVM_CONFIG_$(1)) --components), \
+                        $(LLVM_OPTIONAL_COMPONENTS)) $(LLVM_REQUIRED_COMPONENTS)" \
+		"$$(CFG_ENABLE_LLVM_STATIC_STDCPP)" $$(LLVM_CONFIG_$(1)) \
+		"$(CFG_STDCPP_NAME)" "$$(CFG_USING_LIBCPP)"
 endef
 
 $(foreach host,$(CFG_HOST), \
@@ -94,7 +100,9 @@ $(foreach host,$(CFG_HOST), \
 
 # This can't be done in target.mk because it's included before this file.
 define LLVM_LINKAGE_DEPS
-$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $$(LLVM_LINKAGE_PATH_$(2))
+$$(TLIB$(1)_T_$(2)_H_$(3))/stamp.rustc_llvm: $$(LLVM_LINKAGE_PATH_$(3))
+RUSTFLAGS$(1)_rustc_llvm_T_$(3) += $$(shell echo $$(LLVM_ALL_COMPONENTS_$(3)) | tr '-' '_' |\
+	sed -e 's/^ //;s/\([^ ]*\)/\-\-cfg have_component_\1/g')
 endef
 
 $(foreach source,$(CFG_HOST), \
diff --git a/mk/main.mk b/mk/main.mk
index d03769d9132..f2ff4f1c3a2 100644
--- a/mk/main.mk
+++ b/mk/main.mk
@@ -276,9 +276,18 @@ endif
 # LLVM macros
 ######################################################################
 
-LLVM_COMPONENTS=x86 arm aarch64 mips powerpc ipo bitreader bitwriter linker asmparser mcjit \
+LLVM_OPTIONAL_COMPONENTS=x86 arm aarch64 mips powerpc
+LLVM_REQUIRED_COMPONENTS=ipo bitreader bitwriter linker asmparser mcjit \
                 interpreter instrumentation
 
+ifneq ($(CFG_LLVM_ROOT),)
+# Ensure we only try to link targets that the installed LLVM actually has:
+LLVM_COMPONENTS := $(filter $(shell $(CFG_LLVM_ROOT)/bin/llvm-config$(X_$(CFG_BUILD)) --components),\
+			$(LLVM_OPTIONAL_COMPONENTS)) $(LLVM_REQUIRED_COMPONENTS)
+else
+LLVM_COMPONENTS := $(LLVM_OPTIONAL_COMPONENTS) $(LLVM_REQUIRED_COMPONENTS)
+endif
+
 # Only build these LLVM tools
 LLVM_TOOLS=bugpoint llc llvm-ar llvm-as llvm-dis llvm-mc opt llvm-extract
 
@@ -314,6 +323,8 @@ LLVM_HOST_TRIPLE_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --host-target)
 LLVM_AS_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llvm-as$$(X_$(1))
 LLC_$(1)=$$(CFG_LLVM_INST_DIR_$(1))/bin/llc$$(X_$(1))
 
+LLVM_ALL_COMPONENTS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --components)
+
 endef
 
 $(foreach host,$(CFG_HOST), \
@@ -476,7 +487,7 @@ endif
 endif
 
 LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3) := \
-    $$(CURDIR)/$$(HLIB$(1)_H_$(3))
+    $$(CURDIR)/$$(HLIB$(1)_H_$(3)):$$(CFG_LLVM_INST_DIR_$(3))/lib
 LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3) := \
     $$(CURDIR)/$$(TLIB1_T_$(2)_H_$(CFG_BUILD))
 
diff --git a/mk/target.mk b/mk/target.mk
index f1b5f9e3155..9d5e633c3c6 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -131,6 +131,7 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/$(4)$$(X_$(2)): \
 	@$$(call E, rustc: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) \
 		$$(STDCPP_LIBDIR_RUSTFLAGS_$(2)) \
+		$$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \
 		-o $$@ $$< --cfg $(4)
 
 endef
diff --git a/mk/tests.mk b/mk/tests.mk
index b41eaba1900..bd7414a3bb6 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -1072,7 +1072,9 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
 	    "$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))" \
 	    $(1) \
 	    $$(S) \
-	    $(3)
+	    $(3) \
+	    "$$(LLVM_LIBDIR_RUSTFLAGS_$(3))" \
+	    "$$(LLVM_ALL_COMPONENTS_$(3))"
 	@touch -r $$@.start_time $$@ && rm $$@.start_time
 else
 # FIXME #11094 - The above rule doesn't work right for multiple targets
diff --git a/src/etc/maketest.py b/src/etc/maketest.py
index c2958caddc4..34c2cdbef35 100644
--- a/src/etc/maketest.py
+++ b/src/etc/maketest.py
@@ -53,6 +53,8 @@ putenv('HOST_RPATH_DIR', os.path.abspath(sys.argv[10]))
 putenv('TARGET_RPATH_DIR', os.path.abspath(sys.argv[11]))
 putenv('RUST_BUILD_STAGE', sys.argv[12])
 putenv('S', os.path.abspath(sys.argv[13]))
+putenv('RUSTFLAGS', sys.argv[15])
+putenv('LLVM_COMPONENTS', sys.argv[16])
 putenv('PYTHON', sys.executable)
 os.putenv('TARGET', target_triple)
 
diff --git a/src/etc/mklldeps.py b/src/etc/mklldeps.py
index 215fa1cdd1b..8381e4f7040 100644
--- a/src/etc/mklldeps.py
+++ b/src/etc/mklldeps.py
@@ -18,6 +18,7 @@ components = sys.argv[2].split() # splits on whitespace
 enable_static = sys.argv[3]
 llvm_config = sys.argv[4]
 stdcpp_name = sys.argv[5]
+use_libcpp = sys.argv[6]
 
 f.write("""// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
@@ -44,11 +45,25 @@ def run(args):
         sys.exit(1)
     return out
 
+def runErr(args):
+    proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out, err = proc.communicate()
+
+    if err:
+        return False, out
+    else:
+        return True, out
+
 f.write("\n")
 
+args = [llvm_config, '--shared-mode']
+args.extend(components)
+llvm_shared, out = runErr(args)
+if llvm_shared:
+    llvm_shared = 'shared' in out
+
 # LLVM libs
 args = [llvm_config, '--libs', '--system-libs']
-
 args.extend(components)
 out = run(args)
 for lib in out.strip().replace("\n", ' ').split(' '):
@@ -63,8 +78,7 @@ for lib in out.strip().replace("\n", ' ').split(' '):
     elif lib[0] == '-':
         lib = lib.strip()[1:]
     f.write("#[link(name = \"" + lib + "\"")
-    # LLVM libraries are all static libraries
-    if 'LLVM' in lib:
+    if not llvm_shared and 'LLVM' in lib:
         f.write(", kind = \"static\"")
     f.write(")]\n")
 
@@ -83,7 +97,7 @@ else:
     # Note that we use `cfg_attr` here because on MSVC the C++ standard library
     # is not c++ or stdc++, but rather the linker takes care of linking the
     # right standard library.
-    if 'stdlib=libc++' in out:
+    if use_libcpp != "0" or 'stdlib=libc++' in out:
         f.write("#[cfg_attr(not(target_env = \"msvc\"), link(name = \"c++\"))]\n")
     else:
         f.write("#[cfg_attr(not(target_env = \"msvc\"), link(name = \"" + stdcpp_name + "\"))]\n")
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 2b9adf5490a..0f05db86742 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -33,6 +33,7 @@
 #![feature(link_args)]
 #![feature(staged_api)]
 #![feature(linked_from)]
+#![feature(concat_idents)]
 
 extern crate libc;
 #[macro_use] #[no_link] extern crate rustc_bitflags;
@@ -2327,6 +2328,37 @@ pub unsafe fn debug_loc_to_string(c: ContextRef, tr: DebugLocRef) -> String {
         .expect("got a non-UTF8 DebugLoc from LLVM")
 }
 
+pub fn initialize_available_targets() {
+    macro_rules! init_target(
+        ($cfg:ident $arch:ident) => { {
+            #[cfg($cfg)]
+            fn init() {
+                unsafe {
+                    let f = concat_idents!(LLVMInitialize, $arch, TargetInfo);
+                    f();
+                    let f = concat_idents!(LLVMInitialize, $arch, Target);
+                    f();
+                    let f = concat_idents!(LLVMInitialize, $arch, TargetMC);
+                    f();
+                    let f = concat_idents!(LLVMInitialize, $arch, AsmPrinter);
+                    f();
+                    let f = concat_idents!(LLVMInitialize, $arch, AsmParser);
+                    f();
+                }
+            }
+            #[cfg(not($cfg))]
+            fn init() { }
+            init();
+        } }
+    );
+
+    init_target!(have_component_powerpc PowerPC);
+    init_target!(have_component_mips Mips);
+    init_target!(have_component_aarch64 AArch64);
+    init_target!(have_component_arm ARM);
+    init_target!(have_component_x86 X86);
+}
+
 // The module containing the native LLVM dependencies, generated by the build system
 // Note that this must come after the rustllvm extern declaration so that
 // parts of LLVM that rustllvm depends on aren't thrown away by the linker.
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index c553843f858..4815a399d99 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -961,39 +961,7 @@ pub unsafe fn configure_llvm(sess: &Session) {
 
     llvm::LLVMInitializePasses();
 
-    // Only initialize the platforms supported by Rust here, because
-    // using --llvm-root will have multiple platforms that rustllvm
-    // doesn't actually link to and it's pointless to put target info
-    // into the registry that Rust cannot generate machine code for.
-    llvm::LLVMInitializeX86TargetInfo();
-    llvm::LLVMInitializeX86Target();
-    llvm::LLVMInitializeX86TargetMC();
-    llvm::LLVMInitializeX86AsmPrinter();
-    llvm::LLVMInitializeX86AsmParser();
-
-    llvm::LLVMInitializeARMTargetInfo();
-    llvm::LLVMInitializeARMTarget();
-    llvm::LLVMInitializeARMTargetMC();
-    llvm::LLVMInitializeARMAsmPrinter();
-    llvm::LLVMInitializeARMAsmParser();
-
-    llvm::LLVMInitializeAArch64TargetInfo();
-    llvm::LLVMInitializeAArch64Target();
-    llvm::LLVMInitializeAArch64TargetMC();
-    llvm::LLVMInitializeAArch64AsmPrinter();
-    llvm::LLVMInitializeAArch64AsmParser();
-
-    llvm::LLVMInitializeMipsTargetInfo();
-    llvm::LLVMInitializeMipsTarget();
-    llvm::LLVMInitializeMipsTargetMC();
-    llvm::LLVMInitializeMipsAsmPrinter();
-    llvm::LLVMInitializeMipsAsmParser();
-
-    llvm::LLVMInitializePowerPCTargetInfo();
-    llvm::LLVMInitializePowerPCTarget();
-    llvm::LLVMInitializePowerPCTargetMC();
-    llvm::LLVMInitializePowerPCAsmPrinter();
-    llvm::LLVMInitializePowerPCAsmParser();
+    llvm::initialize_available_targets();
 
     llvm::LLVMRustSetLLVMOptions(llvm_args.len() as c_int,
                                  llvm_args.as_ptr());
diff --git a/src/test/run-make/execution-engine/Makefile b/src/test/run-make/execution-engine/Makefile
index ef646c5bf5d..4c818cd99e2 100644
--- a/src/test/run-make/execution-engine/Makefile
+++ b/src/test/run-make/execution-engine/Makefile
@@ -4,6 +4,8 @@
 # This is a basic test of LLVM ExecutionEngine functionality using compiled
 # Rust code built using the `rustc` crate.
 
+ifeq ($(filter executionengine,$(LLVM_COMPONENTS)),executionengine)
+
 ifneq ($(shell uname),FreeBSD)
 all:
 	$(RUSTC) test.rs
@@ -12,3 +14,8 @@ else
 all:
 
 endif
+
+else
+all:
+
+endif
diff --git a/src/test/run-make/simd-ffi/Makefile b/src/test/run-make/simd-ffi/Makefile
index dc0fcec1980..e9c974a0137 100644
--- a/src/test/run-make/simd-ffi/Makefile
+++ b/src/test/run-make/simd-ffi/Makefile
@@ -1,15 +1,28 @@
 -include ../tools.mk
 
+TARGETS =
+ifeq ($(filter arm,$(LLVM_COMPONENTS)),arm)
 # construct a fairly exhaustive list of platforms that we
 # support. These ones don't follow a pattern
-TARGETS=arm-linux-androideabi arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabi
+TARGETS += arm-linux-androideabi arm-unknown-linux-gnueabihf arm-unknown-linux-gnueabi
+endif
+
+ifeq ($(filter x86,$(LLVM_COMPONENTS)),x86)
+X86_ARCHS = i686 x86_64
+else
+X86_ARCHS =
+endif
 
 # these ones do, each OS lists the architectures it supports
-LINUX=aarch64 i686 x86_64 mips mipsel
-WINDOWS=i686 x86_64
+LINUX=$(filter aarch64 mips,$(LLVM_COMPONENTS)) $(X86_ARCHS)
+ifeq ($(filter mips,$(LLVM_COMPONENTS)),mips)
+LINUX += mipsel
+endif
+
+WINDOWS=$(X86_ARCHS)
 # fails with: failed to get iphonesimulator SDK path: no such file or directory
 #IOS=i386 aarch64 armv7
-DARWIN=i686 x86_64
+DARWIN=$(X86_ARCHS)
 
 $(foreach arch,$(LINUX),$(eval TARGETS += $(arch)-unknown-linux-gnu))
 $(foreach arch,$(WINDOWS),$(eval TARGETS += $(arch)-pc-windows-gnu))
diff --git a/src/test/run-make/tools.mk b/src/test/run-make/tools.mk
index 23af568697f..88cf2a2b031 100644
--- a/src/test/run-make/tools.mk
+++ b/src/test/run-make/tools.mk
@@ -6,7 +6,7 @@ TARGET_RPATH_ENV = \
     $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))"
 
 BARE_RUSTC := $(HOST_RPATH_ENV) $(RUSTC)
-RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
+RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
 #CC := $(CC) -L $(TMPDIR)
 HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py