Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial MSVC support for the compiler #25350

Merged
merged 31 commits into from
May 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
315750a
Very hacky MSVC hacks.
ricky26 Mar 4, 2015
4cc025d
Scale back changes made
alexcrichton May 8, 2015
2d5e577
rustc_trans: Abstract linker support behind a trait
alexcrichton May 8, 2015
40570eb
rustc_llvm: Expose setting more DLL storage classes
alexcrichton May 11, 2015
cb513c7
rt: Clean up to build with cl.exe
alexcrichton May 11, 2015
eb5bf15
mk: Remove generation of .d files
alexcrichton May 11, 2015
150663c
mk: Correct names of installed libs on windows
alexcrichton May 11, 2015
ee258c5
mk: Fix native LLVM deps for cross-host builds
alexcrichton May 11, 2015
7cf0b17
configure: Start adding MSVC support
alexcrichton May 11, 2015
b56d47c
mk: Enable building LLVM targeting MSVC
alexcrichton May 11, 2015
fcf7ecd
mk: Add build system support for cl.exe
alexcrichton May 11, 2015
ee64bab
mk: Don't add cross prefixes for MSVC
alexcrichton May 11, 2015
64412a4
mk: Fix building compiler-rt on MSVC
alexcrichton May 11, 2015
6122a5f
mk: Fix MSVC build for rustllvm.lib
alexcrichton May 11, 2015
a4ef308
mk: Add the ability to depend on native LLVM tools
alexcrichton May 11, 2015
f9846e9
rustc: Shorten MSVC metadata section name
alexcrichton May 11, 2015
839dcfd
rustc_back: Refactor Archive to better express intent
alexcrichton May 11, 2015
37659a1
rustc_back: Remove unneeded explicit variable
alexcrichton May 11, 2015
af56e2e
rustc_back: Tweak the MSVC target spec
alexcrichton May 11, 2015
d97b4af
mklldeps: Don't link stdc++/c++ on MSVC
alexcrichton May 11, 2015
e2854b3
libc: Add necessary libraries for MSVC
alexcrichton May 11, 2015
eb50ffd
rustc_trans: Clean up some style in back::link
alexcrichton May 11, 2015
181dbd7
rustc_trans: Add MSVC linker support
alexcrichton May 11, 2015
ce8b317
rustc_trans: Tidy up some style and line lengths
alexcrichton May 11, 2015
b538189
mk: Generate a .def file for rustc_llvm on MSVC
alexcrichton May 11, 2015
847c852
rustc_llvm: Don't export constants across dlls
alexcrichton May 12, 2015
f5222fb
std: Implement aborting stubs for MSVC unwinding
alexcrichton May 12, 2015
9a2415b
std: Mark rust_get_num_cpus as dllexport
alexcrichton May 12, 2015
3d32cf5
rustc_trans: Apply dllexport attributes for MSVC
alexcrichton May 12, 2015
74f4f39
std: Don't require rust_try as an exported symbol
alexcrichton May 12, 2015
cb3071b
mk: Update `make dist` for MSVC targets
alexcrichton May 13, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,3 @@ ifneq ($(strip $(findstring TAGS.emacs,$(MAKECMDGOALS)) \
CFG_INFO := $(info cfg: including ctags rules)
include $(CFG_SRC_DIR)mk/ctags.mk
endif

# Find all of the .d files and include them to add information about
# header file dependencies.
ALL_DEP_FILES := $(ALL_OBJ_FILES:%.o=%.d)
-include $(ALL_DEP_FILES)
108 changes: 98 additions & 10 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ CFG_TARGET=$(to_llvm_triple $CFG_TARGET)
# 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
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ]
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ]
then
CFG_LIBDIR_RELATIVE=bin
else
Expand All @@ -628,7 +628,8 @@ esac

CFG_LIBDIR_RELATIVE=`echo ${CFG_LIBDIR} | cut -c$((${#CFG_PREFIX}+${CAT_INC}))-`

if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] && [ "$CFG_LIBDIR_RELATIVE" != "bin" ]; then
if ( [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ] ) \
&& [ "$CFG_LIBDIR_RELATIVE" != "bin" ]; then
err "libdir on windows should be set to 'bin'"
fi

Expand Down Expand Up @@ -803,7 +804,7 @@ then
fi

BIN_SUF=
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ]
if [ "$CFG_OSTYPE" = "pc-windows-gnu" ] || [ "$CFG_OSTYPE" = "pc-windows-msvc" ]
then
BIN_SUF=.exe
fi
Expand Down Expand Up @@ -1083,6 +1084,65 @@ do
err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found"
fi
;;

x86_64-*-msvc)
# Currently the build system is not configured to build jemalloc
# with MSVC, so we omit this optional dependency.
step_msg "targeting MSVC, disabling jemalloc"
CFG_DISABLE_JEMALLOC=1
putvar CFG_DISABLE_JEMALLOC

# There are some MSYS python builds which will auto-translate
# windows-style paths to MSYS-style paths in Python itself.
# Unfortunately this breaks LLVM's build system as somewhere along
# the line LLVM prints a path into a file from Python and then CMake
# later tries to interpret that path. If Python prints a MSYS path
# and CMake tries to use it as a Windows path, you're gonna have a
# Bad Time.
#
# Consequently here we try to detect when that happens and print an
# error if it does.
if $CFG_PYTHON -c 'import sys; print sys.argv[1]' `pwd` | grep '^/'
then
err "python is silently translating windows paths to MSYS paths \
and the build will fail if this python is used.\n\n \
Either an official python install must be used or an \
alternative python package in MinGW must be used."
fi

# MSVC requires cmake because that's how we're going to build LLVM
probe_need CFG_CMAKE cmake

# Use the REG program to figure out where VS is installed
# We need to figure out where cl.exe and link.exe are, so we do some
# munging and some probing here. We also look for the default
# INCLUDE and LIB variables for MSVC so we can set those in the
# build system as well.
install=$(reg QUERY \
'HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0' \
-v InstallDir)
need_ok "couldn't find visual studio install root"
CFG_MSVC_ROOT=$(echo "$install" | grep InstallDir | sed 's/.*REG_SZ[ ]*//')
CFG_MSVC_ROOT=$(dirname "$CFG_MSVC_ROOT")
CFG_MSVC_ROOT=$(dirname "$CFG_MSVC_ROOT")
CFG_MSVC_CL="${CFG_MSVC_ROOT}/VC/bin/amd64/cl.exe"
CFG_MSVC_LIB="${CFG_MSVC_ROOT}/VC/bin/amd64/lib.exe"
CFG_MSVC_LINK="${CFG_MSVC_ROOT}/VC/bin/amd64/link.exe"

vcvarsall="${CFG_MSVC_ROOT}/VC/vcvarsall.bat"
CFG_MSVC_INCLUDE_PATH=$(cmd /c "\"$vcvarsall\" amd64 && cmd /c echo %INCLUDE%")
need_ok "failed to learn about MSVC's INCLUDE"
CFG_MSVC_LIB_PATH=$(cmd /c "\"$vcvarsall\" amd64 && cmd /c echo %LIB%")
need_ok "failed to learn about MSVC's LIB"

putvar CFG_MSVC_ROOT
putvar CFG_MSVC_CL
putvar CFG_MSVC_LIB
putvar CFG_MSVC_LINK
putvar CFG_MSVC_INCLUDE_PATH
putvar CFG_MSVC_LIB_PATH
;;

*)
;;
esac
Expand Down Expand Up @@ -1124,6 +1184,7 @@ do
do
make_dir $t/rt/stage$s
make_dir $t/rt/jemalloc
make_dir $t/rt/compiler-rt
for i in \
isaac sync test \
arch/i386 arch/x86_64 arch/arm arch/aarch64 arch/mips arch/powerpc
Expand Down Expand Up @@ -1287,7 +1348,39 @@ do
done
fi

if [ ${do_reconfigure} -ne 0 ]
use_cmake=0
case "$t" in
(*-msvc)
use_cmake=1
;;
esac

if [ ${do_reconfigure} -ne 0 ] && [ ${use_cmake} -ne 0 ]
then
msg "configuring LLVM for $t with cmake"

CMAKE_ARGS="-DLLVM_INCLUDE_TESTS=OFF"
if [ ! -z "$CFG_DISABLE_OPTIMIZE_LLVM" ]; then
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Debug"
else
CMAKE_ARGS="$CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release"
fi
if [ -z "$CFG_ENABLE_LLVM_ASSERTIONS" ]
then
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=OFF"
else
CMAKE_ARGS="$CMAKE_ARGS -DLLVM_ENABLE_ASSERTIONS=ON"
fi

msg "configuring LLVM with:"
msg "$CMAKE_ARGS"
(cd $LLVM_BUILD_DIR && "$CFG_CMAKE" $CFG_LLVM_SRC_DIR \
-G "Visual Studio 12 2013 Win64" \
$CMAKE_ARGS)
need_ok "LLVM cmake configure failed"
fi

if [ ${do_reconfigure} -ne 0 ] && [ ${use_cmake} -eq 0 ]
then
# LLVM's configure doesn't recognize the new Windows triples yet
gnu_t=$(to_gnu_triple $t)
Expand All @@ -1311,7 +1404,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
(*-windows-*)
(*-windows-gnu)
LLVM_OPTS="$LLVM_OPTS --disable-pthreads"
;;
esac
Expand Down Expand Up @@ -1495,11 +1588,6 @@ do
putvar $CFG_LLVM_INST_DIR
done

# Munge any paths that appear in config.mk back to posix-y
cp config.tmp config.tmp.bak
sed -e 's@ \([a-zA-Z]\):[/\\]@ /\1/@g;' <config.tmp.bak >config.tmp
rm -f config.tmp.bak

msg
copy_if_changed ${CFG_SRC_DIR}Makefile.in ./Makefile
move_if_changed config.tmp config.mk
Expand Down
1 change: 1 addition & 0 deletions mk/cfg/aarch64-apple-ios.mk
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ifneq ($(findstring darwin,$(CFG_OSTYPE)),)
CFG_IOS_SDK_aarch64-apple-ios := $(shell xcrun --show-sdk-path -sdk iphoneos 2>/dev/null)
CFG_IOS_SDK_FLAGS_aarch64-apple-ios := -target aarch64-apple-darwin -isysroot $(CFG_IOS_SDK_aarch64-apple-ios) -mios-version-min=7.0 -arch arm64
CC_aarch64-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
LINK_aarch64-apple-ios = $(shell xcrun -find -sdk iphoneos clang)
CXX_aarch64-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
CPP_aarch64-apple-ios = $(shell xcrun -find -sdk iphoneos clang++)
AR_aarch64-apple-ios = $(shell xcrun -find -sdk iphoneos ar)
Expand Down
1 change: 1 addition & 0 deletions mk/cfg/aarch64-linux-android.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# aarch64-linux-android configuration
# CROSS_PREFIX_aarch64-linux-android-
CC_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc
LINK_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc
CXX_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-g++
CPP_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-gcc -E
AR_aarch64-linux-android=$(CFG_ANDROID_CROSS_PATH)/bin/aarch64-linux-android-ar
Expand Down
1 change: 1 addition & 0 deletions mk/cfg/aarch64-unknown-linux-gnu.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# aarch64-unknown-linux-gnu configuration
CROSS_PREFIX_aarch64-unknown-linux-gnu=aarch64-linux-gnu-
CC_aarch64-unknown-linux-gnu=gcc
LINK_aarch64-unknown-linux-gnu=gcc
CXX_aarch64-unknown-linux-gnu=g++
CPP_aarch64-unknown-linux-gnu=gcc -E
AR_aarch64-unknown-linux-gnu=ar
Expand Down
1 change: 1 addition & 0 deletions mk/cfg/arm-linux-androideabi.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# arm-linux-androideabi configuration
LINK_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
CC_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc
CXX_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-g++
CPP_arm-linux-androideabi=$(CFG_ANDROID_CROSS_PATH)/bin/arm-linux-androideabi-gcc -E
Expand Down
1 change: 1 addition & 0 deletions mk/cfg/x86_64-pc-windows-gnu.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# x86_64-pc-windows-gnu configuration
CROSS_PREFIX_x86_64-pc-windows-gnu=x86_64-w64-mingw32-
CC_x86_64-pc-windows-gnu=gcc
LINK_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
Expand Down
82 changes: 82 additions & 0 deletions mk/cfg/x86_64-pc-windows-msvc.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# x86_64-pc-windows-msvc configuration
CC_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo
LINK_x86_64-pc-windows-msvc="$(CFG_MSVC_LINK)" -nologo
CXX_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo
CPP_x86_64-pc-windows-msvc="$(CFG_MSVC_CL)" -nologo
AR_x86_64-pc-windows-msvc="$(CFG_MSVC_LIB)" -nologo
CFG_LIB_NAME_x86_64-pc-windows-msvc=$(1).dll
CFG_STATIC_LIB_NAME_x86_64-pc-windows-msvc=$(1).lib
CFG_LIB_GLOB_x86_64-pc-windows-msvc=$(1)-*.dll
CFG_LIB_DSYM_GLOB_x86_64-pc-windows-msvc=$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_x86_64-pc-windows-msvc :=
CFG_GCCISH_CFLAGS_x86_64-pc-windows-msvc :=
CFG_GCCISH_CXXFLAGS_x86_64-pc-windows-msvc :=
CFG_GCCISH_LINK_FLAGS_x86_64-pc-windows-msvc :=
CFG_GCCISH_DEF_FLAG_x86_64-pc-windows-msvc :=
CFG_LLC_FLAGS_x86_64-pc-windows-msvc :=
CFG_INSTALL_NAME_x86_64-pc-windows-msvc =
CFG_EXE_SUFFIX_x86_64-pc-windows-msvc := .exe
CFG_WINDOWSY_x86_64-pc-windows-msvc := 1
CFG_UNIXY_x86_64-pc-windows-msvc :=
CFG_LDPATH_x86_64-pc-windows-msvc :=
CFG_RUN_x86_64-pc-windows-msvc=$(2)
CFG_RUN_TARG_x86_64-pc-windows-msvc=$(call CFG_RUN_x86_64-pc-windows-msvc,,$(2))
CFG_GNU_TRIPLE_x86_64-pc-windows-msvc := x86_64-pc-win32

# These two environment variables are scraped by the `./configure` script and
# are necessary for `cl.exe` to find standard headers (the INCLUDE variable) and
# for `link.exe` to find standard libraries (the LIB variable).
ifdef CFG_MSVC_INCLUDE_PATH
export INCLUDE := $(CFG_MSVC_INCLUDE_PATH)
endif
ifdef CFG_MSVC_LIB_PATH
export LIB := $(CFG_MSVC_LIB_PATH)
endif

# Unfortunately `link.exe` is also a program in `/usr/bin` on MinGW installs,
# but it's not the one that we want. As a result we make sure that our detected
# `link.exe` shows up in PATH first.
ifdef CFG_MSVC_LINK
export PATH := $(CFG_MSVC_ROOT)/VC/bin/amd64:$(PATH)
endif

# There are more comments about this available in the target specification for
# Windows MSVC in the compiler, but the gist of it is that we use `llvm-ar.exe`
# instead of `lib.exe` for assembling archives, so we need to inject this custom
# dependency here.
NATIVE_TOOL_DEPS_core_T_x86_64-pc-windows-msvc += llvm-ar.exe
INSTALLED_BINS_x86_64-pc-windows-msvc += llvm-ar.exe

# When working with MSVC on windows, each DLL needs to explicitly declare its
# interface to the outside world through some means. The options for doing so
# include:
#
# 1. A custom attribute on each function itself
# 2. A linker argument saying what to export
# 3. A file which lists all symbols that need to be exported
#
# The Rust compiler takes care (1) for us for all Rust code by annotating all
# public-facing functions with dllexport, but we have a few native dependencies
# which need to cross the DLL boundary. The most important of these dependencies
# is LLVM which is linked into `rustc_llvm.dll` but primarily used from
# `rustc_trans.dll`. This means that many of LLVM's C API functions need to be
# exposed from `rustc_llvm.dll` to be forwarded over the boundary.
#
# Unfortunately, at this time, LLVM does not handle this sort of exportation on
# Windows for us, so we're forced to do it ourselves if we want it (which seems
# like the path of least resistance right now). To do this we generate a `.DEF`
# file [1] which we then custom-pass to the linker when building the rustc_llvm
# crate. This DEF file list all symbols that are exported from
# `src/librustc_llvm/lib.rs` and is generated by a small python script.
#
# Fun times!
#
# [1]: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
RUSTFLAGS_rustc_llvm_T_x86_64-pc-windows-msvc += \
-C link-args="-DEF:x86_64-pc-windows-msvc/rt/rustc_llvm.def"
CUSTOM_DEPS_rustc_llvm_T_x86_64-pc-windows-msvc += \
x86_64-pc-windows-msvc/rt/rustc_llvm.def

x86_64-pc-windows-msvc/rt/rustc_llvm.def: $(S)src/etc/mklldef.py \
$(S)src/librustc_llvm/lib.rs
$(CFG_PYTHON) $^ $@ rustc_llvm-$(CFG_FILENAME_EXTRA)
13 changes: 0 additions & 13 deletions mk/clean.mk
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,3 @@ $(foreach host, $(CFG_HOST), \
$(eval $(foreach target, $(CFG_TARGET), \
$(eval $(foreach stage, 0 1 2 3, \
$(eval $(call CLEAN_TARGET_STAGE_N,$(stage),$(target),$(host))))))))

define DEF_CLEAN_LLVM_HOST
ifeq ($(CFG_LLVM_ROOT),)
clean-llvm$(1):
$$(Q)$$(MAKE) -C $$(CFG_LLVM_BUILD_DIR_$(1)) clean
else
clean-llvm$(1): ;

endif
endef

$(foreach host, $(CFG_HOST), \
$(eval $(call DEF_CLEAN_LLVM_HOST,$(host))))
3 changes: 0 additions & 3 deletions mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ ONLY_RLIB_rustc_bitflags := 1
# Documented-by-default crates
DOC_CRATES := std alloc collections core libc rustc_unicode

# Installed objects/libraries by default
INSTALLED_OBJECTS := libmorestack.a libcompiler-rt.a

################################################################################
# You should not need to edit below this line
################################################################################
Expand Down
11 changes: 10 additions & 1 deletion mk/dist.mk
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,11 @@ dist/$$(PKG_NAME)-$(1).tar.gz: dist-install-dir-$(1) prepare-overlay-$(1)
@$(call E, build: $$@)
# Copy essential gcc components into installer
ifdef CFG_WINDOWSY_$(1)
ifeq ($$(findstring gnu,$(1)),gnu)
$$(Q)rm -Rf tmp/dist/win-rust-gcc-$(1)
$$(Q)$$(CFG_PYTHON) $$(S)src/etc/make-win-dist.py tmp/dist/$$(PKG_NAME)-$(1)-image tmp/dist/win-rust-gcc-$(1) $(1)
$$(Q)cp -r $$(S)src/etc/third-party tmp/dist/$$(PKG_NAME)-$(1)-image/share/doc/
endif
endif
$$(Q)$$(S)src/rust-installer/gen-installer.sh \
--product-name=Rust \
Expand Down Expand Up @@ -213,7 +215,14 @@ endif
dist-install-dirs: $(foreach host,$(CFG_HOST),dist-install-dir-$(host))

ifdef CFG_WINDOWSY_$(CFG_BUILD)
MAYBE_MINGW_TARBALLS=$(foreach host,$(CFG_HOST),dist/$(MINGW_PKG_NAME)-$(host).tar.gz)
define BUILD_MINGW_TARBALL
ifeq ($$(findstring gnu,$(1)),gnu)
MAYBE_MINGW_TARBALLS += dist/$(MINGW_PKG_NAME)-$(1).tar.gz
endif
endef

$(foreach host,$(CFG_HOST),\
$(eval $(call BUILD_MINGW_TARBALL,$(host))))
endif

ifeq ($(CFG_DISABLE_DOCS),)
Expand Down
Loading