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.
This commit is contained in:
parent
ce8b317558
commit
b538189ba0
@ -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)
|
||||
|
@ -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) \
|
||||
$$<
|
||||
|
25
src/etc/mklldef.py
Normal file
25
src/etc/mklldef.py
Normal file
@ -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
|
Loading…
x
Reference in New Issue
Block a user