mirror of https://github.com/rust-lang/rust.git
Implement flexible target specification
Removes all target-specific knowledge from rustc. Some targets have changed during this, but none of these should be very visible outside of cross-compilation. The changes make our targets more consistent. iX86-unknown-linux-gnu is now only available as i686-unknown-linux-gnu. We used to accept any value of X greater than 1. i686 was released in 1995, and should encompass the bare minimum of what Rust supports on x86 CPUs. The only two windows targets are now i686-pc-windows-gnu and x86_64-pc-windows-gnu. The iOS target has been renamed from arm-apple-ios to arm-apple-darwin. A complete list of the targets we accept now: arm-apple-darwin arm-linux-androideabi arm-unknown-linux-gnueabi arm-unknown-linux-gnueabihf i686-apple-darwin i686-pc-windows-gnu i686-unknown-freebsd i686-unknown-linux-gnu mips-unknown-linux-gnu mipsel-unknown-linux-gnu x86_64-apple-darwin x86_64-unknown-freebsd x86_64-unknown-linux-gnu x86_64-pc-windows-gnu Closes #16093 [breaking-change]
This commit is contained in:
parent
82fb413d37
commit
6b130e3dd9
|
@ -291,6 +291,22 @@ envopt() {
|
|||
fi
|
||||
}
|
||||
|
||||
to_llvm_triple() {
|
||||
case $1 in
|
||||
i686-w64-mingw32) echo i686-pc-windows-gnu ;;
|
||||
x86_64-w64-mingw32) echo x86_64-pc-windows-gnu ;;
|
||||
*) echo $1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
to_gnu_triple() {
|
||||
case $1 in
|
||||
i686-pc-windows-gnu) echo i686-w64-mingw32 ;;
|
||||
x86_64-pc-windows-gnu) echo x86_64-w64-mingw32 ;;
|
||||
*) echo $1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
msg "looking for configure programs"
|
||||
need_cmd cmp
|
||||
need_cmd mkdir
|
||||
|
@ -350,37 +366,40 @@ case $CFG_OSTYPE in
|
|||
# instead, msys defines $MSYSTEM which is MINGW32 on i686 and
|
||||
# MINGW64 on x86_64.
|
||||
CFG_CPUTYPE=i686
|
||||
CFG_OSTYPE=w64-mingw32
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
if [ "$MSYSTEM" = MINGW64 ]
|
||||
then
|
||||
CFG_CPUTYPE=x86_64
|
||||
CFG_OSTYPE=w64-mingw32
|
||||
fi
|
||||
;;
|
||||
|
||||
MSYS*)
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
;;
|
||||
|
||||
# Thad's Cygwin identifers below
|
||||
|
||||
# Vista 32 bit
|
||||
CYGWIN_NT-6.0)
|
||||
CFG_OSTYPE=pc-mingw32
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
CFG_CPUTYPE=i686
|
||||
;;
|
||||
|
||||
# Vista 64 bit
|
||||
CYGWIN_NT-6.0-WOW64)
|
||||
CFG_OSTYPE=w64-mingw32
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
CFG_CPUTYPE=x86_64
|
||||
;;
|
||||
|
||||
# Win 7 32 bit
|
||||
CYGWIN_NT-6.1)
|
||||
CFG_OSTYPE=pc-mingw32
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
CFG_CPUTYPE=i686
|
||||
;;
|
||||
|
||||
# Win 7 64 bit
|
||||
CYGWIN_NT-6.1-WOW64)
|
||||
CFG_OSTYPE=w64-mingw32
|
||||
CFG_OSTYPE=pc-windows-gnu
|
||||
CFG_CPUTYPE=x86_64
|
||||
;;
|
||||
|
||||
|
@ -466,7 +485,6 @@ opt llvm-assertions 1 "build LLVM with assertions"
|
|||
opt debug 1 "build with extra debug fun"
|
||||
opt ratchet-bench 0 "ratchet benchmarks"
|
||||
opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
|
||||
opt mingw-cross 0 "cross-compile for win32 using mingw"
|
||||
opt ccache 0 "invoke gcc/clang via ccache to reuse object files between builds"
|
||||
opt local-rust 0 "use an installed rustc rather than downloading a snapshot"
|
||||
opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
|
||||
|
@ -487,7 +505,6 @@ valopt llvm-root "" "set LLVM root"
|
|||
valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located"
|
||||
valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
|
||||
valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path"
|
||||
valopt mingw32-cross-path "" "MinGW32 cross compiler path"
|
||||
|
||||
# Many of these are saved below during the "writing configuration" step
|
||||
# (others are conditionally saved).
|
||||
|
@ -501,12 +518,18 @@ valopt_nosave target "${CFG_HOST}" "GNUs ./configure syntax LLVM target triples"
|
|||
valopt_nosave mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
|
||||
valopt_nosave release-channel "dev" "the name of the release channel to build"
|
||||
|
||||
# Temporarily support old triples until buildbots get updated
|
||||
CFG_BUILD=$(to_llvm_triple $CFG_BUILD)
|
||||
putvar CFG_BUILD # Yes, this creates a duplicate entry, but the last one wins.
|
||||
CFG_HOST=$(to_llvm_triple $CFG_HOST)
|
||||
CFG_TARGET=$(to_llvm_triple $CFG_TARGET)
|
||||
|
||||
# On windows we just store the libraries in the bin directory because
|
||||
# there's no rpath. This is where the build system itself puts libraries;
|
||||
# --libdir is used to configure the installation directory.
|
||||
# FIXME: This needs to parameterized over target triples. Do it in platform.mk
|
||||
CFG_LIBDIR_RELATIVE=lib
|
||||
if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
|
||||
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ]
|
||||
then
|
||||
CFG_LIBDIR_RELATIVE=bin
|
||||
fi
|
||||
|
@ -632,7 +655,7 @@ then
|
|||
fi
|
||||
|
||||
BIN_SUF=
|
||||
if [ "$CFG_OSTYPE" = "pc-mingw32" ] || [ "$CFG_OSTYPE" = "w64-mingw32" ]
|
||||
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ]
|
||||
then
|
||||
BIN_SUF=.exe
|
||||
fi
|
||||
|
@ -1100,12 +1123,15 @@ do
|
|||
|
||||
if [ ${do_reconfigure} -ne 0 ]
|
||||
then
|
||||
msg "configuring LLVM for $t"
|
||||
# LLVM's configure doesn't recognize the new Windows triples yet
|
||||
gnu_t=$(to_gnu_triple $t)
|
||||
|
||||
msg "configuring LLVM for $gnu_t"
|
||||
|
||||
LLVM_TARGETS="--enable-targets=x86,x86_64,arm,mips"
|
||||
LLVM_BUILD="--build=$t"
|
||||
LLVM_HOST="--host=$t"
|
||||
LLVM_TARGET="--target=$t"
|
||||
LLVM_BUILD="--build=$gnu_t"
|
||||
LLVM_HOST="--host=$gnu_t"
|
||||
LLVM_TARGET="--target=$gnu_t"
|
||||
|
||||
# Disable unused LLVM features
|
||||
LLVM_OPTS="$LLVM_DBG_OPTS $LLVM_ASSERTION_OPTS --disable-docs --enable-bindings=none"
|
||||
|
@ -1119,7 +1145,7 @@ do
|
|||
# (llvm's configure tries to find pthread first, so we have to disable it explicitly.)
|
||||
# Also note that pthreads works badly on mingw-w64 systems: #8996
|
||||
case "$CFG_BUILD" in
|
||||
(*-mingw32)
|
||||
(*-windows-*)
|
||||
LLVM_OPTS="$LLVM_OPTS --disable-pthreads"
|
||||
;;
|
||||
esac
|
||||
|
@ -1269,6 +1295,7 @@ putvar CFG_HOST
|
|||
putvar CFG_TARGET
|
||||
putvar CFG_LIBDIR_RELATIVE
|
||||
putvar CFG_DISABLE_MANAGE_SUBMODULES
|
||||
putvar CFG_ANDROID_CROSS_PATH
|
||||
putvar CFG_MANDIR
|
||||
|
||||
# Avoid spurious warnings from clang by feeding it original source on
|
||||
|
|
|
@ -3,7 +3,7 @@ CFG_SDK_NAME_arm-apple-ios = iphoneos
|
|||
CFG_SDK_ARCHS_arm-apple-ios = armv7
|
||||
ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
|
||||
CFG_IOS_SDK = $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
|
||||
CFG_IOS_FLAGS = -target armv7-apple-darwin -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
|
||||
CFG_IOS_FLAGS = -target armv7-apple-ios -isysroot $(CFG_IOS_SDK) -mios-version-min=7.0
|
||||
CC_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
|
||||
CXX_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
CPP_arm-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
|
||||
|
@ -32,3 +32,4 @@ CFG_RUN_arm-apple-ios = $(2)
|
|||
CFG_RUN_TARG_arm-apple-ios = $(call CFG_RUN_arm-apple-ios,,$(2))
|
||||
RUSTC_FLAGS_arm-apple-ios := -C relocation_model=pic
|
||||
RUSTC_CROSS_FLAGS_arm-apple-ios :=-C relocation_model=pic
|
||||
CFG_GNU_TRIPLE_arm-apple-ios := arm-apple-ios
|
||||
|
|
|
@ -26,3 +26,4 @@ CFG_RUN_arm-linux-androideabi=
|
|||
CFG_RUN_TARG_arm-linux-androideabi=
|
||||
RUSTC_FLAGS_arm-linux-androideabi :=
|
||||
RUSTC_CROSS_FLAGS_arm-linux-androideabi :=
|
||||
CFG_GNU_TRIPLE_arm-linux-androideabi := arm-linux-androideabi
|
||||
|
|
|
@ -27,3 +27,4 @@ CFG_RUN_arm-unknown-linux-gnueabi=$(2)
|
|||
CFG_RUN_TARG_arm-unknown-linux-gnueabi=$(call CFG_RUN_arm-unknown-linux-gnueabi,,$(2))
|
||||
RUSTC_FLAGS_arm-unknown-linux-gnueabi :=
|
||||
RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabi :=
|
||||
CFG_GNU_TRIPLE_arm-unknown-linux-gnueabi := arm-unknown-linux-gnueabi
|
||||
|
|
|
@ -27,3 +27,4 @@ CFG_RUN_arm-unknown-linux-gnueabihf=$(2)
|
|||
CFG_RUN_TARG_arm-unknown-linux-gnueabihf=$(call CFG_RUN_arm-unknown-linux-gnueabihf,,$(2))
|
||||
RUSTC_FLAGS_arm-unknown-linux-gnueabihf := -C target-feature=+v6,+vfp2
|
||||
RUSTC_CROSS_FLAGS_arm-unknown-linux-gnueabihf :=
|
||||
CFG_GNU_TRIPLE_arm-unknown-linux-gnueabihf := arm-unknown-linux-gnueabihf
|
||||
|
|
|
@ -31,3 +31,4 @@ CFG_LDPATH_i386-apple-ios =
|
|||
CFG_RUN_i386-apple-ios = $(2)
|
||||
CFG_RUN_TARG_i386-apple-ios = $(call CFG_RUN_i386-apple-ios,,$(2))
|
||||
CFG_JEMALLOC_CFLAGS_i386-apple-ios = -target i386-apple-ios -Wl,-syslibroot $(CFG_IOSSIM_SDK) -Wl,-no_compact_unwind
|
||||
CFG_GNU_TRIPLE_i386-apple-ios := i386-apple-ios
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
# i586-mingw32msvc configuration
|
||||
CC_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-gcc
|
||||
CXX_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-g++
|
||||
CPP_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-cpp
|
||||
AR_i586-mingw32msvc=$(CFG_MINGW32_CROSS_PATH)/bin/i586-mingw32msvc-ar
|
||||
CFG_LIB_NAME_i586-mingw32msvc=$(1).dll
|
||||
CFG_STATIC_LIB_NAME_i586-mingw32msvc=$(1).lib
|
||||
CFG_LIB_GLOB_i586-mingw32msvc=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_i586-mingw32msvc=$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_i586-mingw32msvc := -march=i586 -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i586-mingw32msvc := -Wall -Werror -g -march=i586 -m32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i586-mingw32msvc := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i586-mingw32msvc := -shared -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i586-mingw32msvc :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i586-mingw32msvc :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i586-mingw32msvc :=
|
||||
CFG_DEF_SUFFIX_i586-mingw32msvc := .mingw32.def
|
||||
CFG_LLC_FLAGS_i586-mingw32msvc :=
|
||||
CFG_INSTALL_NAME_i586-mingw32msvc =
|
||||
CFG_EXE_SUFFIX_i586-mingw32msvc := .exe
|
||||
CFG_WINDOWSY_i586-mingw32msvc := 1
|
||||
CFG_UNIXY_i586-mingw32msvc :=
|
||||
CFG_PATH_MUNGE_i586-mingw32msvc := $(strip perl -i.bak -p \
|
||||
-e 's@\\(\S)@/\1@go;' \
|
||||
-e 's@^/([a-zA-Z])/@\1:/@o;')
|
||||
CFG_LDPATH_i586-mingw32msvc :=
|
||||
CFG_RUN_i586-mingw32msvc=
|
||||
CFG_RUN_TARG_i586-mingw32msvc=
|
||||
|
|
@ -24,4 +24,4 @@ CFG_PATH_MUNGE_i686-apple-darwin := true
|
|||
CFG_LDPATH_i686-apple-darwin :=
|
||||
CFG_RUN_i686-apple-darwin=$(2)
|
||||
CFG_RUN_TARG_i686-apple-darwin=$(call CFG_RUN_i686-apple-darwin,,$(2))
|
||||
|
||||
CFG_GNU_TRIPLE_i686-apple-darwin := i686-apple-darwin
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# i686-pc-windows-gnu configuration
|
||||
CROSS_PREFIX_i686-pc-windows-gnu=i686-pc-windows-gnu-
|
||||
CC_i686-pc-windows-gnu=gcc
|
||||
CXX_i686-pc-windows-gnu=g++
|
||||
CPP_i686-pc-windows-gnu=gcc -E
|
||||
AR_i686-pc-windows-gnu=ar
|
||||
CFG_LIB_NAME_i686-pc-windows-gnu=$(1).dll
|
||||
CFG_STATIC_LIB_NAME_i686-pc-windows-gnu=$(1).lib
|
||||
CFG_LIB_GLOB_i686-pc-windows-gnu=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_i686-pc-windows-gnu=$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_i686-pc-windows-gnu := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-pc-windows-gnu := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i686-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-pc-windows-gnu := -shared -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i686-pc-windows-gnu :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-pc-windows-gnu :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-pc-windows-gnu :=
|
||||
CFG_DEF_SUFFIX_i686-pc-windows-gnu := .windows.def
|
||||
CFG_LLC_FLAGS_i686-pc-windows-gnu :=
|
||||
CFG_INSTALL_NAME_i686-pc-windows-gnu =
|
||||
CFG_EXE_SUFFIX_i686-pc-windows-gnu := .exe
|
||||
CFG_WINDOWSY_i686-pc-windows-gnu := 1
|
||||
CFG_UNIXY_i686-pc-windows-gnu :=
|
||||
CFG_PATH_MUNGE_i686-pc-windows-gnu :=
|
||||
CFG_LDPATH_i686-pc-windows-gnu :=$(CFG_LDPATH_i686-pc-windows-gnu):$(PATH)
|
||||
CFG_RUN_i686-pc-windows-gnu=PATH="$(CFG_LDPATH_i686-pc-windows-gnu):$(1)" $(2)
|
||||
CFG_RUN_TARG_i686-pc-windows-gnu=$(call CFG_RUN_i686-pc-windows-gnu,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
|
||||
CFG_GNU_TRIPLE_i686-pc-windows-gnu := i686-w64-mingw32
|
|
@ -24,4 +24,4 @@ CFG_PATH_MUNGE_i686-unknown-linux-gnu := true
|
|||
CFG_LDPATH_i686-unknown-linux-gnu :=
|
||||
CFG_RUN_i686-unknown-linux-gnu=$(2)
|
||||
CFG_RUN_TARG_i686-unknown-linux-gnu=$(call CFG_RUN_i686-unknown-linux-gnu,,$(2))
|
||||
|
||||
CFG_GNU_TRIPLE_i686-unknown-linux-gnu := i686-unknown-linux-gnu
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# i686-w64-mingw32 configuration
|
||||
CROSS_PREFIX_i686-w64-mingw32=i686-w64-mingw32-
|
||||
CC_i686-w64-mingw32=gcc
|
||||
CXX_i686-w64-mingw32=g++
|
||||
CPP_i686-w64-mingw32=gcc -E
|
||||
AR_i686-w64-mingw32=ar
|
||||
CFG_LIB_NAME_i686-w64-mingw32=$(1).dll
|
||||
CFG_STATIC_LIB_NAME_i686-w64-mingw32=$(1).lib
|
||||
CFG_LIB_GLOB_i686-w64-mingw32=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_i686-w64-mingw32=$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_i686-w64-mingw32 := -march=i686 -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_i686-w64-mingw32 := -Wall -Werror -g -m32 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_i686-w64-mingw32 := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_i686-w64-mingw32 := -shared -g -m32
|
||||
CFG_GCCISH_DEF_FLAG_i686-w64-mingw32 :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_DEF_SUFFIX_i686-w64-mingw32 := .mingw32.def
|
||||
CFG_LLC_FLAGS_i686-w64-mingw32 :=
|
||||
CFG_INSTALL_NAME_i686-w64-mingw32 =
|
||||
CFG_EXE_SUFFIX_i686-w64-mingw32 := .exe
|
||||
CFG_WINDOWSY_i686-w64-mingw32 := 1
|
||||
CFG_UNIXY_i686-w64-mingw32 :=
|
||||
CFG_PATH_MUNGE_i686-w64-mingw32 :=
|
||||
CFG_LDPATH_i686-w64-mingw32 :=$(CFG_LDPATH_i686-w64-mingw32):$(PATH)
|
||||
CFG_RUN_i686-w64-mingw32=PATH="$(CFG_LDPATH_i686-w64-mingw32):$(1)" $(2)
|
||||
CFG_RUN_TARG_i686-w64-mingw32=$(call CFG_RUN_i686-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
|
||||
# Stop rustc from OOMing when building itself (I think)
|
||||
RUSTC_FLAGS_i686-w64-mingw32=-C link-args="-Wl,--large-address-aware"
|
||||
RUSTC_CROSS_FLAGS_i686-w64-mingw32 :=
|
||||
|
|
@ -25,3 +25,4 @@ CFG_LDPATH_mips-unknown-linux-gnu :=
|
|||
CFG_RUN_mips-unknown-linux-gnu=
|
||||
CFG_RUN_TARG_mips-unknown-linux-gnu=
|
||||
RUSTC_FLAGS_mips-unknown-linux-gnu := -C target-cpu=mips32r2 -C target-feature="+mips32r2,+o32" -C soft-float
|
||||
CFG_GNU_TRIPLE_mips-unknown-linux-gnu := mips-unknown-linux-gnu
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
# mipsel-linux configuration
|
||||
CC_mipsel-linux=mipsel-linux-gcc
|
||||
CXX_mipsel-linux=mipsel-linux-g++
|
||||
CPP_mipsel-linux=mipsel-linux-gcc
|
||||
AR_mipsel-linux=mipsel-linux-ar
|
||||
CFG_LIB_NAME_mipsel-linux=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_mipsel-linux=lib$(1).a
|
||||
CFG_LIB_GLOB_mipsel-linux=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_mipsel-linux=lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_mipsel-linux := -mips32 -mabi=32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_mipsel-linux := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_mipsel-linux := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_mipsel-linux := -shared -fPIC -g -mips32
|
||||
CFG_GCCISH_DEF_FLAG_mipsel-linux := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_mipsel-linux := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_mipsel-linux := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_mipsel-linux := .linux.def
|
||||
CFG_LLC_FLAGS_mipsel-linux :=
|
||||
CFG_INSTALL_NAME_mipsel-linux =
|
||||
CFG_EXE_SUFFIX_mipsel-linux :=
|
||||
CFG_WINDOWSY_mipsel-linux :=
|
||||
CFG_UNIXY_mipsel-linux := 1
|
||||
CFG_PATH_MUNGE_mipsel-linux := true
|
||||
CFG_LDPATH_mipsel-linux :=
|
||||
CFG_RUN_mipsel-linux=
|
||||
CFG_RUN_TARG_mipsel-linux=
|
||||
RUSTC_FLAGS_mipsel-linux := -C target-cpu=mips32 -C target-feature="+mips32,+o32"
|
|
@ -0,0 +1,28 @@
|
|||
# mipsel-unknown-linux-gnu configuration
|
||||
CC_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-gcc
|
||||
CXX_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-g++
|
||||
CPP_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-gcc
|
||||
AR_mipsel-unknown-linux-gnu=mipsel-unknown-linux-gnu-ar
|
||||
CFG_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).so
|
||||
CFG_STATIC_LIB_NAME_mipsel-unknown-linux-gnu=lib$(1).a
|
||||
CFG_LIB_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.so
|
||||
CFG_LIB_DSYM_GLOB_mipsel-unknown-linux-gnu=lib$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_mipsel-unknown-linux-gnu := -mips32 -mabi=32 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_mipsel-unknown-linux-gnu := -Wall -g -fPIC -mips32 -mabi=32 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_mipsel-unknown-linux-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_mipsel-unknown-linux-gnu := -shared -fPIC -g -mips32
|
||||
CFG_GCCISH_DEF_FLAG_mipsel-unknown-linux-gnu := -Wl,--export-dynamic,--dynamic-list=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-whole-archive
|
||||
CFG_GCCISH_POST_LIB_FLAGS_mipsel-unknown-linux-gnu := -Wl,-no-whole-archive
|
||||
CFG_DEF_SUFFIX_mipsel-unknown-linux-gnu := .linux.def
|
||||
CFG_LLC_FLAGS_mipsel-unknown-linux-gnu :=
|
||||
CFG_INSTALL_NAME_mipsel-unknown-linux-gnu =
|
||||
CFG_EXE_SUFFIX_mipsel-unknown-linux-gnu :=
|
||||
CFG_WINDOWSY_mipsel-unknown-linux-gnu :=
|
||||
CFG_UNIXY_mipsel-unknown-linux-gnu := 1
|
||||
CFG_PATH_MUNGE_mipsel-unknown-linux-gnu := true
|
||||
CFG_LDPATH_mipsel-unknown-linux-gnu :=
|
||||
CFG_RUN_mipsel-unknown-linux-gnu=
|
||||
CFG_RUN_TARG_mipsel-unknown-linux-gnu=
|
||||
RUSTC_FLAGS_mipsel-unknown-linux-gnu := -C target-cpu=mips32 -C target-feature="+mips32,+o32"
|
||||
CFG_GNU_TRIPLE_mipsel-unknown-linux-gnu := mipsel-unknown-linux-gnu
|
|
@ -24,3 +24,4 @@ CFG_PATH_MUNGE_x86_64-apple-darwin := true
|
|||
CFG_LDPATH_x86_64-apple-darwin :=
|
||||
CFG_RUN_x86_64-apple-darwin=$(2)
|
||||
CFG_RUN_TARG_x86_64-apple-darwin=$(call CFG_RUN_x86_64-apple-darwin,,$(2))
|
||||
CFG_GNU_TRIPLE_x86_64-apple-darwin := x86_64-apple-darwin
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# x86_64-pc-windows-gnu configuration
|
||||
CROSS_PREFIX_x86_64-pc-windows-gnu=x86_64-pc-windows-gnu-
|
||||
CC_x86_64-pc-windows-gnu=gcc
|
||||
CXX_x86_64-pc-windows-gnu=g++
|
||||
CPP_x86_64-pc-windows-gnu=gcc -E
|
||||
AR_x86_64-pc-windows-gnu=ar
|
||||
CFG_LIB_NAME_x86_64-pc-windows-gnu=$(1).dll
|
||||
CFG_STATIC_LIB_NAME_x86_64-pc-windows-gnu=$(1).lib
|
||||
CFG_LIB_GLOB_x86_64-pc-windows-gnu=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-gnu=$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_x86_64-pc-windows-gnu := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-pc-windows-gnu := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-gnu := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-gnu := -shared -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-gnu :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-pc-windows-gnu :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-pc-windows-gnu :=
|
||||
CFG_DEF_SUFFIX_x86_64-pc-windows-gnu := .windows.def
|
||||
CFG_LLC_FLAGS_x86_64-pc-windows-gnu :=
|
||||
CFG_INSTALL_NAME_x86_64-pc-windows-gnu =
|
||||
CFG_EXE_SUFFIX_x86_64-pc-windows-gnu := .exe
|
||||
CFG_WINDOWSY_x86_64-pc-windows-gnu := 1
|
||||
CFG_UNIXY_x86_64-pc-windows-gnu :=
|
||||
CFG_PATH_MUNGE_x86_64-pc-windows-gnu :=
|
||||
CFG_LDPATH_x86_64-pc-windows-gnu :=$(CFG_LDPATH_x86_64-pc-windows-gnu):$(PATH)
|
||||
CFG_RUN_x86_64-pc-windows-gnu=PATH="$(CFG_LDPATH_x86_64-pc-windows-gnu):$(1)" $(2)
|
||||
CFG_RUN_TARG_x86_64-pc-windows-gnu=$(call CFG_RUN_x86_64-pc-windows-gnu,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
|
||||
CFG_GNU_TRIPLE_x86_64-pc-windows-gnu := x86_64-w64-mingw32
|
|
@ -23,3 +23,4 @@ CFG_PATH_MUNGE_x86_64-unknown-dragonfly :=
|
|||
CFG_LDPATH_x86_64-unknown-dragonfly :=
|
||||
CFG_RUN_x86_64-unknown-dragonfly=$(2)
|
||||
CFG_RUN_TARG_x86_64-unknown-dragonfly=$(call CFG_RUN_x86_64-unknown-dragonfly,,$(2))
|
||||
CFG_GNU_TRIPLE_x86_64-unknown-dragonfly := x86_64-unknown-dragonfly
|
||||
|
|
|
@ -23,3 +23,4 @@ CFG_PATH_MUNGE_x86_64-unknown-freebsd :=
|
|||
CFG_LDPATH_x86_64-unknown-freebsd :=
|
||||
CFG_RUN_x86_64-unknown-freebsd=$(2)
|
||||
CFG_RUN_TARG_x86_64-unknown-freebsd=$(call CFG_RUN_x86_64-unknown-freebsd,,$(2))
|
||||
CFG_GNU_TRIPLE_x86_64-unknown-freebsd := x86_64-unknown-freebsd
|
||||
|
|
|
@ -24,3 +24,5 @@ CFG_PATH_MUNGE_x86_64-unknown-linux-gnu := true
|
|||
CFG_LDPATH_x86_64-unknown-linux-gnu :=
|
||||
CFG_RUN_x86_64-unknown-linux-gnu=$(2)
|
||||
CFG_RUN_TARG_x86_64-unknown-linux-gnu=$(call CFG_RUN_x86_64-unknown-linux-gnu,,$(2))
|
||||
CFG_GNU_TRIPLE_x86_64-unknown-linux-gnu := x86_64-unknown-linux-gnu
|
||||
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
# x86_64-w64-mingw32 configuration
|
||||
CROSS_PREFIX_x86_64-w64-mingw32=x86_64-w64-mingw32-
|
||||
CC_x86_64-w64-mingw32=gcc
|
||||
CXX_x86_64-w64-mingw32=g++
|
||||
CPP_x86_64-w64-mingw32=gcc -E
|
||||
AR_x86_64-w64-mingw32=ar
|
||||
CFG_LIB_NAME_x86_64-w64-mingw32=$(1).dll
|
||||
CFG_STATIC_LIB_NAME_x86_64-w64-mingw32=$(1).lib
|
||||
CFG_LIB_GLOB_x86_64-w64-mingw32=$(1)-*.dll
|
||||
CFG_LIB_DSYM_GLOB_x86_64-w64-mingw32=$(1)-*.dylib.dSYM
|
||||
CFG_CFLAGS_x86_64-w64-mingw32 := -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CFLAGS_x86_64-w64-mingw32 := -Wall -Werror -g -m64 -D_WIN32_WINNT=0x0600 $(CFLAGS)
|
||||
CFG_GCCISH_CXXFLAGS_x86_64-w64-mingw32 := -fno-rtti $(CXXFLAGS)
|
||||
CFG_GCCISH_LINK_FLAGS_x86_64-w64-mingw32 := -shared -g -m64
|
||||
CFG_GCCISH_DEF_FLAG_x86_64-w64-mingw32 :=
|
||||
CFG_GCCISH_PRE_LIB_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_GCCISH_POST_LIB_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_DEF_SUFFIX_x86_64-w64-mingw32 := .mingw32.def
|
||||
CFG_LLC_FLAGS_x86_64-w64-mingw32 :=
|
||||
CFG_INSTALL_NAME_x86_64-w64-mingw32 =
|
||||
CFG_EXE_SUFFIX_x86_64-w64-mingw32 := .exe
|
||||
CFG_WINDOWSY_x86_64-w64-mingw32 := 1
|
||||
CFG_UNIXY_x86_64-w64-mingw32 :=
|
||||
CFG_PATH_MUNGE_x86_64-w64-mingw32 :=
|
||||
CFG_LDPATH_x86_64-w64-mingw32 :=$(CFG_LDPATH_x86_64-w64-mingw32):$(PATH)
|
||||
CFG_RUN_x86_64-w64-mingw32=PATH="$(CFG_LDPATH_x86_64-w64-mingw32):$(1)" $(2)
|
||||
CFG_RUN_TARG_x86_64-w64-mingw32=$(call CFG_RUN_x86_64-w64-mingw32,$(HLIB$(1)_H_$(CFG_BUILD)),$(2))
|
||||
RUSTC_CROSS_FLAGS_x86_64-w64-mingw32 :=
|
|
@ -311,7 +311,6 @@ export CFG_RELEASE
|
|||
export CFG_PACKAGE_NAME
|
||||
export CFG_BUILD
|
||||
export CFG_LLVM_ROOT
|
||||
export CFG_ENABLE_MINGW_CROSS
|
||||
export CFG_PREFIX
|
||||
export CFG_LIBDIR
|
||||
export CFG_LIBDIR_RELATIVE
|
||||
|
|
2
mk/rt.mk
2
mk/rt.mk
|
@ -176,7 +176,7 @@ $$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
|
|||
@$$(call E, make: jemalloc)
|
||||
cd "$$(JEMALLOC_BUILD_DIR_$(1))"; "$(S)src/jemalloc/configure" \
|
||||
$$(JEMALLOC_ARGS_$(1)) --with-jemalloc-prefix=je_ $(CFG_JEMALLOC_FLAGS) \
|
||||
--build=$(CFG_BUILD) --host=$(1) \
|
||||
--build=$$(CFG_GNU_TRIPLE_$(CFG_BUILD)) --host=$$(CFG_GNU_TRIPLE_$(1)) \
|
||||
CC="$$(CC_$(1))" \
|
||||
AR="$$(AR_$(1))" \
|
||||
RANLIB="$$(AR_$(1)) s" \
|
||||
|
|
|
@ -75,9 +75,8 @@ def full_snapshot_name(date, rev, platform, hsh):
|
|||
|
||||
|
||||
def get_kernel(triple):
|
||||
os_name = triple.split('-')[-1]
|
||||
#scrub(os.getenv("CFG_ENABLE_MINGW_CROSS")):
|
||||
if os_name == "nt" or os_name == "mingw32":
|
||||
os_name = triple.split('-')[2]
|
||||
if os_name == "windows":
|
||||
return "winnt"
|
||||
if os_name == "darwin":
|
||||
return "macos"
|
||||
|
|
|
@ -19,7 +19,7 @@ use driver::config::NoDebugInfo;
|
|||
use driver::session::Session;
|
||||
use driver::config;
|
||||
use metadata::common::LinkMeta;
|
||||
use metadata::{encoder, cstore, filesearch, csearch, loader, creader};
|
||||
use metadata::{encoder, cstore, filesearch, csearch, creader};
|
||||
use middle::trans::context::CrateContext;
|
||||
use middle::trans::common::gensym_name;
|
||||
use middle::ty;
|
||||
|
@ -36,7 +36,6 @@ use std::str;
|
|||
use std::string::String;
|
||||
use flate;
|
||||
use serialize::hex::ToHex;
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map::{PathElem, PathElems, PathName};
|
||||
use syntax::ast_map;
|
||||
|
@ -363,17 +362,8 @@ pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> Stri
|
|||
pub fn get_cc_prog(sess: &Session) -> String {
|
||||
match sess.opts.cg.linker {
|
||||
Some(ref linker) => return linker.to_string(),
|
||||
None => {}
|
||||
None => sess.target.target.options.linker.clone(),
|
||||
}
|
||||
|
||||
// In the future, FreeBSD will use clang as default compiler.
|
||||
// It would be flexible to use cc (system's default C compiler)
|
||||
// instead of hard-coded gcc.
|
||||
// For Windows, there is no cc command, so we add a condition to make it use gcc.
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsWindows => "gcc",
|
||||
_ => "cc",
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
pub fn remove(sess: &Session, path: &Path) {
|
||||
|
@ -397,7 +387,7 @@ pub fn link_binary(sess: &Session,
|
|||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
if invalid_output_for_target(sess, crate_type) {
|
||||
sess.bug(format!("invalid output type `{}` for target os `{}`",
|
||||
crate_type, sess.targ_cfg.os).as_slice());
|
||||
crate_type, sess.opts.target_triple).as_slice());
|
||||
}
|
||||
let out_file = link_binary_output(sess, trans, crate_type, outputs,
|
||||
crate_name);
|
||||
|
@ -427,17 +417,20 @@ pub fn link_binary(sess: &Session,
|
|||
/// interaction with Rust code through static library is the only
|
||||
/// option for now
|
||||
pub fn default_output_for_target(sess: &Session) -> config::CrateType {
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsiOS => config::CrateTypeStaticlib,
|
||||
_ => config::CrateTypeExecutable
|
||||
if !sess.target.target.options.executables {
|
||||
config::CrateTypeStaticlib
|
||||
} else {
|
||||
config::CrateTypeExecutable
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if target supports crate_type as output
|
||||
pub fn invalid_output_for_target(sess: &Session,
|
||||
crate_type: config::CrateType) -> bool {
|
||||
match (sess.targ_cfg.os, crate_type) {
|
||||
(abi::OsiOS, config::CrateTypeDylib) => true,
|
||||
match (sess.target.target.options.dynamic_linking,
|
||||
sess.target.target.options.executables, crate_type) {
|
||||
(false, _, config::CrateTypeDylib) => true,
|
||||
(_, false, config::CrateTypeExecutable) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -459,15 +452,8 @@ pub fn filename_for_input(sess: &Session,
|
|||
out_filename.with_filename(format!("lib{}.rlib", libname))
|
||||
}
|
||||
config::CrateTypeDylib => {
|
||||
let (prefix, suffix) = match sess.targ_cfg.os {
|
||||
abi::OsWindows => (loader::WIN32_DLL_PREFIX, loader::WIN32_DLL_SUFFIX),
|
||||
abi::OsMacos => (loader::MACOS_DLL_PREFIX, loader::MACOS_DLL_SUFFIX),
|
||||
abi::OsLinux => (loader::LINUX_DLL_PREFIX, loader::LINUX_DLL_SUFFIX),
|
||||
abi::OsAndroid => (loader::ANDROID_DLL_PREFIX, loader::ANDROID_DLL_SUFFIX),
|
||||
abi::OsFreebsd => (loader::FREEBSD_DLL_PREFIX, loader::FREEBSD_DLL_SUFFIX),
|
||||
abi::OsDragonfly => (loader::DRAGONFLY_DLL_PREFIX, loader::DRAGONFLY_DLL_SUFFIX),
|
||||
abi::OsiOS => unreachable!(),
|
||||
};
|
||||
let (prefix, suffix) = (sess.target.target.options.dll_prefix.as_slice(),
|
||||
sess.target.target.options.dll_suffix.as_slice());
|
||||
out_filename.with_filename(format!("{}{}{}",
|
||||
prefix,
|
||||
libname,
|
||||
|
@ -477,15 +463,8 @@ pub fn filename_for_input(sess: &Session,
|
|||
out_filename.with_filename(format!("lib{}.a", libname))
|
||||
}
|
||||
config::CrateTypeExecutable => {
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsWindows => out_filename.with_extension("exe"),
|
||||
abi::OsMacos |
|
||||
abi::OsLinux |
|
||||
abi::OsAndroid |
|
||||
abi::OsFreebsd |
|
||||
abi::OsDragonfly |
|
||||
abi::OsiOS => out_filename.clone(),
|
||||
}
|
||||
let suffix = sess.target.target.options.exe_suffix.as_slice();
|
||||
out_filename.with_filename(format!("{}{}", libname, suffix))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,7 +541,8 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||
handler: handler,
|
||||
dst: out_filename.clone(),
|
||||
lib_search_paths: archive_search_paths(sess),
|
||||
os: sess.targ_cfg.os,
|
||||
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
|
||||
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
|
||||
maybe_ar_prog: sess.opts.cg.ar.clone()
|
||||
};
|
||||
let mut ab = ArchiveBuilder::create(config);
|
||||
|
@ -581,12 +561,12 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||
// symbol table of the archive.
|
||||
ab.update_symbols();
|
||||
|
||||
let mut ab = match sess.targ_cfg.os {
|
||||
let mut ab = match sess.target.target.options.is_like_osx {
|
||||
// For OSX/iOS, we must be careful to update symbols only when adding
|
||||
// object files. We're about to start adding non-object files, so run
|
||||
// `ar` now to process the object files.
|
||||
abi::OsMacos | abi::OsiOS => ab.build().extend(),
|
||||
_ => ab,
|
||||
true => ab.build().extend(),
|
||||
false => ab,
|
||||
};
|
||||
|
||||
// Note that it is important that we add all of our non-object "magical
|
||||
|
@ -686,6 +666,13 @@ fn link_rlib<'a>(sess: &'a Session,
|
|||
remove(sess, &bc_filename);
|
||||
}
|
||||
}
|
||||
|
||||
// After adding all files to the archive, we need to update the
|
||||
// symbol table of the archive. This currently dies on OSX (see
|
||||
// #11162), and isn't necessary there anyway
|
||||
if !sess.target.target.options.is_like_osx {
|
||||
ab.update_symbols();
|
||||
}
|
||||
}
|
||||
|
||||
None => {}
|
||||
|
@ -734,11 +721,13 @@ fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
|
|||
// metadata file).
|
||||
fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
|
||||
let ab = link_rlib(sess, None, obj_filename, out_filename);
|
||||
let mut ab = match sess.targ_cfg.os {
|
||||
abi::OsMacos | abi::OsiOS => ab.build().extend(),
|
||||
_ => ab,
|
||||
let mut ab = match sess.target.target.options.is_like_osx {
|
||||
true => ab.build().extend(),
|
||||
false => ab,
|
||||
};
|
||||
ab.add_native_library("morestack").unwrap();
|
||||
if sess.target.target.options.morestack {
|
||||
ab.add_native_library("morestack").unwrap();
|
||||
}
|
||||
ab.add_native_library("compiler-rt").unwrap();
|
||||
|
||||
let crates = sess.cstore.get_used_crates(cstore::RequireStatic);
|
||||
|
@ -791,9 +780,13 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
|
|||
let pname = get_cc_prog(sess);
|
||||
let mut cmd = Command::new(pname.as_slice());
|
||||
|
||||
cmd.args(sess.targ_cfg.target_strs.cc_args.as_slice());
|
||||
cmd.args(sess.target.target.options.pre_link_args.as_slice());
|
||||
link_args(&mut cmd, sess, dylib, tmpdir.path(),
|
||||
trans, obj_filename, out_filename);
|
||||
cmd.args(sess.target.target.options.post_link_args.as_slice());
|
||||
if !sess.target.target.options.no_compiler_rt {
|
||||
cmd.arg("-lcompiler-rt");
|
||||
}
|
||||
|
||||
if (sess.opts.debugging_opts & config::PRINT_LINK_ARGS) != 0 {
|
||||
println!("{}", &cmd);
|
||||
|
@ -831,16 +824,15 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
|
|||
|
||||
// On OSX, debuggers need this utility to get run to do some munging of
|
||||
// the symbols
|
||||
if (sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS)
|
||||
&& (sess.opts.debuginfo != NoDebugInfo) {
|
||||
match Command::new("dsymutil").arg(out_filename).output() {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
if sess.target.target.options.is_like_osx && sess.opts.debuginfo != NoDebugInfo {
|
||||
match Command::new("dsymutil").arg(out_filename).output() {
|
||||
Ok(..) => {}
|
||||
Err(e) => {
|
||||
sess.err(format!("failed to run dsymutil: {}", e).as_slice());
|
||||
sess.abort_if_errors();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn link_args(cmd: &mut Command,
|
||||
|
@ -854,10 +846,15 @@ fn link_args(cmd: &mut Command,
|
|||
// The default library location, we need this to find the runtime.
|
||||
// The location of crates will be determined as needed.
|
||||
let lib_path = sess.target_filesearch().get_lib_path();
|
||||
|
||||
// target descriptor
|
||||
let t = &sess.target.target;
|
||||
|
||||
cmd.arg("-L").arg(&lib_path);
|
||||
|
||||
cmd.arg("-o").arg(out_filename).arg(obj_filename);
|
||||
|
||||
|
||||
// Stack growth requires statically linking a __morestack function. Note
|
||||
// that this is listed *before* all other libraries. Due to the usage of the
|
||||
// --as-needed flag below, the standard library may only be useful for its
|
||||
|
@ -874,17 +871,15 @@ fn link_args(cmd: &mut Command,
|
|||
// all contents of this library. This way we're guaranteed that the linker
|
||||
// will include the __morestack symbol 100% of the time, always resolving
|
||||
// references to it even if the object above didn't use it.
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsMacos | abi::OsiOS => {
|
||||
if t.options.morestack {
|
||||
if t.options.is_like_osx {
|
||||
let morestack = lib_path.join("libmorestack.a");
|
||||
|
||||
let mut v = b"-Wl,-force_load,".to_vec();
|
||||
v.push_all(morestack.as_vec());
|
||||
cmd.arg(v.as_slice());
|
||||
}
|
||||
_ => {
|
||||
cmd.args(["-Wl,--whole-archive", "-lmorestack",
|
||||
"-Wl,--no-whole-archive"]);
|
||||
} else {
|
||||
cmd.args(["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -895,60 +890,10 @@ fn link_args(cmd: &mut Command,
|
|||
cmd.arg(obj_filename.with_extension("metadata.o"));
|
||||
}
|
||||
|
||||
// We want to prevent the compiler from accidentally leaking in any system
|
||||
// libraries, so we explicitly ask gcc to not link to any libraries by
|
||||
// default. Note that this does not happen for windows because windows pulls
|
||||
// in some large number of libraries and I couldn't quite figure out which
|
||||
// subset we wanted.
|
||||
//
|
||||
// FIXME(#11937) we should invoke the system linker directly
|
||||
if sess.targ_cfg.os != abi::OsWindows {
|
||||
cmd.arg("-nodefaultlibs");
|
||||
}
|
||||
|
||||
// Rust does its' own LTO
|
||||
cmd.arg("-fno-lto");
|
||||
|
||||
// clang fails hard if -fno-use-linker-plugin is passed
|
||||
if sess.targ_cfg.os == abi::OsWindows {
|
||||
cmd.arg("-fno-use-linker-plugin");
|
||||
}
|
||||
|
||||
// If we're building a dylib, we don't use --gc-sections because LLVM has
|
||||
// already done the best it can do, and we also don't want to eliminate the
|
||||
// metadata. If we're building an executable, however, --gc-sections drops
|
||||
// the size of hello world from 1.8MB to 597K, a 67% reduction.
|
||||
if !dylib && sess.targ_cfg.os != abi::OsMacos && sess.targ_cfg.os != abi::OsiOS {
|
||||
cmd.arg("-Wl,--gc-sections");
|
||||
}
|
||||
|
||||
let used_link_args = sess.cstore.get_used_link_args().borrow();
|
||||
|
||||
// Dynamically linked executables can be compiled as position independent if the default
|
||||
// relocation model of position independent code is not changed. This is a requirement to take
|
||||
// advantage of ASLR, as otherwise the functions in the executable are not randomized and can
|
||||
// be used during an exploit of a vulnerability in any code.
|
||||
if sess.targ_cfg.os == abi::OsLinux {
|
||||
let mut args = sess.opts.cg.link_args.iter().chain(used_link_args.iter());
|
||||
if !dylib && sess.opts.cg.relocation_model.as_slice() == "pic" &&
|
||||
!args.any(|x| x.as_slice() == "-static") {
|
||||
cmd.arg("-pie");
|
||||
}
|
||||
}
|
||||
|
||||
if sess.targ_cfg.os == abi::OsLinux || sess.targ_cfg.os == abi::OsDragonfly {
|
||||
// GNU-style linkers will use this to omit linking to libraries which
|
||||
// don't actually fulfill any relocations, but only for libraries which
|
||||
// follow this flag. Thus, use it before specifying libraries to link to.
|
||||
cmd.arg("-Wl,--as-needed");
|
||||
|
||||
// GNU-style linkers support optimization with -O. GNU ld doesn't need a
|
||||
// numeric argument, but other linkers do.
|
||||
if sess.opts.optimize == config::Default ||
|
||||
sess.opts.optimize == config::Aggressive {
|
||||
cmd.arg("-Wl,-O1");
|
||||
}
|
||||
} else if sess.targ_cfg.os == abi::OsMacos || sess.targ_cfg.os == abi::OsiOS {
|
||||
if t.options.is_like_osx {
|
||||
// The dead_strip option to the linker specifies that functions and data
|
||||
// unreachable by the entry point will be removed. This is quite useful
|
||||
// with Rust's compilation model of compiling libraries at a time into
|
||||
|
@ -959,67 +904,58 @@ fn link_args(cmd: &mut Command,
|
|||
// won't get much benefit from dylibs because LLVM will have already
|
||||
// stripped away as much as it could. This has not been seen to impact
|
||||
// link times negatively.
|
||||
//
|
||||
// -dead_strip can't be part of the pre_link_args because it's also used for partial
|
||||
// linking when using multiple codegen units (-r). So we insert it here.
|
||||
cmd.arg("-Wl,-dead_strip");
|
||||
}
|
||||
|
||||
if sess.targ_cfg.os == abi::OsWindows {
|
||||
if sess.targ_cfg.arch == abi::X86 {
|
||||
// Make sure that we link to the dynamic libgcc, otherwise cross-module
|
||||
// DWARF stack unwinding will not work.
|
||||
// This behavior may be overridden by -Clink-args="-static-libgcc"
|
||||
cmd.arg("-shared-libgcc");
|
||||
} else {
|
||||
// On Win64 unwinding is handled by the OS, so we can link libgcc statically.
|
||||
cmd.arg("-static-libgcc");
|
||||
}
|
||||
// If we're building a dylib, we don't use --gc-sections because LLVM has
|
||||
// already done the best it can do, and we also don't want to eliminate the
|
||||
// metadata. If we're building an executable, however, --gc-sections drops
|
||||
// the size of hello world from 1.8MB to 597K, a 67% reduction.
|
||||
if !dylib && !t.options.is_like_osx {
|
||||
cmd.arg("-Wl,--gc-sections");
|
||||
}
|
||||
|
||||
// And here, we see obscure linker flags #45. On windows, it has been
|
||||
// found to be necessary to have this flag to compile liblibc.
|
||||
//
|
||||
// First a bit of background. On Windows, the file format is not ELF,
|
||||
// but COFF (at least according to LLVM). COFF doesn't officially allow
|
||||
// for section names over 8 characters, apparently. Our metadata
|
||||
// section, ".note.rustc", you'll note is over 8 characters.
|
||||
//
|
||||
// On more recent versions of gcc on mingw, apparently the section name
|
||||
// is *not* truncated, but rather stored elsewhere in a separate lookup
|
||||
// table. On older versions of gcc, they apparently always truncated the
|
||||
// section names (at least in some cases). Truncating the section name
|
||||
// actually creates "invalid" objects [1] [2], but only for some
|
||||
// introspection tools, not in terms of whether it can be loaded.
|
||||
//
|
||||
// Long story short, passing this flag forces the linker to *not*
|
||||
// truncate section names (so we can find the metadata section after
|
||||
// it's compiled). The real kicker is that rust compiled just fine on
|
||||
// windows for quite a long time *without* this flag, so I have no idea
|
||||
// why it suddenly started failing for liblibc. Regardless, we
|
||||
// definitely don't want section name truncation, so we're keeping this
|
||||
// flag for windows.
|
||||
//
|
||||
// [1] - https://sourceware.org/bugzilla/show_bug.cgi?id=13130
|
||||
// [2] - https://code.google.com/p/go/issues/detail?id=2139
|
||||
cmd.arg("-Wl,--enable-long-section-names");
|
||||
let used_link_args = sess.cstore.get_used_link_args().borrow();
|
||||
|
||||
// Always enable DEP (NX bit) when it is available
|
||||
cmd.arg("-Wl,--nxcompat");
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with ASLR
|
||||
// FIXME #16514: ASLR is disabled on Windows due to MinGW-w64 bugs:
|
||||
// FIXME #17098: ASLR breaks gdb on Windows
|
||||
// FIXME #17684: ASLR breaks thread-local storage on Windows
|
||||
//cmd.arg("-Wl,--dynamicbase");
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
if sess.targ_cfg.arch == abi::X86 {
|
||||
cmd.arg("-Wl,--large-address-aware");
|
||||
if t.options.position_independant_executables {
|
||||
let empty_vec = Vec::new();
|
||||
let empty_str = String::new();
|
||||
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
|
||||
let mut args = args.iter().chain(used_link_args.iter());
|
||||
if !dylib
|
||||
&& (t.options.relocation_model.as_slice() == "pic"
|
||||
|| sess.opts.cg.relocation_model.as_ref()
|
||||
.unwrap_or(&empty_str).as_slice() == "pic")
|
||||
&& !args.any(|x| x.as_slice() == "-static") {
|
||||
cmd.arg("-pie");
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
cmd.arg("-Wl,--allow-multiple-definition");
|
||||
if t.options.linker_is_gnu {
|
||||
// GNU-style linkers support optimization with -O. GNU ld doesn't need a
|
||||
// numeric argument, but other linkers do.
|
||||
if sess.opts.optimize == config::Default ||
|
||||
sess.opts.optimize == config::Aggressive {
|
||||
cmd.arg("-Wl,-O1");
|
||||
}
|
||||
}
|
||||
|
||||
// We want to prevent the compiler from accidentally leaking in any system
|
||||
// libraries, so we explicitly ask gcc to not link to any libraries by
|
||||
// default. Note that this does not happen for windows because windows pulls
|
||||
// in some large number of libraries and I couldn't quite figure out which
|
||||
// subset we wanted.
|
||||
if !t.options.is_like_windows {
|
||||
cmd.arg("-nodefaultlibs");
|
||||
}
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with ASLR
|
||||
// FIXME #17098: ASLR breaks gdb
|
||||
if t.options.is_like_windows && sess.opts.debuginfo == NoDebugInfo {
|
||||
// cmd.arg("-Wl,--dynamicbase");
|
||||
}
|
||||
|
||||
// Take careful note of the ordering of the arguments we pass to the linker
|
||||
|
@ -1063,7 +999,7 @@ fn link_args(cmd: &mut Command,
|
|||
|
||||
if dylib {
|
||||
// On mac we need to tell the linker to let this library be rpathed
|
||||
if sess.targ_cfg.os == abi::OsMacos {
|
||||
if sess.target.target.options.is_like_osx {
|
||||
cmd.args(["-dynamiclib", "-Wl,-dylib"]);
|
||||
|
||||
if sess.opts.cg.rpath {
|
||||
|
@ -1076,18 +1012,6 @@ fn link_args(cmd: &mut Command,
|
|||
}
|
||||
}
|
||||
|
||||
if sess.targ_cfg.os == abi::OsFreebsd {
|
||||
cmd.args(["-L/usr/local/lib",
|
||||
"-L/usr/local/lib/gcc46",
|
||||
"-L/usr/local/lib/gcc44"]);
|
||||
}
|
||||
else if sess.targ_cfg.os == abi::OsDragonfly {
|
||||
cmd.args(["-L/usr/local/lib",
|
||||
"-L/usr/lib/gcc47",
|
||||
"-L/usr/lib/gcc44"]);
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
@ -1103,27 +1027,20 @@ fn link_args(cmd: &mut Command,
|
|||
path
|
||||
};
|
||||
let rpath_config = RPathConfig {
|
||||
os: sess.targ_cfg.os,
|
||||
used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
|
||||
out_filename: out_filename.clone(),
|
||||
has_rpath: sess.target.target.options.has_rpath,
|
||||
is_like_osx: sess.target.target.options.is_like_osx,
|
||||
get_install_prefix_lib_path: get_install_prefix_lib_path,
|
||||
realpath: ::util::fs::realpath
|
||||
};
|
||||
cmd.args(rpath::get_rpath_flags(rpath_config).as_slice());
|
||||
}
|
||||
|
||||
// compiler-rt contains implementations of low-level LLVM helpers. This is
|
||||
// used to resolve symbols from the object file we just created, as well as
|
||||
// any system static libraries that may be expecting gcc instead. Most
|
||||
// symbols in libgcc also appear in compiler-rt.
|
||||
//
|
||||
// This is the end of the command line, so this library is used to resolve
|
||||
// *all* undefined symbols in all other libraries, and this is intentional.
|
||||
cmd.arg("-lcompiler-rt");
|
||||
|
||||
// Finally add all the linker arguments provided on the command line along
|
||||
// with any #[link_args] attributes found inside the crate
|
||||
cmd.args(sess.opts.cg.link_args.as_slice());
|
||||
let empty = Vec::new();
|
||||
cmd.args(sess.opts.cg.link_args.as_ref().unwrap_or(&empty).as_slice());
|
||||
cmd.args(used_link_args.as_slice());
|
||||
}
|
||||
|
||||
|
@ -1152,8 +1069,7 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||
// For those that support this, we ensure we pass the option if the library
|
||||
// was flagged "static" (most defaults are dynamic) to ensure that if
|
||||
// libfoo.a and libfoo.so both exist that the right one is chosen.
|
||||
let takes_hints = sess.targ_cfg.os != abi::OsMacos &&
|
||||
sess.targ_cfg.os != abi::OsiOS;
|
||||
let takes_hints = !sess.target.target.options.is_like_osx;
|
||||
|
||||
let libs = sess.cstore.get_used_libraries();
|
||||
let libs = libs.borrow();
|
||||
|
@ -1184,7 +1100,8 @@ fn add_local_native_libraries(cmd: &mut Command, sess: &Session) {
|
|||
// -force_load is the OSX equivalent of --whole-archive, but it
|
||||
// involves passing the full path to the library to link.
|
||||
let lib = archive::find_library(l.as_slice(),
|
||||
sess.targ_cfg.os,
|
||||
sess.target.target.options.staticlib_prefix.as_slice(),
|
||||
sess.target.target.options.staticlib_suffix.as_slice(),
|
||||
search_path.as_slice(),
|
||||
&sess.diagnostic().handler);
|
||||
let mut v = b"-Wl,-force_load,".to_vec();
|
||||
|
@ -1257,7 +1174,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||
|
||||
// Converts a library file-stem into a cc -l argument
|
||||
fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] {
|
||||
if stem.starts_with("lib".as_bytes()) && config.os != abi::OsWindows {
|
||||
if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows {
|
||||
stem[3..]
|
||||
} else {
|
||||
stem
|
||||
|
@ -1315,7 +1232,8 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||
handler: handler,
|
||||
dst: dst.clone(),
|
||||
lib_search_paths: archive_search_paths(sess),
|
||||
os: sess.targ_cfg.os,
|
||||
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
|
||||
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
|
||||
maybe_ar_prog: sess.opts.cg.ar.clone()
|
||||
};
|
||||
let mut archive = Archive::open(config);
|
||||
|
@ -1342,7 +1260,7 @@ fn add_upstream_rust_crates(cmd: &mut Command, sess: &Session,
|
|||
if !dir.is_empty() { cmd.arg("-L").arg(dir); }
|
||||
|
||||
let mut v = "-l".as_bytes().to_vec();
|
||||
v.push_all(unlib(&sess.targ_cfg, cratepath.filestem().unwrap()));
|
||||
v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
|
||||
cmd.arg(v.as_slice());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ use llvm;
|
|||
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef};
|
||||
use llvm::SMDiagnosticRef;
|
||||
use util::common::time;
|
||||
use syntax::abi;
|
||||
use syntax::codemap;
|
||||
use syntax::diagnostic;
|
||||
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
|
||||
|
@ -150,20 +149,8 @@ impl Emitter for SharedEmitter {
|
|||
// Note that without those flags various linking errors might
|
||||
// arise as some of intrinsics are converted into function calls
|
||||
// and nobody provides implementations those functions
|
||||
fn target_feature<'a>(sess: &'a Session) -> &'a str {
|
||||
match sess.targ_cfg.os {
|
||||
abi::OsAndroid => {
|
||||
if "" == sess.opts.cg.target_feature.as_slice() {
|
||||
"+v7"
|
||||
} else {
|
||||
sess.opts.cg.target_feature.as_slice()
|
||||
}
|
||||
},
|
||||
abi::OsiOS if sess.targ_cfg.arch == abi::Arm => {
|
||||
"+v7,+thumb2,+vfp3,+neon"
|
||||
},
|
||||
_ => sess.opts.cg.target_feature.as_slice()
|
||||
}
|
||||
fn target_feature(sess: &Session) -> String {
|
||||
format!("{},{}", sess.target.target.options.features, sess.opts.cg.target_feature)
|
||||
}
|
||||
|
||||
fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
|
||||
|
@ -176,7 +163,11 @@ fn get_llvm_opt_level(optimize: config::OptLevel) -> llvm::CodeGenOptLevel {
|
|||
}
|
||||
|
||||
fn create_target_machine(sess: &Session) -> TargetMachineRef {
|
||||
let reloc_model = match sess.opts.cg.relocation_model.as_slice() {
|
||||
let reloc_model_arg = match sess.opts.cg.relocation_model {
|
||||
Some(ref s) => s.as_slice(),
|
||||
None => sess.target.target.options.relocation_model.as_slice()
|
||||
};
|
||||
let reloc_model = match reloc_model_arg {
|
||||
"pic" => llvm::RelocPIC,
|
||||
"static" => llvm::RelocStatic,
|
||||
"default" => llvm::RelocDefault,
|
||||
|
@ -195,22 +186,22 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
|
|||
let use_softfp = sess.opts.cg.soft_float;
|
||||
|
||||
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a parameter.
|
||||
// FIXME: #11954: mac64 unwinding may not work with fp elim
|
||||
let no_fp_elim = (sess.opts.debuginfo != NoDebugInfo) ||
|
||||
(sess.targ_cfg.os == abi::OsMacos &&
|
||||
sess.targ_cfg.arch == abi::X86_64);
|
||||
!sess.target.target.options.eliminate_frame_pointer;
|
||||
|
||||
let any_library = sess.crate_types.borrow().iter().any(|ty| {
|
||||
*ty != config::CrateTypeExecutable
|
||||
});
|
||||
|
||||
// OSX has -dead_strip, which doesn't rely on ffunction_sections
|
||||
// FIXME(#13846) this should be enabled for windows
|
||||
let ffunction_sections = sess.targ_cfg.os != abi::OsMacos &&
|
||||
sess.targ_cfg.os != abi::OsWindows;
|
||||
let ffunction_sections = sess.target.target.options.function_sections;
|
||||
let fdata_sections = ffunction_sections;
|
||||
|
||||
let code_model = match sess.opts.cg.code_model.as_slice() {
|
||||
let code_model_arg = match sess.opts.cg.code_model {
|
||||
Some(ref s) => s.as_slice(),
|
||||
None => sess.target.target.options.code_model.as_slice()
|
||||
};
|
||||
|
||||
let code_model = match code_model_arg {
|
||||
"default" => llvm::CodeModelDefault,
|
||||
"small" => llvm::CodeModelSmall,
|
||||
"kernel" => llvm::CodeModelKernel,
|
||||
|
@ -226,11 +217,15 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
|
|||
}
|
||||
};
|
||||
|
||||
let triple = sess.targ_cfg.target_strs.target_triple.as_slice();
|
||||
let triple = sess.target.target.llvm_target.as_slice();
|
||||
|
||||
let tm = unsafe {
|
||||
triple.with_c_str(|t| {
|
||||
sess.opts.cg.target_cpu.as_slice().with_c_str(|cpu| {
|
||||
triple.with_c_str(|t| {
|
||||
let cpu = match sess.opts.cg.target_cpu {
|
||||
Some(ref s) => s.as_slice(),
|
||||
None => sess.target.target.options.cpu.as_slice()
|
||||
};
|
||||
cpu.with_c_str(|cpu| {
|
||||
target_feature(sess).with_c_str(|features| {
|
||||
llvm::LLVMRustCreateTargetMachine(
|
||||
t, cpu, features,
|
||||
|
@ -692,7 +687,7 @@ pub fn run_passes(sess: &Session,
|
|||
// the desired path. This will give the correct behavior whether or
|
||||
// not GCC adds --force-exe-suffix.
|
||||
let windows_output_path =
|
||||
if sess.targ_cfg.os == abi::OsWindows {
|
||||
if sess.target.target.options.is_like_windows {
|
||||
Some(output_path.with_extension("o.exe"))
|
||||
} else {
|
||||
None
|
||||
|
@ -701,7 +696,7 @@ pub fn run_passes(sess: &Session,
|
|||
let pname = get_cc_prog(sess);
|
||||
let mut cmd = Command::new(pname.as_slice());
|
||||
|
||||
cmd.args(sess.targ_cfg.target_strs.cc_args.as_slice());
|
||||
cmd.args(sess.target.target.options.pre_link_args.as_slice());
|
||||
cmd.arg("-nostdlib");
|
||||
|
||||
for index in range(0, trans.modules.len()) {
|
||||
|
@ -712,6 +707,8 @@ pub fn run_passes(sess: &Session,
|
|||
.arg("-o")
|
||||
.arg(windows_output_path.as_ref().unwrap_or(output_path));
|
||||
|
||||
cmd.args(sess.target.target.options.post_link_args.as_slice());
|
||||
|
||||
if (sess.opts.debugging_opts & config::PRINT_LINK_ARGS) != 0 {
|
||||
println!("{}", &cmd);
|
||||
}
|
||||
|
|
|
@ -17,17 +17,15 @@ use driver::session::Session;
|
|||
|
||||
use back;
|
||||
use back::write;
|
||||
use back::target_strs;
|
||||
use back::{arm, x86, x86_64, mips, mipsel};
|
||||
use rustc_back::target::Target;
|
||||
use lint;
|
||||
use metadata::cstore;
|
||||
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::ast::{IntTy, UintTy};
|
||||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::diagnostic::{ColorConfig, Auto, Always, Never};
|
||||
use syntax::diagnostic::{ColorConfig, Auto, Always, Never, SpanHandler};
|
||||
use syntax::parse;
|
||||
use syntax::parse::token::InternedString;
|
||||
|
||||
|
@ -41,9 +39,7 @@ use std::fmt;
|
|||
use llvm;
|
||||
|
||||
pub struct Config {
|
||||
pub os: abi::Os,
|
||||
pub arch: abi::Architecture,
|
||||
pub target_strs: target_strs::t,
|
||||
pub target: Target,
|
||||
pub int_type: IntTy,
|
||||
pub uint_type: UintTy,
|
||||
}
|
||||
|
@ -291,6 +287,13 @@ macro_rules! cgoptions(
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some(..) => false,
|
||||
None => { *slot = Some(true); true }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
Some(s) => { *slot = Some(s.to_string()); true },
|
||||
|
@ -318,6 +321,18 @@ macro_rules! cgoptions(
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
|
||||
-> bool {
|
||||
match v {
|
||||
Some(s) => {
|
||||
let v = s.words().map(|s| s.to_string()).collect();
|
||||
*slot = Some(v);
|
||||
true
|
||||
},
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_uint(slot: &mut uint, v: Option<&str>) -> bool {
|
||||
use std::from_str::FromStr;
|
||||
match v.and_then(FromStr::from_str) {
|
||||
|
@ -351,11 +366,11 @@ cgoptions!(
|
|||
"tool to assemble archives with"),
|
||||
linker: Option<String> = (None, parse_opt_string,
|
||||
"system linker to link outputs with"),
|
||||
link_args: Vec<String> = (Vec::new(), parse_list,
|
||||
link_args: Option<Vec<String>> = (None, parse_opt_list,
|
||||
"extra arguments to pass to the linker (space separated)"),
|
||||
lto: bool = (false, parse_bool,
|
||||
"perform LLVM link-time optimizations"),
|
||||
target_cpu: String = ("generic".to_string(), parse_string,
|
||||
target_cpu: Option<String> = (None, parse_opt_string,
|
||||
"select target processor (llc -mcpu=help for details)"),
|
||||
target_feature: String = ("".to_string(), parse_string,
|
||||
"target specific attributes (llc -mattr=help for details)"),
|
||||
|
@ -379,11 +394,11 @@ cgoptions!(
|
|||
"prefer dynamic linking to static linking"),
|
||||
no_integrated_as: bool = (false, parse_bool,
|
||||
"use an external assembler rather than LLVM's integrated one"),
|
||||
no_redzone: bool = (false, parse_bool,
|
||||
no_redzone: Option<bool> = (None, parse_opt_bool,
|
||||
"disable the use of the redzone"),
|
||||
relocation_model: String = ("pic".to_string(), parse_string,
|
||||
relocation_model: Option<String> = (None, parse_opt_string,
|
||||
"choose the relocation model to use (llc -relocation-model for details)"),
|
||||
code_model: String = ("default".to_string(), parse_string,
|
||||
code_model: Option<String> = (None, parse_opt_string,
|
||||
"choose the code model to use (llc -code-model for details)"),
|
||||
metadata: Vec<String> = (Vec::new(), parse_list,
|
||||
"metadata to mangle symbol names with"),
|
||||
|
@ -437,40 +452,27 @@ pub fn default_lib_output() -> CrateType {
|
|||
}
|
||||
|
||||
pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
|
||||
let tos = match sess.targ_cfg.os {
|
||||
abi::OsWindows => InternedString::new("windows"),
|
||||
abi::OsMacos => InternedString::new("macos"),
|
||||
abi::OsLinux => InternedString::new("linux"),
|
||||
abi::OsAndroid => InternedString::new("android"),
|
||||
abi::OsFreebsd => InternedString::new("freebsd"),
|
||||
abi::OsDragonfly => InternedString::new("dragonfly"),
|
||||
abi::OsiOS => InternedString::new("ios"),
|
||||
};
|
||||
use syntax::parse::token::intern_and_get_ident as intern;
|
||||
|
||||
// ARM is bi-endian, however using NDK seems to default
|
||||
// to little-endian unless a flag is provided.
|
||||
let (end,arch,wordsz) = match sess.targ_cfg.arch {
|
||||
abi::X86 => ("little", "x86", "32"),
|
||||
abi::X86_64 => ("little", "x86_64", "64"),
|
||||
abi::Arm => ("little", "arm", "32"),
|
||||
abi::Mips => ("big", "mips", "32"),
|
||||
abi::Mipsel => ("little", "mipsel", "32")
|
||||
};
|
||||
let end = sess.target.target.target_endian.as_slice();
|
||||
let arch = sess.target.target.arch.as_slice();
|
||||
let wordsz = sess.target.target.target_word_size.as_slice();
|
||||
let os = sess.target.target.target_os.as_slice();
|
||||
|
||||
let fam = match sess.targ_cfg.os {
|
||||
abi::OsWindows => InternedString::new("windows"),
|
||||
_ => InternedString::new("unix")
|
||||
let fam = match sess.target.target.options.is_like_windows {
|
||||
true => InternedString::new("windows"),
|
||||
false => InternedString::new("unix")
|
||||
};
|
||||
|
||||
let mk = attr::mk_name_value_item_str;
|
||||
return vec!(// Target bindings.
|
||||
attr::mk_word_item(fam.clone()),
|
||||
mk(InternedString::new("target_os"), tos),
|
||||
mk(InternedString::new("target_os"), intern(os)),
|
||||
mk(InternedString::new("target_family"), fam),
|
||||
mk(InternedString::new("target_arch"), InternedString::new(arch)),
|
||||
mk(InternedString::new("target_endian"), InternedString::new(end)),
|
||||
mk(InternedString::new("target_arch"), intern(arch)),
|
||||
mk(InternedString::new("target_endian"), intern(end)),
|
||||
mk(InternedString::new("target_word_size"),
|
||||
InternedString::new(wordsz))
|
||||
intern(wordsz))
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -495,78 +497,23 @@ pub fn build_configuration(sess: &Session) -> ast::CrateConfig {
|
|||
v
|
||||
}
|
||||
|
||||
pub fn get_os(triple: &str) -> Option<abi::Os> {
|
||||
for &(name, os) in os_names.iter() {
|
||||
if triple.contains(name) { return Some(os) }
|
||||
pub fn build_target_config(opts: &Options, sp: &SpanHandler) -> Config {
|
||||
let target = match Target::search(opts.target_triple.as_slice()) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
sp.handler().fatal((format!("Error loading target specification: {}", e)).as_slice());
|
||||
}
|
||||
None
|
||||
}
|
||||
#[allow(non_upper_case_globals)]
|
||||
static os_names : &'static [(&'static str, abi::Os)] = &[
|
||||
("mingw32", abi::OsWindows),
|
||||
("win32", abi::OsWindows),
|
||||
("windows", abi::OsWindows),
|
||||
("darwin", abi::OsMacos),
|
||||
("android", abi::OsAndroid),
|
||||
("linux", abi::OsLinux),
|
||||
("freebsd", abi::OsFreebsd),
|
||||
("dragonfly", abi::OsDragonfly),
|
||||
("ios", abi::OsiOS)];
|
||||
|
||||
pub fn get_arch(triple: &str) -> Option<abi::Architecture> {
|
||||
for &(arch, abi) in architecture_abis.iter() {
|
||||
if triple.contains(arch) { return Some(abi) }
|
||||
}
|
||||
None
|
||||
}
|
||||
#[allow(non_upper_case_globals)]
|
||||
static architecture_abis : &'static [(&'static str, abi::Architecture)] = &[
|
||||
("i386", abi::X86),
|
||||
("i486", abi::X86),
|
||||
("i586", abi::X86),
|
||||
("i686", abi::X86),
|
||||
("i786", abi::X86),
|
||||
|
||||
("x86_64", abi::X86_64),
|
||||
|
||||
("arm", abi::Arm),
|
||||
("xscale", abi::Arm),
|
||||
("thumb", abi::Arm),
|
||||
|
||||
("mipsel", abi::Mipsel),
|
||||
("mips", abi::Mips)];
|
||||
|
||||
pub fn build_target_config(sopts: &Options) -> Config {
|
||||
let os = match get_os(sopts.target_triple.as_slice()) {
|
||||
Some(os) => os,
|
||||
None => early_error("unknown operating system")
|
||||
};
|
||||
let arch = match get_arch(sopts.target_triple.as_slice()) {
|
||||
Some(arch) => arch,
|
||||
None => {
|
||||
early_error(format!("unknown architecture: {}",
|
||||
sopts.target_triple.as_slice()).as_slice())
|
||||
}
|
||||
};
|
||||
let (int_type, uint_type) = match arch {
|
||||
abi::X86 => (ast::TyI32, ast::TyU32),
|
||||
abi::X86_64 => (ast::TyI64, ast::TyU64),
|
||||
abi::Arm => (ast::TyI32, ast::TyU32),
|
||||
abi::Mips => (ast::TyI32, ast::TyU32),
|
||||
abi::Mipsel => (ast::TyI32, ast::TyU32)
|
||||
};
|
||||
let target_triple = sopts.target_triple.clone();
|
||||
let target_strs = match arch {
|
||||
abi::X86 => x86::get_target_strs(target_triple, os),
|
||||
abi::X86_64 => x86_64::get_target_strs(target_triple, os),
|
||||
abi::Arm => arm::get_target_strs(target_triple, os),
|
||||
abi::Mips => mips::get_target_strs(target_triple, os),
|
||||
abi::Mipsel => mipsel::get_target_strs(target_triple, os)
|
||||
|
||||
let (int_type, uint_type) = match target.target_word_size.as_slice() {
|
||||
"32" => (ast::TyI32, ast::TyU32),
|
||||
"64" => (ast::TyI64, ast::TyU64),
|
||||
w => sp.handler().fatal((format!("target specification was invalid: unrecognized \
|
||||
target-word-size {}", w)).as_slice())
|
||||
};
|
||||
|
||||
Config {
|
||||
os: os,
|
||||
arch: arch,
|
||||
target_strs: target_strs,
|
||||
target: target,
|
||||
int_type: int_type,
|
||||
uint_type: uint_type,
|
||||
}
|
||||
|
|
|
@ -749,8 +749,8 @@ pub fn collect_crate_types(session: &Session,
|
|||
|
||||
if !res {
|
||||
session.warn(format!("dropping unsupported crate type `{}` \
|
||||
for target os `{}`",
|
||||
*crate_type, session.targ_cfg.os).as_slice());
|
||||
for target `{}`",
|
||||
*crate_type, session.opts.target_triple).as_slice());
|
||||
}
|
||||
|
||||
res
|
||||
|
|
|
@ -435,7 +435,7 @@ pub fn early_warn(msg: &str) {
|
|||
|
||||
pub fn list_metadata(sess: &Session, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
metadata::loader::list_file_metadata(sess.targ_cfg.os, path, out)
|
||||
metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx, path, out)
|
||||
}
|
||||
|
||||
/// Run a procedure which will detect failures in the compiler and print nicer
|
||||
|
|
|
@ -32,7 +32,7 @@ use std::cell::{Cell, RefCell};
|
|||
// Represents the data associated with a compilation
|
||||
// session for a single crate.
|
||||
pub struct Session {
|
||||
pub targ_cfg: config::Config,
|
||||
pub target: config::Config,
|
||||
pub opts: config::Options,
|
||||
pub cstore: CStore,
|
||||
pub parse_sess: ParseSess,
|
||||
|
@ -219,7 +219,7 @@ pub fn build_session_(sopts: config::Options,
|
|||
local_crate_source_file: Option<Path>,
|
||||
span_diagnostic: diagnostic::SpanHandler)
|
||||
-> Session {
|
||||
let target_cfg = config::build_target_config(&sopts);
|
||||
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
|
||||
let p_s = parse::new_parse_sess_special_handler(span_diagnostic);
|
||||
let default_sysroot = match sopts.maybe_sysroot {
|
||||
Some(_) => None,
|
||||
|
@ -236,7 +236,7 @@ pub fn build_session_(sopts: config::Options,
|
|||
);
|
||||
|
||||
let sess = Session {
|
||||
targ_cfg: target_cfg,
|
||||
target: target_cfg,
|
||||
opts: sopts,
|
||||
cstore: CStore::new(token::get_ident_interner()),
|
||||
parse_sess: p_s,
|
||||
|
|
|
@ -210,7 +210,7 @@ impl LintPass for TypeLimits {
|
|||
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
|
||||
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
|
||||
let int_type = if t == ast::TyI {
|
||||
cx.sess().targ_cfg.int_type
|
||||
cx.sess().target.int_type
|
||||
} else { t };
|
||||
let (min, max) = int_ty_range(int_type);
|
||||
let negative = self.negated_expr_id == e.id;
|
||||
|
@ -227,7 +227,7 @@ impl LintPass for TypeLimits {
|
|||
},
|
||||
ty::ty_uint(t) => {
|
||||
let uint_type = if t == ast::TyU {
|
||||
cx.sess().targ_cfg.uint_type
|
||||
cx.sess().target.uint_type
|
||||
} else { t };
|
||||
let (min, max) = uint_ty_range(uint_type);
|
||||
let lit_val: u64 = match lit.node {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
use back::svh::Svh;
|
||||
use driver::session::Session;
|
||||
use driver::{driver, config};
|
||||
use driver::driver;
|
||||
use metadata::cstore;
|
||||
use metadata::cstore::{CStore, CrateSource};
|
||||
use metadata::decoder;
|
||||
|
@ -237,6 +237,9 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||
Some(k) => {
|
||||
if k.equiv(&("static")) {
|
||||
cstore::NativeStatic
|
||||
} else if e.sess.target.target.options.is_like_osx
|
||||
&& k.equiv(&("framework")) {
|
||||
cstore::NativeFramework
|
||||
} else if k.equiv(&("framework")) {
|
||||
cstore::NativeFramework
|
||||
} else {
|
||||
|
@ -285,8 +288,7 @@ fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
|
|||
}
|
||||
return
|
||||
}
|
||||
let is_osx = sess.targ_cfg.os == abi::OsMacos ||
|
||||
sess.targ_cfg.os == abi::OsiOS;
|
||||
let is_osx = sess.target.target.options.is_like_osx;
|
||||
if kind == cstore::NativeFramework && !is_osx {
|
||||
let msg = "native frameworks are only available on OSX targets";
|
||||
match span {
|
||||
|
@ -400,8 +402,7 @@ fn resolve_crate<'a>(e: &mut Env,
|
|||
crate_name: name,
|
||||
hash: hash.map(|a| &*a),
|
||||
filesearch: e.sess.target_filesearch(),
|
||||
os: e.sess.targ_cfg.os,
|
||||
triple: e.sess.targ_cfg.target_strs.target_triple.as_slice(),
|
||||
triple: e.sess.opts.target_triple.as_slice(),
|
||||
root: root,
|
||||
rejected_via_hash: vec!(),
|
||||
rejected_via_triple: vec!(),
|
||||
|
@ -451,10 +452,9 @@ impl<'a> PluginMetadataReader<'a> {
|
|||
|
||||
pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata {
|
||||
let info = extract_crate_info(&self.env, krate).unwrap();
|
||||
let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice();
|
||||
let target_triple = self.env.sess.opts.target_triple.as_slice();
|
||||
let is_cross = target_triple != driver::host_triple();
|
||||
let mut should_link = info.should_link && !is_cross;
|
||||
let os = config::get_os(driver::host_triple()).unwrap();
|
||||
let mut load_ctxt = loader::Context {
|
||||
sess: self.env.sess,
|
||||
span: krate.span,
|
||||
|
@ -463,7 +463,6 @@ impl<'a> PluginMetadataReader<'a> {
|
|||
hash: None,
|
||||
filesearch: self.env.sess.host_filesearch(),
|
||||
triple: driver::host_triple(),
|
||||
os: os,
|
||||
root: &None,
|
||||
rejected_via_hash: vec!(),
|
||||
rejected_via_triple: vec!(),
|
||||
|
@ -475,7 +474,6 @@ impl<'a> PluginMetadataReader<'a> {
|
|||
// try loading from target crates (only valid if there are
|
||||
// no syntax extensions)
|
||||
load_ctxt.triple = target_triple;
|
||||
load_ctxt.os = self.env.sess.targ_cfg.os;
|
||||
load_ctxt.filesearch = self.env.sess.target_filesearch();
|
||||
let lib = load_ctxt.load_library_crate();
|
||||
if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
|
||||
|
|
|
@ -2071,8 +2071,7 @@ fn encode_metadata_inner(wr: &mut SeekableMemWriter, parms: EncodeParams, krate:
|
|||
encode_crate_name(&mut rbml_w, ecx.link_meta.crate_name.as_slice());
|
||||
encode_crate_triple(&mut rbml_w,
|
||||
tcx.sess
|
||||
.targ_cfg
|
||||
.target_strs
|
||||
.opts
|
||||
.target_triple
|
||||
.as_slice());
|
||||
encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);
|
||||
|
|
|
@ -222,7 +222,6 @@ use metadata::cstore::{MetadataBlob, MetadataVec, MetadataArchive};
|
|||
use metadata::decoder;
|
||||
use metadata::encoder;
|
||||
use metadata::filesearch::{FileSearch, FileMatches, FileDoesntMatch};
|
||||
use syntax::abi;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use util::fs;
|
||||
|
@ -240,24 +239,6 @@ use std::collections::hash_map::{Occupied, Vacant};
|
|||
use flate;
|
||||
use time;
|
||||
|
||||
pub const MACOS_DLL_PREFIX: &'static str = "lib";
|
||||
pub const MACOS_DLL_SUFFIX: &'static str = ".dylib";
|
||||
|
||||
pub const WIN32_DLL_PREFIX: &'static str = "";
|
||||
pub const WIN32_DLL_SUFFIX: &'static str = ".dll";
|
||||
|
||||
pub const LINUX_DLL_PREFIX: &'static str = "lib";
|
||||
pub const LINUX_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub const FREEBSD_DLL_PREFIX: &'static str = "lib";
|
||||
pub const FREEBSD_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub const DRAGONFLY_DLL_PREFIX: &'static str = "lib";
|
||||
pub const DRAGONFLY_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub const ANDROID_DLL_PREFIX: &'static str = "lib";
|
||||
pub const ANDROID_DLL_SUFFIX: &'static str = ".so";
|
||||
|
||||
pub struct CrateMismatch {
|
||||
path: Path,
|
||||
got: String,
|
||||
|
@ -270,7 +251,6 @@ pub struct Context<'a> {
|
|||
pub crate_name: &'a str,
|
||||
pub hash: Option<&'a Svh>,
|
||||
pub triple: &'a str,
|
||||
pub os: abi::Os,
|
||||
pub filesearch: FileSearch<'a>,
|
||||
pub root: &'a Option<CratePaths>,
|
||||
pub rejected_via_hash: Vec<CrateMismatch>,
|
||||
|
@ -387,9 +367,7 @@ impl<'a> Context<'a> {
|
|||
let dypair = self.dylibname();
|
||||
|
||||
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||
let dylib_prefix = dypair.map(|(prefix, _)| {
|
||||
format!("{}{}", prefix, self.crate_name)
|
||||
});
|
||||
let dylib_prefix = format!("{}{}", dypair.ref0(), self.crate_name);
|
||||
let rlib_prefix = format!("lib{}", self.crate_name);
|
||||
|
||||
let mut candidates = HashMap::new();
|
||||
|
@ -416,13 +394,9 @@ impl<'a> Context<'a> {
|
|||
file.ends_with(".rlib") {
|
||||
(file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
|
||||
true)
|
||||
} else if dypair.map_or(false, |(_, suffix)| {
|
||||
file.starts_with(dylib_prefix.as_ref().unwrap().as_slice()) &&
|
||||
file.ends_with(suffix)
|
||||
}) {
|
||||
let (_, suffix) = dypair.unwrap();
|
||||
let dylib_prefix = dylib_prefix.as_ref().unwrap().as_slice();
|
||||
(file.slice(dylib_prefix.len(), file.len() - suffix.len()),
|
||||
} else if file.starts_with(dylib_prefix.as_slice()) &&
|
||||
file.ends_with(dypair.ref1().as_slice()) {
|
||||
(file.slice(dylib_prefix.len(), file.len() - dypair.ref1().len()),
|
||||
false)
|
||||
} else {
|
||||
return FileDoesntMatch
|
||||
|
@ -530,7 +504,8 @@ impl<'a> Context<'a> {
|
|||
|
||||
for lib in m.into_iter() {
|
||||
info!("{} reading metadata from: {}", flavor, lib.display());
|
||||
let metadata = match get_metadata_section(self.os, &lib) {
|
||||
let metadata = match get_metadata_section(self.sess.target.target.options.is_like_osx,
|
||||
&lib) {
|
||||
Ok(blob) => {
|
||||
if self.crate_matches(blob.as_slice(), &lib) {
|
||||
blob
|
||||
|
@ -617,16 +592,9 @@ impl<'a> Context<'a> {
|
|||
|
||||
// Returns the corresponding (prefix, suffix) that files need to have for
|
||||
// dynamic libraries
|
||||
fn dylibname(&self) -> Option<(&'static str, &'static str)> {
|
||||
match self.os {
|
||||
abi::OsWindows => Some((WIN32_DLL_PREFIX, WIN32_DLL_SUFFIX)),
|
||||
abi::OsMacos => Some((MACOS_DLL_PREFIX, MACOS_DLL_SUFFIX)),
|
||||
abi::OsLinux => Some((LINUX_DLL_PREFIX, LINUX_DLL_SUFFIX)),
|
||||
abi::OsAndroid => Some((ANDROID_DLL_PREFIX, ANDROID_DLL_SUFFIX)),
|
||||
abi::OsFreebsd => Some((FREEBSD_DLL_PREFIX, FREEBSD_DLL_SUFFIX)),
|
||||
abi::OsDragonfly => Some((DRAGONFLY_DLL_PREFIX, DRAGONFLY_DLL_SUFFIX)),
|
||||
abi::OsiOS => None,
|
||||
}
|
||||
fn dylibname(&self) -> (String, String) {
|
||||
let t = &self.sess.target.target;
|
||||
(t.options.dll_prefix.clone(), t.options.dll_suffix.clone())
|
||||
}
|
||||
|
||||
fn find_commandline_library(&mut self) -> Option<Library> {
|
||||
|
@ -660,13 +628,9 @@ impl<'a> Context<'a> {
|
|||
if file.starts_with("lib") && file.ends_with(".rlib") {
|
||||
return true
|
||||
} else {
|
||||
match dylibname {
|
||||
Some((prefix, suffix)) => {
|
||||
if file.starts_with(prefix) && file.ends_with(suffix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
let (ref prefix, ref suffix) = dylibname;
|
||||
if file.starts_with(prefix.as_slice()) && file.ends_with(suffix.as_slice()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
sess.err(format!("extern location for {} is of an unknown type: {}",
|
||||
|
@ -726,15 +690,15 @@ impl ArchiveMetadata {
|
|||
}
|
||||
|
||||
// Just a small wrapper to time how long reading metadata takes.
|
||||
fn get_metadata_section(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
fn get_metadata_section(is_osx: bool, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
let start = time::precise_time_ns();
|
||||
let ret = get_metadata_section_imp(os, filename);
|
||||
let ret = get_metadata_section_imp(is_osx, filename);
|
||||
info!("reading {} => {}ms", filename.filename_display(),
|
||||
(time::precise_time_ns() - start) / 1000000);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlob, String> {
|
||||
if !filename.exists() {
|
||||
return Err(format!("no such file: '{}'", filename.display()));
|
||||
}
|
||||
|
@ -780,7 +744,7 @@ fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob
|
|||
let name = string::raw::from_buf_len(name_buf as *const u8,
|
||||
name_len as uint);
|
||||
debug!("get_metadata_section: name {}", name);
|
||||
if read_meta_section_name(os).as_slice() == name.as_slice() {
|
||||
if read_meta_section_name(is_osx).as_slice() == name.as_slice() {
|
||||
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
|
||||
let csz = llvm::LLVMGetSectionSize(si.llsi) as uint;
|
||||
let mut found =
|
||||
|
@ -821,34 +785,26 @@ fn get_metadata_section_imp(os: abi::Os, filename: &Path) -> Result<MetadataBlob
|
|||
}
|
||||
}
|
||||
|
||||
pub fn meta_section_name(os: abi::Os) -> Option<&'static str> {
|
||||
match os {
|
||||
abi::OsMacos => Some("__DATA,__note.rustc"),
|
||||
abi::OsiOS => Some("__DATA,__note.rustc"),
|
||||
abi::OsWindows => Some(".note.rustc"),
|
||||
abi::OsLinux => Some(".note.rustc"),
|
||||
abi::OsAndroid => Some(".note.rustc"),
|
||||
abi::OsFreebsd => Some(".note.rustc"),
|
||||
abi::OsDragonfly => Some(".note.rustc"),
|
||||
pub fn meta_section_name(is_osx: bool) -> &'static str {
|
||||
if is_osx {
|
||||
"__DATA,__note.rustc"
|
||||
} else {
|
||||
".note.rustc"
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_meta_section_name(os: abi::Os) -> &'static str {
|
||||
match os {
|
||||
abi::OsMacos => "__note.rustc",
|
||||
abi::OsiOS => unreachable!(),
|
||||
abi::OsWindows => ".note.rustc",
|
||||
abi::OsLinux => ".note.rustc",
|
||||
abi::OsAndroid => ".note.rustc",
|
||||
abi::OsFreebsd => ".note.rustc",
|
||||
abi::OsDragonfly => ".note.rustc"
|
||||
pub fn read_meta_section_name(is_osx: bool) -> &'static str {
|
||||
if is_osx {
|
||||
"__note.rustc"
|
||||
} else {
|
||||
".note.rustc"
|
||||
}
|
||||
}
|
||||
|
||||
// A diagnostic function for dumping crate metadata to an output stream
|
||||
pub fn list_file_metadata(os: abi::Os, path: &Path,
|
||||
pub fn list_file_metadata(is_osx: bool, path: &Path,
|
||||
out: &mut io::Writer) -> io::IoResult<()> {
|
||||
match get_metadata_section(os, path) {
|
||||
match get_metadata_section(is_osx, path) {
|
||||
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
|
||||
Err(msg) => {
|
||||
write!(out, "{}\n", msg)
|
||||
|
|
|
@ -135,13 +135,13 @@ fn calculate_type(sess: &session::Session,
|
|||
sess.cstore.iter_crate_data(|cnum, data| {
|
||||
let src = sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||
if src.dylib.is_some() {
|
||||
add_library(sess, cnum, cstore::RequireDynamic, &mut formats);
|
||||
debug!("adding dylib: {}", data.name);
|
||||
add_library(sess, cnum, cstore::RequireDynamic, &mut formats);
|
||||
let deps = csearch::get_dylib_dependency_formats(&sess.cstore, cnum);
|
||||
for &(depnum, style) in deps.iter() {
|
||||
add_library(sess, depnum, style, &mut formats);
|
||||
debug!("adding {}: {}", style,
|
||||
sess.cstore.get_crate_data(depnum).name.clone());
|
||||
add_library(sess, depnum, style, &mut formats);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -160,9 +160,9 @@ fn calculate_type(sess: &session::Session,
|
|||
let src = sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||
if src.dylib.is_none() && !formats.contains_key(&cnum) {
|
||||
assert!(src.rlib.is_some());
|
||||
debug!("adding staticlib: {}", data.name);
|
||||
add_library(sess, cnum, cstore::RequireStatic, &mut formats);
|
||||
ret[cnum as uint - 1] = Some(cstore::RequireStatic);
|
||||
debug!("adding staticlib: {}", data.name);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ use middle::trans::type_::Type;
|
|||
use middle::trans::type_of;
|
||||
use middle::ty;
|
||||
use middle::ty::Disr;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
|
||||
use syntax::ast;
|
||||
use syntax::attr;
|
||||
use syntax::attr::IntType;
|
||||
|
@ -410,14 +409,12 @@ fn range_to_inttype(cx: &CrateContext, hint: Hint, bounds: &IntBounds) -> IntTyp
|
|||
return ity;
|
||||
}
|
||||
attr::ReprExtern => {
|
||||
attempts = match cx.sess().targ_cfg.arch {
|
||||
X86 | X86_64 => at_least_32,
|
||||
attempts = match cx.sess().target.target.arch.as_slice() {
|
||||
// WARNING: the ARM EABI has two variants; the one corresponding to `at_least_32`
|
||||
// appears to be used on Linux and NetBSD, but some systems may use the variant
|
||||
// corresponding to `choose_shortest`. However, we don't run on those yet...?
|
||||
Arm => at_least_32,
|
||||
Mips => at_least_32,
|
||||
Mipsel => at_least_32,
|
||||
"arm" => at_least_32,
|
||||
_ => at_least_32,
|
||||
}
|
||||
}
|
||||
attr::ReprAny => {
|
||||
|
|
|
@ -87,8 +87,7 @@ use std::cell::{Cell, RefCell};
|
|||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
use std::{i8, i16, i32, i64};
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustCall};
|
||||
use syntax::abi::{RustIntrinsic, Abi, OsWindows};
|
||||
use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
|
||||
use syntax::ast_util::local_def;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
|
@ -193,7 +192,8 @@ pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
|
|||
llvm::SetFunctionAttribute(llfn, llvm::NoReturnAttribute);
|
||||
}
|
||||
|
||||
if ccx.tcx().sess.opts.cg.no_redzone {
|
||||
if ccx.tcx().sess.opts.cg.no_redzone
|
||||
.unwrap_or(ccx.tcx().sess.target.target.options.disable_redzone) {
|
||||
llvm::SetFunctionAttribute(llfn, llvm::NoRedZoneAttribute)
|
||||
}
|
||||
|
||||
|
@ -934,17 +934,16 @@ pub fn trans_external_path(ccx: &CrateContext, did: ast::DefId, t: ty::t) -> Val
|
|||
let name = csearch::get_symbol(&ccx.sess().cstore, did);
|
||||
match ty::get(t).sty {
|
||||
ty::ty_bare_fn(ref fn_ty) => {
|
||||
match fn_ty.abi.for_target(ccx.sess().targ_cfg.os,
|
||||
ccx.sess().targ_cfg.arch) {
|
||||
Some(Rust) | Some(RustCall) => {
|
||||
match ccx.sess().target.target.adjust_abi(fn_ty.abi) {
|
||||
Rust | RustCall => {
|
||||
get_extern_rust_fn(ccx, t, name.as_slice(), did)
|
||||
}
|
||||
Some(RustIntrinsic) => {
|
||||
RustIntrinsic => {
|
||||
ccx.sess().bug("unexpected intrinsic in trans_external_path")
|
||||
}
|
||||
Some(..) | None => {
|
||||
_ => {
|
||||
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
|
||||
name.as_slice(), None)
|
||||
name.as_slice())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1143,9 +1142,10 @@ pub fn call_lifetime_end(cx: Block, ptr: ValueRef) {
|
|||
pub fn call_memcpy(cx: Block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) {
|
||||
let _icx = push_ctxt("call_memcpy");
|
||||
let ccx = cx.ccx();
|
||||
let key = match ccx.sess().targ_cfg.arch {
|
||||
X86 | Arm | Mips | Mipsel => "llvm.memcpy.p0i8.p0i8.i32",
|
||||
X86_64 => "llvm.memcpy.p0i8.p0i8.i64"
|
||||
let key = match ccx.sess().target.target.target_word_size.as_slice() {
|
||||
"32" => "llvm.memcpy.p0i8.p0i8.i32",
|
||||
"64" => "llvm.memcpy.p0i8.p0i8.i64",
|
||||
tws => panic!("Unsupported target word size for memcpy: {}", tws),
|
||||
};
|
||||
let memcpy = ccx.get_intrinsic(&key);
|
||||
let src_ptr = PointerCast(cx, src, Type::i8p(ccx));
|
||||
|
@ -1187,9 +1187,10 @@ fn memzero(b: &Builder, llptr: ValueRef, ty: ty::t) {
|
|||
|
||||
let llty = type_of::type_of(ccx, ty);
|
||||
|
||||
let intrinsic_key = match ccx.sess().targ_cfg.arch {
|
||||
X86 | Arm | Mips | Mipsel => "llvm.memset.p0i8.i32",
|
||||
X86_64 => "llvm.memset.p0i8.i64"
|
||||
let intrinsic_key = match ccx.sess().target.target.target_word_size.as_slice() {
|
||||
"32" => "llvm.memset.p0i8.i32",
|
||||
"64" => "llvm.memset.p0i8.i64",
|
||||
tws => panic!("Unsupported target word size for memset: {}", tws),
|
||||
};
|
||||
|
||||
let llintrinsicfn = ccx.get_intrinsic(&intrinsic_key);
|
||||
|
@ -2583,7 +2584,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext,
|
|||
|
||||
// FIXME: #16581: Marking a symbol in the executable with `dllexport`
|
||||
// linkage forces MinGW's linker to output a `.reloc` section for ASLR
|
||||
if ccx.sess().targ_cfg.os == OsWindows {
|
||||
if ccx.sess().target.target.options.is_like_windows {
|
||||
unsafe { llvm::LLVMRustSetDLLExportStorageClass(llfn) }
|
||||
}
|
||||
|
||||
|
@ -2803,9 +2804,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
|
|||
let abi = ccx.tcx().map.get_foreign_abi(id);
|
||||
let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
|
||||
let name = foreign::link_name(&*ni);
|
||||
foreign::register_foreign_item_fn(ccx, abi, ty,
|
||||
name.get().as_slice(),
|
||||
Some(ni.span))
|
||||
foreign::register_foreign_item_fn(ccx, abi, ty, name.get().as_slice())
|
||||
}
|
||||
ast::ForeignItemStatic(..) => {
|
||||
foreign::register_static(ccx, &*ni)
|
||||
|
@ -2946,8 +2945,8 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
|
|||
});
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
let name = loader::meta_section_name(cx.sess().targ_cfg.os);
|
||||
name.unwrap_or("rust_metadata").with_c_str(|buf| {
|
||||
let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx);
|
||||
name.with_c_str(|buf| {
|
||||
llvm::LLVMSetSection(llglobal, buf)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17,8 +17,6 @@ use middle::trans::cabi_x86_win64;
|
|||
use middle::trans::cabi_arm;
|
||||
use middle::trans::cabi_mips;
|
||||
use middle::trans::type_::Type;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
|
||||
use syntax::abi::{OsWindows};
|
||||
|
||||
#[deriving(Clone, PartialEq)]
|
||||
pub enum ArgKind {
|
||||
|
@ -107,16 +105,16 @@ pub fn compute_abi_info(ccx: &CrateContext,
|
|||
atys: &[Type],
|
||||
rty: Type,
|
||||
ret_def: bool) -> FnType {
|
||||
match ccx.sess().targ_cfg.arch {
|
||||
X86 => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
X86_64 =>
|
||||
if ccx.sess().targ_cfg.os == OsWindows {
|
||||
cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
|
||||
} else {
|
||||
cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
|
||||
},
|
||||
Arm => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
Mips => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
Mipsel => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
match ccx.sess().target.target.arch.as_slice() {
|
||||
"x86" => cabi_x86::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
"x86_64" => if ccx.sess().target.target.options.is_like_windows {
|
||||
cabi_x86_win64::compute_abi_info(ccx, atys, rty, ret_def)
|
||||
} else {
|
||||
cabi_x86_64::compute_abi_info(ccx, atys, rty, ret_def)
|
||||
},
|
||||
"arm" => cabi_arm::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
|
||||
a => ccx.sess().fatal((format!("unrecognized arch \"{}\" in target specification", a))
|
||||
.as_slice()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ use middle::trans::cabi::{ArgType, FnType};
|
|||
use middle::trans::type_::Type;
|
||||
use super::common::*;
|
||||
use super::machine::*;
|
||||
use syntax::abi::{OsWindows, OsMacos, OsiOS};
|
||||
|
||||
pub fn compute_abi_info(ccx: &CrateContext,
|
||||
atys: &[Type],
|
||||
|
@ -34,19 +33,17 @@ pub fn compute_abi_info(ccx: &CrateContext,
|
|||
// Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp
|
||||
|
||||
enum Strategy { RetValue(Type), RetPointer }
|
||||
let strategy = match ccx.sess().targ_cfg.os {
|
||||
OsWindows | OsMacos | OsiOS => {
|
||||
match llsize_of_alloc(ccx, rty) {
|
||||
1 => RetValue(Type::i8(ccx)),
|
||||
2 => RetValue(Type::i16(ccx)),
|
||||
4 => RetValue(Type::i32(ccx)),
|
||||
8 => RetValue(Type::i64(ccx)),
|
||||
_ => RetPointer
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
RetPointer
|
||||
let t = &ccx.sess().target.target;
|
||||
let strategy = if t.options.is_like_osx || t.options.is_like_windows {
|
||||
match llsize_of_alloc(ccx, rty) {
|
||||
1 => RetValue(Type::i8(ccx)),
|
||||
2 => RetValue(Type::i16(ccx)),
|
||||
4 => RetValue(Type::i32(ccx)),
|
||||
8 => RetValue(Type::i64(ccx)),
|
||||
_ => RetPointer
|
||||
}
|
||||
} else {
|
||||
RetPointer
|
||||
};
|
||||
|
||||
match strategy {
|
||||
|
|
|
@ -34,7 +34,6 @@ use std::c_str::ToCStr;
|
|||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::InternedString;
|
||||
|
||||
|
@ -220,16 +219,16 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
|
|||
let llmod = mod_name.with_c_str(|buf| {
|
||||
llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
|
||||
});
|
||||
sess.targ_cfg
|
||||
.target_strs
|
||||
sess.target
|
||||
.target
|
||||
.data_layout
|
||||
.as_slice()
|
||||
.with_c_str(|buf| {
|
||||
llvm::LLVMSetDataLayout(llmod, buf);
|
||||
});
|
||||
sess.targ_cfg
|
||||
.target_strs
|
||||
.target_triple
|
||||
sess.target
|
||||
.target
|
||||
.llvm_target
|
||||
.as_slice()
|
||||
.with_c_str(|buf| {
|
||||
llvm::LLVMRustSetNormalizedTarget(llmod, buf);
|
||||
|
@ -378,8 +377,8 @@ impl LocalCrateContext {
|
|||
|
||||
let td = mk_target_data(shared.tcx
|
||||
.sess
|
||||
.targ_cfg
|
||||
.target_strs
|
||||
.target
|
||||
.target
|
||||
.data_layout
|
||||
.as_slice());
|
||||
|
||||
|
@ -531,16 +530,8 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Although there is an experimental implementation of LLVM which
|
||||
// supports SS on armv7 it wasn't approved by Apple, see:
|
||||
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
|
||||
// It looks like it might be never accepted to upstream LLVM.
|
||||
//
|
||||
// So far the decision was to disable them in default builds
|
||||
// but it could be enabled (with patched LLVM)
|
||||
pub fn is_split_stack_supported(&self) -> bool {
|
||||
let ref cfg = self.sess().targ_cfg;
|
||||
(cfg.os != abi::OsiOS || cfg.arch != abi::Arm) && cfg.os != abi::OsWindows
|
||||
self.sess().target.target.options.morestack
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ use std::ptr;
|
|||
use std::rc::{Rc, Weak};
|
||||
use syntax::util::interner::Interner;
|
||||
use syntax::codemap::{Span, Pos};
|
||||
use syntax::{abi, ast, codemap, ast_util, ast_map};
|
||||
use syntax::{ast, codemap, ast_util, ast_map};
|
||||
use syntax::ast_util::PostExpansionMethod;
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::special_idents;
|
||||
|
@ -750,8 +750,7 @@ pub fn finalize(cx: &CrateContext) {
|
|||
// instruct LLVM to emit an older version of dwarf, however,
|
||||
// for OS X to understand. For more info see #11352
|
||||
// This can be overridden using --llvm-opts -dwarf-version,N.
|
||||
if cx.sess().targ_cfg.os == abi::OsMacos ||
|
||||
cx.sess().targ_cfg.os == abi::OsiOS {
|
||||
if cx.sess().target.target.options.is_like_osx {
|
||||
"Dwarf Version".with_c_str(
|
||||
|s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 2));
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ use syntax::parse::token::{InternedString, special_idents};
|
|||
use syntax::parse::token;
|
||||
use syntax::{ast};
|
||||
use syntax::{attr, ast_map};
|
||||
use util::ppaux::{Repr, UserString};
|
||||
use util::ppaux::Repr;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Type definitions
|
||||
|
@ -70,39 +70,35 @@ struct LlvmSignature {
|
|||
// Calls to external functions
|
||||
|
||||
pub fn llvm_calling_convention(ccx: &CrateContext,
|
||||
abi: Abi) -> Option<CallConv> {
|
||||
let os = ccx.sess().targ_cfg.os;
|
||||
let arch = ccx.sess().targ_cfg.arch;
|
||||
abi.for_target(os, arch).map(|abi| {
|
||||
match abi {
|
||||
RustIntrinsic => {
|
||||
// Intrinsics are emitted at the call site
|
||||
ccx.sess().bug("asked to register intrinsic fn");
|
||||
}
|
||||
|
||||
Rust => {
|
||||
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
|
||||
ccx.sess().unimpl("foreign functions with Rust ABI");
|
||||
}
|
||||
|
||||
RustCall => {
|
||||
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
|
||||
ccx.sess().unimpl("foreign functions with RustCall ABI");
|
||||
}
|
||||
|
||||
// It's the ABI's job to select this, not us.
|
||||
System => ccx.sess().bug("system abi should be selected elsewhere"),
|
||||
|
||||
Stdcall => llvm::X86StdcallCallConv,
|
||||
Fastcall => llvm::X86FastcallCallConv,
|
||||
C => llvm::CCallConv,
|
||||
Win64 => llvm::X86_64_Win64,
|
||||
|
||||
// These API constants ought to be more specific...
|
||||
Cdecl => llvm::CCallConv,
|
||||
Aapcs => llvm::CCallConv,
|
||||
abi: Abi) -> CallConv {
|
||||
match ccx.sess().target.target.adjust_abi(abi) {
|
||||
RustIntrinsic => {
|
||||
// Intrinsics are emitted at the call site
|
||||
ccx.sess().bug("asked to register intrinsic fn");
|
||||
}
|
||||
})
|
||||
|
||||
Rust => {
|
||||
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
|
||||
ccx.sess().unimpl("foreign functions with Rust ABI");
|
||||
}
|
||||
|
||||
RustCall => {
|
||||
// FIXME(#3678) Implement linking to foreign fns with Rust ABI
|
||||
ccx.sess().unimpl("foreign functions with RustCall ABI");
|
||||
}
|
||||
|
||||
// It's the ABI's job to select this, not us.
|
||||
System => ccx.sess().bug("system abi should be selected elsewhere"),
|
||||
|
||||
Stdcall => llvm::X86StdcallCallConv,
|
||||
Fastcall => llvm::X86FastcallCallConv,
|
||||
C => llvm::CCallConv,
|
||||
Win64 => llvm::X86_64_Win64,
|
||||
|
||||
// These API constants ought to be more specific...
|
||||
Cdecl => llvm::CCallConv,
|
||||
Aapcs => llvm::CCallConv,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn llvm_linkage_by_name(name: &str) -> Option<Linkage> {
|
||||
|
@ -191,7 +187,7 @@ pub fn register_static(ccx: &CrateContext,
|
|||
}
|
||||
|
||||
pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, fty: ty::t,
|
||||
name: &str, span: Option<Span>) -> ValueRef {
|
||||
name: &str) -> ValueRef {
|
||||
/*!
|
||||
* Registers a foreign function found in a library.
|
||||
* Just adds a LLVM global.
|
||||
|
@ -204,25 +200,7 @@ pub fn register_foreign_item_fn(ccx: &CrateContext, abi: Abi, fty: ty::t,
|
|||
fty.repr(ccx.tcx()),
|
||||
name);
|
||||
|
||||
let cc = match llvm_calling_convention(ccx, abi) {
|
||||
Some(cc) => cc,
|
||||
None => {
|
||||
match span {
|
||||
Some(s) => {
|
||||
ccx.sess().span_fatal(s,
|
||||
format!("ABI `{}` has no suitable calling convention \
|
||||
for target architecture",
|
||||
abi.user_string(ccx.tcx())).as_slice())
|
||||
}
|
||||
None => {
|
||||
ccx.sess().fatal(
|
||||
format!("ABI `{}` has no suitable calling convention \
|
||||
for target architecture",
|
||||
abi.user_string(ccx.tcx())).as_slice())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let cc = llvm_calling_convention(ccx, abi);
|
||||
|
||||
// Register the function as a C extern fn
|
||||
let tys = foreign_types_for_fn_ty(ccx, fty);
|
||||
|
@ -375,16 +353,7 @@ pub fn trans_native_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
llargs_foreign.push(llarg_foreign);
|
||||
}
|
||||
|
||||
let cc = match llvm_calling_convention(ccx, fn_abi) {
|
||||
Some(cc) => cc,
|
||||
None => {
|
||||
// FIXME(#8357) We really ought to report a span here
|
||||
ccx.sess().fatal(
|
||||
format!("ABI string `{}` has no suitable ABI \
|
||||
for target architecture",
|
||||
fn_abi.user_string(ccx.tcx())).as_slice());
|
||||
}
|
||||
};
|
||||
let cc = llvm_calling_convention(ccx, fn_abi);
|
||||
|
||||
// A function pointer is called without the declaration available, so we have to apply
|
||||
// any attributes with ABI implications directly to the call instruction.
|
||||
|
@ -498,8 +467,7 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
|
|||
abi => {
|
||||
let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
|
||||
register_foreign_item_fn(ccx, abi, ty,
|
||||
lname.get().as_slice(),
|
||||
Some(foreign_item.span));
|
||||
lname.get().as_slice());
|
||||
// Unlike for other items, we shouldn't call
|
||||
// `base::update_linkage` here. Foreign items have
|
||||
// special linkage requirements, which are handled
|
||||
|
@ -548,8 +516,7 @@ pub fn decl_rust_fn_with_foreign_abi(ccx: &CrateContext,
|
|||
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
|
||||
let cconv = match ty::get(t).sty {
|
||||
ty::ty_bare_fn(ref fn_ty) => {
|
||||
let c = llvm_calling_convention(ccx, fn_ty.abi);
|
||||
c.unwrap_or(llvm::CCallConv)
|
||||
llvm_calling_convention(ccx, fn_ty.abi)
|
||||
}
|
||||
_ => panic!("expected bare fn in decl_rust_fn_with_foreign_abi")
|
||||
};
|
||||
|
@ -572,8 +539,7 @@ pub fn register_rust_fn_with_foreign_abi(ccx: &CrateContext,
|
|||
let t = ty::node_id_to_type(ccx.tcx(), node_id);
|
||||
let cconv = match ty::get(t).sty {
|
||||
ty::ty_bare_fn(ref fn_ty) => {
|
||||
let c = llvm_calling_convention(ccx, fn_ty.abi);
|
||||
c.unwrap_or(llvm::CCallConv)
|
||||
llvm_calling_convention(ccx, fn_ty.abi)
|
||||
}
|
||||
_ => panic!("expected bare fn in register_rust_fn_with_foreign_abi")
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@ use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
|||
use middle::trans::context::CrateContext;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel};
|
||||
|
||||
use std::c_str::ToCStr;
|
||||
use std::mem;
|
||||
|
@ -105,9 +104,10 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn int(ccx: &CrateContext) -> Type {
|
||||
match ccx.tcx().sess.targ_cfg.arch {
|
||||
X86 | Arm | Mips | Mipsel => Type::i32(ccx),
|
||||
X86_64 => Type::i64(ccx)
|
||||
match ccx.tcx().sess.target.target.target_word_size.as_slice() {
|
||||
"32" => Type::i32(ccx),
|
||||
"64" => Type::i64(ccx),
|
||||
tws => panic!("Unsupported target word size for int: {}", tws),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4840,7 +4840,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
ast::TyU16 => disr as u16 as Disr == disr,
|
||||
ast::TyU32 => disr as u32 as Disr == disr,
|
||||
ast::TyU64 => disr as u64 as Disr == disr,
|
||||
ast::TyU => uint_in_range(ccx, ccx.tcx.sess.targ_cfg.uint_type, disr)
|
||||
ast::TyU => uint_in_range(ccx, ccx.tcx.sess.target.uint_type, disr)
|
||||
}
|
||||
}
|
||||
fn int_in_range(ccx: &CrateCtxt, ty: ast::IntTy, disr: ty::Disr) -> bool {
|
||||
|
@ -4849,7 +4849,7 @@ pub fn check_enum_variants(ccx: &CrateCtxt,
|
|||
ast::TyI16 => disr as i16 as Disr == disr,
|
||||
ast::TyI32 => disr as i32 as Disr == disr,
|
||||
ast::TyI64 => disr as i64 as Disr == disr,
|
||||
ast::TyI => int_in_range(ccx, ccx.tcx.sess.targ_cfg.int_type, disr)
|
||||
ast::TyI => int_in_range(ccx, ccx.tcx.sess.target.int_type, disr)
|
||||
}
|
||||
}
|
||||
match ty {
|
||||
|
|
|
@ -16,7 +16,6 @@ use std::io::{fs, TempDir};
|
|||
use std::io;
|
||||
use std::os;
|
||||
use std::str;
|
||||
use syntax::abi;
|
||||
use syntax::diagnostic::Handler as ErrorHandler;
|
||||
|
||||
pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
|
||||
|
@ -25,7 +24,8 @@ pub struct ArchiveConfig<'a> {
|
|||
pub handler: &'a ErrorHandler,
|
||||
pub dst: Path,
|
||||
pub lib_search_paths: Vec<Path>,
|
||||
pub os: abi::Os,
|
||||
pub slib_prefix: String,
|
||||
pub slib_suffix: String,
|
||||
pub maybe_ar_prog: Option<String>
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,8 @@ pub struct Archive<'a> {
|
|||
handler: &'a ErrorHandler,
|
||||
dst: Path,
|
||||
lib_search_paths: Vec<Path>,
|
||||
os: abi::Os,
|
||||
slib_prefix: String,
|
||||
slib_suffix: String,
|
||||
maybe_ar_prog: Option<String>
|
||||
}
|
||||
|
||||
|
@ -96,14 +97,11 @@ fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_library(name: &str, os: abi::Os, search_paths: &[Path],
|
||||
handler: &ErrorHandler) -> Path {
|
||||
let (osprefix, osext) = match os {
|
||||
abi::OsWindows => ("", "lib"), _ => ("lib", "a"),
|
||||
};
|
||||
pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
|
||||
search_paths: &[Path], handler: &ErrorHandler) -> Path {
|
||||
// On Windows, static libraries sometimes show up as libfoo.a and other
|
||||
// times show up as foo.lib
|
||||
let oslibname = format!("{}{}.{}", osprefix, name, osext);
|
||||
let oslibname = format!("{}{}{}", osprefix, name, ossuffix);
|
||||
let unixlibname = format!("lib{}.a", name);
|
||||
|
||||
for path in search_paths.iter() {
|
||||
|
@ -122,12 +120,14 @@ pub fn find_library(name: &str, os: abi::Os, search_paths: &[Path],
|
|||
|
||||
impl<'a> Archive<'a> {
|
||||
fn new(config: ArchiveConfig<'a>) -> Archive<'a> {
|
||||
let ArchiveConfig { handler, dst, lib_search_paths, os, maybe_ar_prog } = config;
|
||||
let ArchiveConfig { handler, dst, lib_search_paths, slib_prefix, slib_suffix,
|
||||
maybe_ar_prog } = config;
|
||||
Archive {
|
||||
handler: handler,
|
||||
dst: dst,
|
||||
lib_search_paths: lib_search_paths,
|
||||
os: os,
|
||||
slib_prefix: slib_prefix,
|
||||
slib_suffix: slib_suffix,
|
||||
maybe_ar_prog: maybe_ar_prog
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +178,9 @@ impl<'a> ArchiveBuilder<'a> {
|
|||
/// Adds all of the contents of a native library to this archive. This will
|
||||
/// search in the relevant locations for a library named `name`.
|
||||
pub fn add_native_library(&mut self, name: &str) -> io::IoResult<()> {
|
||||
let location = find_library(name, self.archive.os,
|
||||
let location = find_library(name,
|
||||
self.archive.slib_prefix.as_slice(),
|
||||
self.archive.slib_suffix.as_slice(),
|
||||
self.archive.lib_search_paths.as_slice(),
|
||||
self.archive.handler);
|
||||
self.add_archive(&location, name, [])
|
||||
|
|
|
@ -51,3 +51,4 @@ pub mod svh;
|
|||
pub mod target_strs;
|
||||
pub mod x86;
|
||||
pub mod x86_64;
|
||||
pub mod target;
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
use std::collections::HashSet;
|
||||
use std::os;
|
||||
use std::io::IoError;
|
||||
use syntax::abi;
|
||||
use syntax::ast;
|
||||
|
||||
pub struct RPathConfig<'a> {
|
||||
pub os: abi::Os,
|
||||
pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
|
||||
pub out_filename: Path,
|
||||
pub is_like_osx: bool,
|
||||
pub has_rpath: bool,
|
||||
pub get_install_prefix_lib_path: ||:'a -> Path,
|
||||
pub realpath: |&Path|:'a -> Result<Path, IoError>
|
||||
}
|
||||
|
@ -26,24 +26,12 @@ pub struct RPathConfig<'a> {
|
|||
pub fn get_rpath_flags(config: RPathConfig) -> Vec<String> {
|
||||
|
||||
// No rpath on windows
|
||||
if config.os == abi::OsWindows {
|
||||
if !config.has_rpath {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
let mut flags = Vec::new();
|
||||
|
||||
if config.os == abi::OsFreebsd {
|
||||
flags.push_all(["-Wl,-rpath,/usr/local/lib/gcc46".to_string(),
|
||||
"-Wl,-rpath,/usr/local/lib/gcc44".to_string(),
|
||||
"-Wl,-z,origin".to_string()]);
|
||||
}
|
||||
else if config.os == abi::OsDragonfly {
|
||||
flags.push_all(["-Wl,-rpath,/usr/lib/gcc47".to_string(),
|
||||
"-Wl,-rpath,/usr/lib/gcc44".to_string(),
|
||||
"-Wl,-z,origin".to_string()]);
|
||||
}
|
||||
|
||||
|
||||
debug!("preparing the RPATH!");
|
||||
|
||||
let libs = config.used_crates.clone();
|
||||
|
@ -107,14 +95,11 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
|
|||
lib: &Path) -> String {
|
||||
use std::os;
|
||||
|
||||
assert!(config.os != abi::OsWindows);
|
||||
|
||||
// Mac doesn't appear to support $ORIGIN
|
||||
let prefix = match config.os {
|
||||
abi::OsAndroid | abi::OsLinux | abi::OsFreebsd | abi::OsDragonfly
|
||||
=> "$ORIGIN",
|
||||
abi::OsMacos => "@loader_path",
|
||||
abi::OsWindows | abi::OsiOS => unreachable!()
|
||||
let prefix = if config.is_like_osx {
|
||||
"@loader_path"
|
||||
} else {
|
||||
"$ORIGIN"
|
||||
};
|
||||
|
||||
let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
|
||||
|
@ -203,10 +188,11 @@ mod test {
|
|||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
fn test_rpath_relative() {
|
||||
let config = &mut RPathConfig {
|
||||
os: abi::OsLinux,
|
||||
used_crates: Vec::new(),
|
||||
out_filename: Path::new("bin/rustc"),
|
||||
get_install_prefix_lib_path: || panic!(),
|
||||
has_rpath: true,
|
||||
is_like_osx: false,
|
||||
realpath: |p| Ok(p.clone())
|
||||
};
|
||||
let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
|
||||
|
@ -217,8 +203,9 @@ mod test {
|
|||
#[cfg(target_os = "freebsd")]
|
||||
fn test_rpath_relative() {
|
||||
let config = &mut RPathConfig {
|
||||
os: abi::OsFreebsd,
|
||||
used_crates: Vec::new(),
|
||||
has_rpath: true,
|
||||
is_like_osx: false,
|
||||
out_filename: Path::new("bin/rustc"),
|
||||
get_install_prefix_lib_path: || panic!(),
|
||||
realpath: |p| Ok(p.clone())
|
||||
|
@ -231,8 +218,9 @@ mod test {
|
|||
#[cfg(target_os = "dragonfly")]
|
||||
fn test_rpath_relative() {
|
||||
let config = &mut RPathConfig {
|
||||
os: abi::OsDragonfly,
|
||||
used_crates: Vec::new(),
|
||||
has_rpath: true,
|
||||
is_like_osx: false,
|
||||
out_filename: Path::new("bin/rustc"),
|
||||
get_install_prefix_lib_path: || panic!(),
|
||||
realpath: |p| Ok(p.clone())
|
||||
|
@ -245,8 +233,9 @@ mod test {
|
|||
#[cfg(target_os = "macos")]
|
||||
fn test_rpath_relative() {
|
||||
let config = &mut RPathConfig {
|
||||
os: abi::OsMacos,
|
||||
used_crates: Vec::new(),
|
||||
has_rpath: true,
|
||||
is_like_osx: true,
|
||||
out_filename: Path::new("bin/rustc"),
|
||||
get_install_prefix_lib_path: || panic!(),
|
||||
realpath: |p| Ok(p.clone())
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
// OSX has -dead_strip, which doesn't rely on ffunction_sections
|
||||
function_sections: false,
|
||||
linker: "cc".to_string(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
is_like_osx: true,
|
||||
morestack: true,
|
||||
has_rpath: true,
|
||||
dll_prefix: "lib".to_string(),
|
||||
dll_suffix: ".dylib".to_string(),
|
||||
pre_link_args: Vec::new(),
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::{Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "arm-apple-ios".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "ios".to_string(),
|
||||
options: TargetOptions {
|
||||
features: "+v7,+thumb2,+vfp3,+neon".to_string(),
|
||||
executables: false,
|
||||
dynamic_linking: false,
|
||||
// Although there is an experimental implementation of LLVM which
|
||||
// supports SS on armv7 it wasn't approved by Apple, see:
|
||||
// http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20140505/216350.html
|
||||
// It looks like it might be never accepted to upstream LLVM.
|
||||
morestack: false,
|
||||
.. super::apple_base::opts()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::linux_base::opts();
|
||||
base.features = "+v7".to_string();
|
||||
// Many of the symbols defined in compiler-rt are also defined in libgcc. Android
|
||||
// linker doesn't like that by default.
|
||||
base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "arm-linux-androideabi".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "android".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::{Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let base = super::linux_base::opts();
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "arm-unknown-linux-gnueabi".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
|
||||
options: TargetOptions {
|
||||
features: "+v6".to_string(),
|
||||
.. base
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::{Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let base = super::linux_base::opts();
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "arm-unknown-linux-gnueabi".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "arm".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
|
||||
options: TargetOptions {
|
||||
features: "+v6,+vfp2".to_string(),
|
||||
.. base
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
linker: "cc".to_string(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
morestack: true,
|
||||
has_rpath: true,
|
||||
pre_link_args: vec!(
|
||||
"-L/usr/local/lib".to_string(),
|
||||
"-L/usr/local/lib/gcc47".to_string(),
|
||||
"-L/usr/local/lib/gcc44".to_string(),
|
||||
),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
linker: "cc".to_string(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
morestack: true,
|
||||
has_rpath: true,
|
||||
pre_link_args: vec!(
|
||||
"-L/usr/local/lib".to_string(),
|
||||
"-L/usr/local/lib/gcc46".to_string(),
|
||||
"-L/usr/local/lib/gcc44".to_string(),
|
||||
),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
|
||||
-i32:32:32-i64:32:64\
|
||||
-f32:32:32-f64:32:64-v64:64:64\
|
||||
-v128:128:128-a0:0:64-f80:128:128\
|
||||
-n8:16:32".to_string(),
|
||||
llvm_target: "i386-apple-ios".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86".to_string(),
|
||||
target_os: "ios".to_string(),
|
||||
|
||||
options: super::apple_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16\
|
||||
-i32:32:32-i64:32:64\
|
||||
-f32:32:32-f64:32:64-v64:64:64\
|
||||
-v128:128:128-a0:0:64-f80:128:128\
|
||||
-n8:16:32".to_string(),
|
||||
llvm_target: "i686-apple-darwin".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86".to_string(),
|
||||
target_os: "macos".to_string(),
|
||||
|
||||
options: super::apple_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = super::windows_base::opts();
|
||||
|
||||
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address
|
||||
// space available to x86 Windows binaries on x86_64.
|
||||
options.pre_link_args.push("-Wl,--large-address-aware".to_string());
|
||||
|
||||
// Make sure that we link to the dynamic libgcc, otherwise cross-module
|
||||
// DWARF stack unwinding will not work.
|
||||
// This behavior may be overridden by -Clink-args="-static-libgcc"
|
||||
options.pre_link_args.push("-shared-libgcc".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32".to_string(),
|
||||
llvm_target: "i686-pc-windows-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86".to_string(),
|
||||
target_os: "windows".to_string(),
|
||||
options: options,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string(),
|
||||
llvm_target: "i686-unknown-dragonfly".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86".to_string(),
|
||||
target_os: "dragonfly".to_string(),
|
||||
options: super::dragonfly_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string(),
|
||||
llvm_target: "i686-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
options: super::linux_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
linker: "cc".to_string(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
morestack: true,
|
||||
linker_is_gnu: true,
|
||||
has_rpath: true,
|
||||
pre_link_args: vec!(
|
||||
// GNU-style linkers will use this to omit linking to libraries which
|
||||
// don't actually fulfill any relocations, but only for libraries which
|
||||
// follow this flag. Thus, use it before specifying libraries to link to.
|
||||
"-Wl,--as-needed".to_string(),
|
||||
),
|
||||
position_independant_executables: true,
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "E-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "mips-unknown-linux-gnu".to_string(),
|
||||
target_endian: "big".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "mips".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
options: super::linux_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32:32\
|
||||
-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64\
|
||||
-f32:32:32-f64:64:64\
|
||||
-v64:64:64-v128:64:128\
|
||||
-a0:0:64-n32".to_string(),
|
||||
llvm_target: "mipsel-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "mips".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
|
||||
options: super::linux_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,379 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
//! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
|
||||
//!
|
||||
//! Rust targets a wide variety of usecases, and in the interest of flexibility,
|
||||
//! allows new target triples to be defined in configuration files. Most users
|
||||
//! will not need to care about these, but this is invaluable when porting Rust
|
||||
//! to a new platform, and allows for an unprecedented level of control over how
|
||||
//! the compiler works.
|
||||
//!
|
||||
//! # Using custom targets
|
||||
//!
|
||||
//! A target triple, as passed via `rustc --target=TRIPLE`, will first be
|
||||
//! compared against the list of built-in targets. This is to ease distributing
|
||||
//! rustc (no need for configuration files) and also to hold these built-in
|
||||
//! targets as immutable and sacred. If `TRIPLE` is not one of the built-in
|
||||
//! targets, rustc will check if a file named `TRIPLE` exists. If it does, it
|
||||
//! will be loaded as the target configuration. If the file does not exist,
|
||||
//! rustc will search each directory in the environment variable
|
||||
//! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will
|
||||
//! be loaded. If no file is found in any of those directories, a fatal error
|
||||
//! will be given. `RUST_TARGET_PATH` includes `/etc/rustc` as its last entry,
|
||||
//! to be searched by default.
|
||||
//!
|
||||
//! Projects defining their own targets should use
|
||||
//! `--target=path/to/my-awesome-platform.json` instead of adding to
|
||||
//! `RUST_TARGET_PATH`.
|
||||
//!
|
||||
//! # Defining a new target
|
||||
//!
|
||||
//! Targets are defined using [JSON](http://json.org/). The `Target` struct in
|
||||
//! this module defines the format the JSON file should take, though each
|
||||
//! underscore in the field names should be replaced with a hyphen (`-`) in the
|
||||
//! JSON file. Some fields are required in every target specification, such as
|
||||
//! `data-layout`, `llvm-target`, `target-endian`, `target-word-size`, and
|
||||
//! `arch`. In general, options passed to rustc with `-C` override the target's
|
||||
//! settings, though `target-feature` and `link-args` will *add* to the list
|
||||
//! specified by the target, rather than replace.
|
||||
|
||||
use serialize::json::Json;
|
||||
use syntax::{diagnostic, abi};
|
||||
use std::default::Default;
|
||||
use std::io::fs::PathExtensions;
|
||||
|
||||
mod windows_base;
|
||||
mod linux_base;
|
||||
mod apple_base;
|
||||
mod freebsd_base;
|
||||
mod dragonfly_base;
|
||||
|
||||
mod arm_apple_ios;
|
||||
mod arm_linux_androideabi;
|
||||
mod arm_unknown_linux_gnueabi;
|
||||
mod arm_unknown_linux_gnueabihf;
|
||||
mod i686_apple_darwin;
|
||||
mod i386_apple_ios;
|
||||
mod i686_pc_windows_gnu;
|
||||
mod i686_unknown_linux_gnu;
|
||||
mod mips_unknown_linux_gnu;
|
||||
mod mipsel_unknown_linux_gnu;
|
||||
mod x86_64_apple_darwin;
|
||||
mod x86_64_pc_windows_gnu;
|
||||
mod x86_64_unknown_freebsd;
|
||||
mod x86_64_unknown_dragonfly;
|
||||
mod x86_64_unknown_linux_gnu;
|
||||
|
||||
/// Everything `rustc` knows about how to compile for a specific target.
|
||||
///
|
||||
/// Every field here must be specified, and has no default value.
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct Target {
|
||||
/// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
|
||||
pub data_layout: String,
|
||||
/// Target triple to pass to LLVM.
|
||||
pub llvm_target: String,
|
||||
/// String to use as the `target_endian` `cfg` variable.
|
||||
pub target_endian: String,
|
||||
/// String to use as the `target_word_size` `cfg` variable.
|
||||
pub target_word_size: String,
|
||||
/// OS name to use for conditional compilation.
|
||||
pub target_os: String,
|
||||
/// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm", and
|
||||
/// "mips". "mips" includes "mipsel".
|
||||
pub arch: String,
|
||||
/// Optional settings with defaults.
|
||||
pub options: TargetOptions,
|
||||
}
|
||||
|
||||
/// Optional aspects of a target specification.
|
||||
///
|
||||
/// This has an implementation of `Default`, see each field for what the default is. In general,
|
||||
/// these try to take "minimal defaults" that don't assume anything about the runtime they run in.
|
||||
#[deriving(Clone, Show)]
|
||||
pub struct TargetOptions {
|
||||
/// Linker to invoke. Defaults to "cc".
|
||||
pub linker: String,
|
||||
/// Linker arguments that are unconditionally passed *before* any user-defined libraries.
|
||||
pub pre_link_args: Vec<String>,
|
||||
/// Linker arguments that are unconditionally passed *after* any user-defined libraries.
|
||||
pub post_link_args: Vec<String>,
|
||||
/// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults to "default".
|
||||
pub cpu: String,
|
||||
/// Default target features to pass to LLVM. These features will *always* be passed, and cannot
|
||||
/// be disabled even via `-C`. Corresponds to `llc -mattr=$features`.
|
||||
pub features: String,
|
||||
/// Whether dynamic linking is available on this target. Defaults to false.
|
||||
pub dynamic_linking: bool,
|
||||
/// Whether executables are available on this target. iOS, for example, only allows static
|
||||
/// libraries. Defaults to false.
|
||||
pub executables: bool,
|
||||
/// Whether LLVM's segmented stack prelude is supported by whatever runtime is available.
|
||||
/// Will emit stack checks and calls to __morestack. Defaults to false.
|
||||
pub morestack: bool,
|
||||
/// Relocation model to use in object file. Corresponds to `llc
|
||||
/// -relocation-model=$relocation_model`. Defaults to "pic".
|
||||
pub relocation_model: String,
|
||||
/// Code model to use. Corresponds to `llc -code-model=$code_model`. Defaults to "default".
|
||||
pub code_model: String,
|
||||
/// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
|
||||
pub disable_redzone: bool,
|
||||
/// Eliminate frame pointers from stack frames if possible. Defaults to true.
|
||||
pub eliminate_frame_pointer: bool,
|
||||
/// Emit each function in its own section. Defaults to true.
|
||||
pub function_sections: bool,
|
||||
/// String to prepend to the name of every dynamic library. Defaults to "lib".
|
||||
pub dll_prefix: String,
|
||||
/// String to append to the name of every dynamic library. Defaults to ".so".
|
||||
pub dll_suffix: String,
|
||||
/// String to append to the name of every executable.
|
||||
pub exe_suffix: String,
|
||||
/// String to prepend to the name of every static library. Defaults to "lib".
|
||||
pub staticlib_prefix: String,
|
||||
/// String to append to the name of every static library. Defaults to ".a".
|
||||
pub staticlib_suffix: String,
|
||||
/// Whether the target toolchain is like OSX's. Only useful for compiling against iOS/OS X, in
|
||||
/// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
|
||||
pub is_like_osx: bool,
|
||||
/// Whether the target toolchain is like Windows'. Only useful for compiling against Windows,
|
||||
/// only realy used for figuring out how to find libraries, since Windows uses its own
|
||||
/// library naming convention. Defaults to false.
|
||||
pub is_like_windows: bool,
|
||||
/// Whether the linker support GNU-like arguments such as -O. Defaults to false.
|
||||
pub linker_is_gnu: 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,
|
||||
/// Dynamically linked executables can be compiled as position independent if the default
|
||||
/// relocation model of position independent code is not changed. This is a requirement to take
|
||||
/// advantage of ASLR, as otherwise the functions in the executable are not randomized and can
|
||||
/// be used during an exploit of a vulnerability in any code.
|
||||
pub position_independant_executables: bool,
|
||||
}
|
||||
|
||||
impl Default for TargetOptions {
|
||||
/// Create a set of "sane defaults" for any target. This is still incomplete, and if used for
|
||||
/// compilation, will certainly not work.
|
||||
fn default() -> TargetOptions {
|
||||
TargetOptions {
|
||||
linker: "cc".to_string(),
|
||||
pre_link_args: Vec::new(),
|
||||
post_link_args: Vec::new(),
|
||||
cpu: "generic".to_string(),
|
||||
features: "".to_string(),
|
||||
dynamic_linking: false,
|
||||
executables: false,
|
||||
morestack: false,
|
||||
relocation_model: "pic".to_string(),
|
||||
code_model: "default".to_string(),
|
||||
disable_redzone: false,
|
||||
eliminate_frame_pointer: true,
|
||||
function_sections: true,
|
||||
dll_prefix: "lib".to_string(),
|
||||
dll_suffix: ".so".to_string(),
|
||||
exe_suffix: "".to_string(),
|
||||
staticlib_prefix: "lib".to_string(),
|
||||
staticlib_suffix: ".a".to_string(),
|
||||
is_like_osx: false,
|
||||
is_like_windows: false,
|
||||
linker_is_gnu: false,
|
||||
has_rpath: false,
|
||||
no_compiler_rt: false,
|
||||
position_independant_executables: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Target {
|
||||
/// Given a function ABI, turn "System" into the correct ABI for this target.
|
||||
pub fn adjust_abi(&self, abi: abi::Abi) -> abi::Abi {
|
||||
match abi {
|
||||
abi::System => {
|
||||
if self.options.is_like_windows && self.arch.as_slice() == "x86" {
|
||||
abi::Stdcall
|
||||
} else {
|
||||
abi::C
|
||||
}
|
||||
},
|
||||
abi => abi
|
||||
}
|
||||
}
|
||||
|
||||
/// Load a target descriptor from a JSON object.
|
||||
pub fn from_json(obj: Json) -> Target {
|
||||
// this is 1. ugly, 2. error prone.
|
||||
|
||||
|
||||
let handler = diagnostic::default_handler(diagnostic::Auto, None);
|
||||
|
||||
let get_req_field = |name: &str| {
|
||||
match obj.find(&name.to_string())
|
||||
.map(|s| s.as_string())
|
||||
.and_then(|os| os.map(|s| s.to_string())) {
|
||||
Some(val) => val,
|
||||
None =>
|
||||
handler.fatal((format!("Field {} in target specification is required", name))
|
||||
.as_slice())
|
||||
}
|
||||
};
|
||||
|
||||
let mut base = Target {
|
||||
data_layout: get_req_field("data-layout"),
|
||||
llvm_target: get_req_field("llvm-target"),
|
||||
target_endian: get_req_field("target-endian"),
|
||||
target_word_size: get_req_field("target-word-size"),
|
||||
arch: get_req_field("arch"),
|
||||
target_os: get_req_field("os"),
|
||||
options: Default::default(),
|
||||
};
|
||||
|
||||
macro_rules! key (
|
||||
($key_name:ident) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.find(&name).map(|o| o.as_string()
|
||||
.map(|s| base.options.$key_name = s.to_string()));
|
||||
} );
|
||||
($key_name:ident, bool) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.find(&name).map(|o| o.as_boolean().map(|s| base.options.$key_name = s));
|
||||
} );
|
||||
($key_name:ident, list) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.find(&name).map(|o| o.as_list()
|
||||
.map(|v| base.options.$key_name = v.iter()
|
||||
.map(|a| a.as_string().unwrap().to_string()).collect()
|
||||
)
|
||||
);
|
||||
} );
|
||||
)
|
||||
|
||||
key!(cpu);
|
||||
key!(linker);
|
||||
key!(relocation_model);
|
||||
key!(code_model);
|
||||
key!(dll_prefix);
|
||||
key!(dll_suffix);
|
||||
key!(exe_suffix);
|
||||
key!(staticlib_prefix);
|
||||
key!(staticlib_suffix);
|
||||
key!(features);
|
||||
key!(dynamic_linking, bool);
|
||||
key!(executables, bool);
|
||||
key!(morestack, bool);
|
||||
key!(disable_redzone, bool);
|
||||
key!(eliminate_frame_pointer, bool);
|
||||
key!(function_sections, bool);
|
||||
key!(is_like_osx, bool);
|
||||
key!(is_like_windows, bool);
|
||||
key!(linker_is_gnu, bool);
|
||||
key!(has_rpath, bool);
|
||||
key!(no_compiler_rt, bool);
|
||||
key!(pre_link_args, list);
|
||||
key!(post_link_args, list);
|
||||
|
||||
base
|
||||
}
|
||||
|
||||
/// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
|
||||
/// could also just be a bare filename already, so also check for that. If one of the hardcoded
|
||||
/// targets we know about, just return it directly.
|
||||
///
|
||||
/// The error string could come from any of the APIs called, including filesystem access and
|
||||
/// JSON decoding.
|
||||
pub fn search(target: &str) -> Result<Target, String> {
|
||||
use std::os;
|
||||
use std::io::File;
|
||||
use std::path::Path;
|
||||
use serialize::json;
|
||||
|
||||
fn load_file(path: &Path) -> Result<Target, String> {
|
||||
let mut f = try!(File::open(path).map_err(|e| e.to_string()));
|
||||
let obj = try!(json::from_reader(&mut f).map_err(|e| e.to_string()));
|
||||
Ok(Target::from_json(obj))
|
||||
}
|
||||
|
||||
// this would use a match if stringify! were allowed in pattern position
|
||||
macro_rules! load_specific (
|
||||
( $($name:ident),+ ) => (
|
||||
{
|
||||
let target = target.replace("-", "_");
|
||||
let target = target.as_slice();
|
||||
if false { }
|
||||
$(
|
||||
else if target == stringify!($name) {
|
||||
let t = $name::target();
|
||||
debug!("Got builtin target: {}", t);
|
||||
return Ok(t);
|
||||
}
|
||||
)*
|
||||
else if target == "x86_64-w64-mingw32" {
|
||||
let t = x86_64_pc_windows_gnu::target();
|
||||
return Ok(t);
|
||||
} else if target == "i686-w64-mingw32" {
|
||||
let t = i686_pc_windows_gnu::target();
|
||||
return Ok(t);
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
load_specific!(
|
||||
x86_64_unknown_linux_gnu,
|
||||
i686_unknown_linux_gnu,
|
||||
mips_unknown_linux_gnu,
|
||||
mipsel_unknown_linux_gnu,
|
||||
arm_linux_androideabi,
|
||||
arm_unknown_linux_gnueabi,
|
||||
arm_unknown_linux_gnueabihf,
|
||||
|
||||
x86_64_unknown_freebsd,
|
||||
|
||||
x86_64_unknown_dragonfly,
|
||||
|
||||
x86_64_apple_darwin,
|
||||
i686_apple_darwin,
|
||||
i386_apple_ios,
|
||||
arm_apple_ios,
|
||||
|
||||
x86_64_pc_windows_gnu,
|
||||
i686_pc_windows_gnu
|
||||
)
|
||||
|
||||
|
||||
let path = Path::new(target);
|
||||
|
||||
if path.is_file() {
|
||||
return load_file(&path);
|
||||
}
|
||||
|
||||
let path = {
|
||||
let mut target = target.to_string();
|
||||
target.push_str(".json");
|
||||
Path::new(target)
|
||||
};
|
||||
|
||||
let target_path = os::getenv("RUST_TARGET_PATH").unwrap_or(String::new());
|
||||
|
||||
let paths = os::split_paths(target_path.as_slice());
|
||||
// FIXME 16351: add a sane default search path?
|
||||
|
||||
for dir in paths.iter() {
|
||||
let p = dir.join(path.clone());
|
||||
if p.is_file() {
|
||||
return load_file(&p);
|
||||
}
|
||||
}
|
||||
|
||||
Err(format!("Could not find specification for target {}", target))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::TargetOptions;
|
||||
use std::default::Default;
|
||||
|
||||
pub fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
// FIXME(#13846) this should be enabled for windows
|
||||
function_sections: false,
|
||||
linker: "gcc".to_string(),
|
||||
dynamic_linking: true,
|
||||
executables: true,
|
||||
dll_prefix: "".to_string(),
|
||||
dll_suffix: ".dll".to_string(),
|
||||
exe_suffix: ".exe".to_string(),
|
||||
staticlib_prefix: "".to_string(),
|
||||
staticlib_suffix: ".lib".to_string(),
|
||||
morestack: false,
|
||||
is_like_windows: true,
|
||||
pre_link_args: vec!(
|
||||
// And here, we see obscure linker flags #45. On windows, it has been
|
||||
// found to be necessary to have this flag to compile liblibc.
|
||||
//
|
||||
// First a bit of background. On Windows, the file format is not ELF,
|
||||
// but COFF (at least according to LLVM). COFF doesn't officially allow
|
||||
// for section names over 8 characters, apparently. Our metadata
|
||||
// section, ".note.rustc", you'll note is over 8 characters.
|
||||
//
|
||||
// On more recent versions of gcc on mingw, apparently the section name
|
||||
// is *not* truncated, but rather stored elsewhere in a separate lookup
|
||||
// table. On older versions of gcc, they apparently always truncated th
|
||||
// section names (at least in some cases). Truncating the section name
|
||||
// actually creates "invalid" objects [1] [2], but only for some
|
||||
// introspection tools, not in terms of whether it can be loaded.
|
||||
//
|
||||
// Long story short, passing this flag forces the linker to *not*
|
||||
// truncate section names (so we can find the metadata section after
|
||||
// it's compiled). The real kicker is that rust compiled just fine on
|
||||
// windows for quite a long time *without* this flag, so I have no idea
|
||||
// why it suddenly started failing for liblibc. Regardless, we
|
||||
// definitely don't want section name truncation, so we're keeping this
|
||||
// flag for windows.
|
||||
//
|
||||
// [1] - https://sourceware.org/bugzilla/show_bug.cgi?id=13130
|
||||
// [2] - https://code.google.com/p/go/issues/detail?id=2139
|
||||
"-Wl,--enable-long-section-names".to_string(),
|
||||
|
||||
// Tell GCC to avoid linker plugins, because we are not bundling
|
||||
// them with Windows installer, and Rust does its own LTO anyways.
|
||||
"-fno-use-linker-plugin".to_string(),
|
||||
|
||||
// Always enable DEP (NX bit) when it is available
|
||||
"-Wl,--nxcompat".to_string(),
|
||||
),
|
||||
|
||||
.. Default::default()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::apple_base::opts();
|
||||
base.eliminate_frame_pointer = false;
|
||||
base.pre_link_args.push("-m64".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64".to_string(),
|
||||
llvm_target: "x86_64-apple-darwin".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "64".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "macos".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::windows_base::opts();
|
||||
// On Win64 unwinding is handled by the OS, so we can link libgcc statically.
|
||||
base.pre_link_args.push("-static-libgcc".to_string());
|
||||
base.pre_link_args.push("-m64".to_string());
|
||||
|
||||
Target {
|
||||
// FIXME: Test this. Copied from linux (#2398)
|
||||
data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(),
|
||||
llvm_target: "x86_64-pc-windows-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "64".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "windows".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
Target {
|
||||
data_layout: "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32".to_string(),
|
||||
llvm_target: "x86_64-unknown-dragonfly".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "32".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "dragonfly".to_string(),
|
||||
options: super::dragonfly_base::opts()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::freebsd_base::opts();
|
||||
base.pre_link_args.push("-m64".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(),
|
||||
llvm_target: "x86_64-unknown-freebsd".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "64".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "freebsd".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
use target::Target;
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut base = super::linux_base::opts();
|
||||
base.pre_link_args.push("-m64".to_string());
|
||||
|
||||
Target {
|
||||
data_layout: "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-\
|
||||
f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-\
|
||||
s0:64:64-f80:128:128-n8:16:32:64-S128".to_string(),
|
||||
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
target_endian: "little".to_string(),
|
||||
target_word_size: "64".to_string(),
|
||||
arch: "x86_64".to_string(),
|
||||
target_os: "linux".to_string(),
|
||||
options: base,
|
||||
}
|
||||
}
|
|
@ -183,7 +183,7 @@ fn runtest(test: &str, cratename: &str, libs: Vec<Path>, externs: core::Externs,
|
|||
// environment to ensure that the target loads the right libraries at
|
||||
// runtime. It would be a sad day if the *host* libraries were loaded as a
|
||||
// mistake.
|
||||
let mut cmd = Command::new(outdir.path().join("rust_out"));
|
||||
let mut cmd = Command::new(outdir.path().join("rust-out"));
|
||||
let newpath = {
|
||||
let mut path = DynamicLibrary::search_path();
|
||||
path.insert(0, libdir.clone());
|
||||
|
|
|
@ -37,9 +37,6 @@ pub enum Abi {
|
|||
#[allow(non_camel_case_types)]
|
||||
#[deriving(PartialEq)]
|
||||
pub enum Architecture {
|
||||
// NB. You cannot change the ordering of these
|
||||
// constants without adjusting IntelBits below.
|
||||
// (This is ensured by the test indices_are_correct().)
|
||||
X86,
|
||||
X86_64,
|
||||
Arm,
|
||||
|
@ -47,20 +44,11 @@ pub enum Architecture {
|
|||
Mipsel
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint));
|
||||
#[allow(non_upper_case_globals)]
|
||||
const ArmBits: u32 = (1 << (Arm as uint));
|
||||
|
||||
pub struct AbiData {
|
||||
abi: Abi,
|
||||
|
||||
// Name of this ABI as we like it called.
|
||||
name: &'static str,
|
||||
|
||||
// Is it specific to a platform? If so, which one? Also, what is
|
||||
// the name that LLVM gives it (in case we disagree)
|
||||
abi_arch: AbiArchitecture
|
||||
}
|
||||
|
||||
pub enum AbiArchitecture {
|
||||
|
@ -75,22 +63,21 @@ pub enum AbiArchitecture {
|
|||
#[allow(non_upper_case_globals)]
|
||||
static AbiDatas: &'static [AbiData] = &[
|
||||
// Platform-specific ABIs
|
||||
AbiData {abi: Cdecl, name: "cdecl", abi_arch: Archs(IntelBits)},
|
||||
AbiData {abi: Stdcall, name: "stdcall", abi_arch: Archs(IntelBits)},
|
||||
AbiData {abi: Fastcall, name:"fastcall", abi_arch: Archs(IntelBits)},
|
||||
AbiData {abi: Aapcs, name: "aapcs", abi_arch: Archs(ArmBits)},
|
||||
AbiData {abi: Win64, name: "win64",
|
||||
abi_arch: Archs(1 << (X86_64 as uint))},
|
||||
AbiData {abi: Cdecl, name: "cdecl" },
|
||||
AbiData {abi: Stdcall, name: "stdcall" },
|
||||
AbiData {abi: Fastcall, name:"fastcall" },
|
||||
AbiData {abi: Aapcs, name: "aapcs" },
|
||||
AbiData {abi: Win64, name: "win64" },
|
||||
|
||||
// Cross-platform ABIs
|
||||
//
|
||||
// NB: Do not adjust this ordering without
|
||||
// adjusting the indices below.
|
||||
AbiData {abi: Rust, name: "Rust", abi_arch: RustArch},
|
||||
AbiData {abi: C, name: "C", abi_arch: AllArch},
|
||||
AbiData {abi: System, name: "system", abi_arch: AllArch},
|
||||
AbiData {abi: RustIntrinsic, name: "rust-intrinsic", abi_arch: RustArch},
|
||||
AbiData {abi: RustCall, name: "rust-call", abi_arch: RustArch},
|
||||
AbiData {abi: Rust, name: "Rust" },
|
||||
AbiData {abi: C, name: "C" },
|
||||
AbiData {abi: System, name: "system" },
|
||||
AbiData {abi: RustIntrinsic, name: "rust-intrinsic" },
|
||||
AbiData {abi: RustCall, name: "rust-call" },
|
||||
];
|
||||
|
||||
/// Returns the ABI with the given name (if any).
|
||||
|
@ -116,28 +103,6 @@ impl Abi {
|
|||
pub fn name(&self) -> &'static str {
|
||||
self.data().name
|
||||
}
|
||||
|
||||
pub fn for_target(&self, os: Os, arch: Architecture) -> Option<Abi> {
|
||||
// If this ABI isn't actually for the specified architecture, then we
|
||||
// short circuit early
|
||||
match self.data().abi_arch {
|
||||
Archs(a) if a & arch.bit() == 0 => return None,
|
||||
Archs(_) | RustArch | AllArch => {}
|
||||
}
|
||||
// Transform this ABI as appropriate for the requested os/arch
|
||||
// combination.
|
||||
Some(match (*self, os, arch) {
|
||||
(System, OsWindows, X86) => Stdcall,
|
||||
(System, _, _) => C,
|
||||
(me, _, _) => me,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Architecture {
|
||||
fn bit(&self) -> u32 {
|
||||
1 << (*self as uint)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Show for Abi {
|
||||
|
@ -184,23 +149,4 @@ fn indices_are_correct() {
|
|||
for (i, abi_data) in AbiDatas.iter().enumerate() {
|
||||
assert_eq!(i, abi_data.abi.index());
|
||||
}
|
||||
|
||||
let bits = 1 << (X86 as uint);
|
||||
let bits = bits | 1 << (X86_64 as uint);
|
||||
assert_eq!(IntelBits, bits);
|
||||
|
||||
let bits = 1 << (Arm as uint);
|
||||
assert_eq!(ArmBits, bits);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pick_uniplatform() {
|
||||
assert_eq!(Stdcall.for_target(OsLinux, X86), Some(Stdcall));
|
||||
assert_eq!(Stdcall.for_target(OsLinux, Arm), None);
|
||||
assert_eq!(System.for_target(OsLinux, X86), Some(C));
|
||||
assert_eq!(System.for_target(OsWindows, X86), Some(Stdcall));
|
||||
assert_eq!(System.for_target(OsWindows, X86_64), Some(C));
|
||||
assert_eq!(System.for_target(OsWindows, Arm), Some(C));
|
||||
assert_eq!(Stdcall.for_target(OsWindows, X86), Some(Stdcall));
|
||||
assert_eq!(Stdcall.for_target(OsWindows, X86_64), Some(Stdcall));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
ifndef IS_WINDOWS
|
||||
|
||||
all:
|
||||
@echo $(RUSTDOC)
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) --test foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
cp verify.sh $(TMPDIR)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
-include ../tools.mk
|
||||
all:
|
||||
$(RUSTC) foo.rs --target=my-awesome-platform.json --crate-type=lib --emit=asm
|
||||
grep --quiet --invert-match morestack < $(TMPDIR)/foo.s
|
||||
$(RUSTC) foo.rs --target=my-invalid-platform.json 2>&1 | grep --quiet --invert-match "Error loading taget specification"
|
||||
$(RUSTC) foo.rs --target=my-incomplete-platform.json 2>&1 | grep 'Field llvm-target'
|
||||
RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=my-awesome-platform --crate-type=lib --emit=asm
|
||||
RUST_TARGET_PATH=. $(RUSTC) foo.rs --target=x86_64-unknown-linux-gnu --crate-type=lib --emit=asm
|
||||
# The built-in target *should* override the one we have here, and thus we
|
||||
# should have morestack
|
||||
grep --quiet morestack < $(TMPDIR)/foo.s
|
|
@ -0,0 +1,26 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
#![feature(lang_items)]
|
||||
#![no_std]
|
||||
|
||||
#[lang="sized"]
|
||||
trait Sized { }
|
||||
|
||||
#[lang="start"]
|
||||
fn start(_main: *const u8, _argc: int, _argv: *const *const u8) -> int { 0 }
|
||||
|
||||
extern {
|
||||
fn _foo() -> [u8, ..16];
|
||||
}
|
||||
|
||||
fn _main() {
|
||||
let _a = unsafe { _foo() };
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
|
||||
"llvm-target": "i686-unknown-linux-gnu",
|
||||
"target-endian": "little",
|
||||
"target-word-size": "32",
|
||||
"arch": "x86",
|
||||
"os": "linux",
|
||||
"morestack": false
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
|
||||
"target-endian": "little",
|
||||
"target-word-size": "32",
|
||||
"arch": "x86",
|
||||
"os": "foo",
|
||||
"morestack": false
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
wow this json is really broke!
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
|
||||
"llvm-target": "i686-unknown-linux-gnu",
|
||||
"target-endian": "little",
|
||||
"target-word-size": "32",
|
||||
"arch": "x86",
|
||||
"os": "linux",
|
||||
"morestack": false
|
||||
}
|
Loading…
Reference in New Issue