diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2015-05-11 15:49:30 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2015-05-19 10:53:07 -0700 |
| commit | b538189ba0abb77658c7b082d2d541daaaa7f80a (patch) | |
| tree | 10bfbb144628df7710c2c196000818fcf01cabc8 | |
| parent | ce8b317558a83021b7ea0f40c5719995e234da03 (diff) | |
| download | rust-b538189ba0abb77658c7b082d2d541daaaa7f80a.tar.gz rust-b538189ba0abb77658c7b082d2d541daaaa7f80a.zip | |
mk: Generate a .def file for rustc_llvm on MSVC
Windows needs explicit exports of functions from DLLs but LLVM does not mention any of its symbols as being export-able from a DLL. The compiler, however, relies on being able to use LLVM symbols across DLL boundaries so we need to force many of LLVM's symbols to be exported from `rustc_llvm.dll`. This commit adds support for generation of a `rustc_llvm.def` file which is passed along to the linker when generating `rustc_llvm.dll` which should keep all these symbols exportable and usable.
| -rw-r--r-- | mk/cfg/x86_64-pc-windows-msvc.mk | 34 | ||||
| -rw-r--r-- | mk/target.mk | 4 | ||||
| -rw-r--r-- | src/etc/mklldef.py | 25 |
3 files changed, 62 insertions, 1 deletions
diff --git a/mk/cfg/x86_64-pc-windows-msvc.mk b/mk/cfg/x86_64-pc-windows-msvc.mk index 209c53f0452..1a1f059945a 100644 --- a/mk/cfg/x86_64-pc-windows-msvc.mk +++ b/mk/cfg/x86_64-pc-windows-msvc.mk @@ -45,3 +45,37 @@ endif # 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 + +# 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) diff --git a/mk/target.mk b/mk/target.mk index 4359eec8447..c8efb8e86d6 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -39,7 +39,8 @@ CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \ $$(foreach dep,$$(NATIVE_DEPS_$(4)_T_$(2)), \ $$(RT_OUTPUT_DIR_$(2))/$$(dep)) \ $$(foreach dep,$$(NATIVE_TOOL_DEPS_$(4)_T_$(2)), \ - $$(TBIN$(1)_T_$(3)_H_$(3))/$$(dep)) + $$(TBIN$(1)_T_$(3)_H_$(3))/$$(dep)) \ + $$(CUSTOM_DEPS_$(4)_T_$(2)) endef $(foreach host,$(CFG_HOST), \ @@ -92,6 +93,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \ $$(LLVM_LIBDIR_RUSTFLAGS_$(2)) \ $$(LLVM_STDCPP_RUSTFLAGS_$(2)) \ $$(RUSTFLAGS_$(4)) \ + $$(RUSTFLAGS_$(4)_T_$(2)) \ --out-dir $$(@D) \ -C extra-filename=-$$(CFG_FILENAME_EXTRA) \ $$< diff --git a/src/etc/mklldef.py b/src/etc/mklldef.py new file mode 100644 index 00000000000..d2f8ee469a4 --- /dev/null +++ b/src/etc/mklldef.py @@ -0,0 +1,25 @@ +# Copyright 2015 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. + +import sys + +input_file = sys.argv[1] +output_file = sys.argv[2] +name = sys.argv[3] + +with open(input_file, 'r') as f: + with open(output_file, 'w') as g: + print >> g, 'LIBRARY ' + name + print >> g, 'EXPORTS' + for x in f: + x = str(x) + if not x.startswith(' pub fn LLVM'): continue + name = x[11:x.find('(')] + print >> g, ' ' + name |
