@@ -238,3 +238,72 @@ endef
238
238
239
239
$(foreach target,$(CFG_TARGET), \
240
240
$(eval $(call CFG_MAKE_TOOLCHAIN,$(target))))
241
+
242
+ # These two environment variables are scraped by the `./configure` script and
243
+ # are necessary for `cl.exe` to find standard headers (the INCLUDE variable) and
244
+ # for `link.exe` to find standard libraries (the LIB variable).
245
+ ifdef CFG_MSVC_INCLUDE_PATH
246
+ export INCLUDE := $(CFG_MSVC_INCLUDE_PATH )
247
+ endif
248
+ ifdef CFG_MSVC_LIB_PATH
249
+ export LIB := $(CFG_MSVC_LIB_PATH )
250
+ endif
251
+
252
+ # Unfortunately `link.exe` is also a program in `/usr/bin` on MinGW installs,
253
+ # but it's not the one that we want. As a result we make sure that our detected
254
+ # `link.exe` shows up in PATH first.
255
+ ifdef CFG_MSVC_LINK
256
+ export PATH := $(CFG_MSVC_ROOT ) /VC/bin/amd64:$(PATH )
257
+ endif
258
+
259
+ # There are more comments about this available in the target specification for
260
+ # Windows MSVC in the compiler, but the gist of it is that we use `llvm-ar.exe`
261
+ # instead of `lib.exe` for assembling archives, so we need to inject this custom
262
+ # dependency here.
263
+ define ADD_LLVM_AR_TO_MSVC_DEPS
264
+ ifeq ($$(findstring msvc,$(1 ) ) ,msvc)
265
+ NATIVE_TOOL_DEPS_core_T_$(1) += llvm-ar.exe
266
+ INSTALLED_BINS_$(1) += llvm-ar.exe
267
+ endif
268
+ endef
269
+
270
+ $(foreach target,$(CFG_TARGET), \
271
+ $(eval $(call ADD_LLVM_AR_TO_MSVC_DEPS,$(target))))
272
+
273
+ # When working with MSVC on windows, each DLL needs to explicitly declare its
274
+ # interface to the outside world through some means. The options for doing so
275
+ # include:
276
+ #
277
+ # 1. A custom attribute on each function itself
278
+ # 2. A linker argument saying what to export
279
+ # 3. A file which lists all symbols that need to be exported
280
+ #
281
+ # The Rust compiler takes care (1) for us for all Rust code by annotating all
282
+ # public-facing functions with dllexport, but we have a few native dependencies
283
+ # which need to cross the DLL boundary. The most important of these dependencies
284
+ # is LLVM which is linked into `rustc_llvm.dll` but primarily used from
285
+ # `rustc_trans.dll`. This means that many of LLVM's C API functions need to be
286
+ # exposed from `rustc_llvm.dll` to be forwarded over the boundary.
287
+ #
288
+ # Unfortunately, at this time, LLVM does not handle this sort of exportation on
289
+ # Windows for us, so we're forced to do it ourselves if we want it (which seems
290
+ # like the path of least resistance right now). To do this we generate a `.DEF`
291
+ # file [1] which we then custom-pass to the linker when building the rustc_llvm
292
+ # crate. This DEF file list all symbols that are exported from
293
+ # `src/librustc_llvm/lib.rs` and is generated by a small python script.
294
+ #
295
+ # Fun times!
296
+ #
297
+ # [1]: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx
298
+ define ADD_RUSTC_LLVM_DEF_TO_MSVC
299
+ ifeq ($$(findstring msvc,$(1 ) ) ,msvc)
300
+ RUSTFLAGS_rustc_llvm_T_$(1) += -C link-args="-DEF:$(1 ) /rt/rustc_llvm.def"
301
+ CUSTOM_DEPS_rustc_llvm_T_$(1) += $(1 ) /rt/rustc_llvm.def
302
+
303
+ $(1 ) /rt/rustc_llvm.def : $$(S ) src/etc/mklldef.py $$(S ) src/librustc_llvm/lib.rs
304
+ $$(CFG_PYTHON ) $$^ $$@ rustc_llvm-$$(CFG_FILENAME_EXTRA )
305
+ endif
306
+ endef
307
+
308
+ $(foreach target,$(CFG_TARGET), \
309
+ $(eval $(call ADD_RUSTC_LLVM_DEF_TO_MSVC,$(target))))
0 commit comments