Bug 1329737 - part 3 - use an alternate linker for Cargo invocations; r=rillian

For linking static libraries, rustc will use whatever `cc` it finds (or
the equivalent on Windows).  For our purposes, however, `cc` is not what
we use to link and we may have additional options we would like to pass
to the linker.

To do this, we need to tell Cargo about our alternate linker (currently
only used for target compilations, on the theory that the host compiler
rustc finds is probably good enough) and we also need to pass our linker
options into the process.  We do this with environment variables, which
is not a great solution, but works surprisingly well.

This alternate linker is disabled for ASan builds due to peculiar
crashes when running Rust build scripts and for Windows, because we
don't do any interesting cross-compiling there.
This commit is contained in:
Nathan Froyd 2017-04-28 14:06:41 -04:00
parent 67c11f7395
commit d3325ce1a2
2 changed files with 42 additions and 2 deletions

20
build/cargo-linker Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
# If you want to use a custom linker with Cargo, Cargo requires that you
# specify it in Cargo.toml or via the matching environment variable.
# Passing extra options to the linker is possible with Cargo via
# RUSTFLAGS='-C link-args', but testing showed that doing this reliably
# was difficult.
#
# Our solution to these problems is to use this wrapper script. We pass
# in the LD and the LDFLAGS to use via environment variables. Note that
# we do *not* quote either MOZ_CARGO_WRAP variable:
#
# * MOZ_CARGO_WRAP_LD is equivalent to CC on Unix-y platforms, and CC
# frequently has additional arguments in addition to the compiler
# itself.
# * MOZ_CARGO_WRAP_LDFLAGS contains space-separated arguments to pass,
# and not quoting it ensures that either of those arguments is passed
# as a separate argument to the actual LD.
${MOZ_CARGO_WRAP_LD} ${MOZ_CARGO_WRAP_LDFLAGS} "$@"

View File

@ -984,6 +984,26 @@ env $(environment_cleaner) $(rustflags_override) \
$(CARGO) build $(cargo_build_flags) $(CARGO) build $(cargo_build_flags)
endef endef
cargo_linker_env_var := CARGO_TARGET_$(RUST_TARGET_ENV_NAME)_LINKER
# Don't define a custom linker on Windows, as it's difficult to have a
# non-binary file that will get executed correctly by Cargo. We don't
# have to worry about a cross-compiling (besides x86-64 -> x86, which
# already works with the current setup) setup on Windows, and we don't
# have to pass in any special linker options on Windows.
ifneq (WINNT,$(OS_ARCH))
# Defining all of this for ASan builds results in crashes while running
# some crates's build scripts (!), so disable it for now.
ifndef MOZ_ASAN
target_cargo_env_vars := \
MOZ_CARGO_WRAP_LDFLAGS="$(LDFLAGS)" \
MOZ_CARGO_WRAP_LD="$(CC)" \
$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
endif # MOZ_ASAN
endif # ifneq WINNT
ifdef RUST_LIBRARY_FILE ifdef RUST_LIBRARY_FILE
ifdef RUST_LIBRARY_FEATURES ifdef RUST_LIBRARY_FEATURES
@ -997,7 +1017,7 @@ endif
# build. # build.
force-cargo-library-build: force-cargo-library-build:
$(REPORT_BUILD) $(REPORT_BUILD)
$(call CARGO_BUILD) --lib $(cargo_target_flag) $(rust_features_flag) $(call CARGO_BUILD,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag)
$(RUST_LIBRARY_FILE): force-cargo-library-build $(RUST_LIBRARY_FILE): force-cargo-library-build
endif # RUST_LIBRARY_FILE endif # RUST_LIBRARY_FILE
@ -1018,7 +1038,7 @@ endif # HOST_RUST_LIBRARY_FILE
ifdef RUST_PROGRAMS ifdef RUST_PROGRAMS
force-cargo-program-build: force-cargo-program-build:
$(REPORT_BUILD) $(REPORT_BUILD)
$(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) $(call CARGO_BUILD,$(target_cargo_env_vars)) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
$(RUST_PROGRAMS): force-cargo-program-build $(RUST_PROGRAMS): force-cargo-program-build
endif # RUST_PROGRAMS endif # RUST_PROGRAMS