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).
This commit is contained in:
Richard Diamond 2015-08-21 23:43:56 -05:00
parent 83eda08037
commit 7bd69f2248
12 changed files with 115 additions and 49 deletions

10
configure vendored
View File

@ -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.

View File

@ -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), \

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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.

View File

@ -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());

View File

@ -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

View File

@ -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))

View File

@ -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