Bug 1522614 - Move rust related rules/setup to a separate makefile. r=froydnj

Because we're going to change how cargo recipes are called to export
environment variables rather than by wrapping the call with `env`, to
avoid msys roundtrips, it's better to avoid the complexity when not
building rust, and including a separate file only when required helps
with that. It is also possible to wrap the entire rust section of
rules.mk in the same condition we use for the include, but using a
separate file also makes things clearer.

Differential Revision: https://phabricator.services.mozilla.com/D18180

--HG--
rename : config/rules.mk => config/makefiles/rust.mk
extra : moz-landing-system : lando
This commit is contained in:
Mike Hommey 2019-02-05 21:38:42 +00:00
parent 6defc0874e
commit f23ed044ba
2 changed files with 283 additions and 276 deletions

281
config/makefiles/rust.mk Normal file
View File

@ -0,0 +1,281 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
cargo_host_flag := --target=$(RUST_HOST_TARGET)
cargo_target_flag := --target=$(RUST_TARGET)
# Permit users to pass flags to cargo from their mozconfigs (e.g. --color=always).
cargo_build_flags = $(CARGOFLAGS)
ifndef MOZ_DEBUG_RUST
cargo_build_flags += --release
endif
# The Spidermonkey library can be built from a package tarball outside the
# tree, so we want to let Cargo create lock files in this case. When built
# within a tree, the Rust dependencies have been vendored in so Cargo won't
# touch the lock file.
ifndef JS_STANDALONE
cargo_build_flags += --frozen
endif
cargo_build_flags += --manifest-path $(CARGO_FILE)
ifdef BUILD_VERBOSE_LOG
cargo_build_flags += -vv
endif
# Enable color output if original stdout was a TTY and color settings
# aren't already present. This essentially restores the default behavior
# of cargo when running via `mach`.
ifdef MACH_STDOUT_ISATTY
ifeq (,$(findstring --color,$(cargo_build_flags)))
cargo_build_flags += --color=always
endif
endif
# These flags are passed via `cargo rustc` and only apply to the final rustc
# invocation (i.e., only the top-level crate, not its dependencies).
cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
ifndef DEVELOPER_OPTIONS
ifndef MOZ_DEBUG_RUST
# Enable link-time optimization for release builds.
cargo_rustc_flags += -C lto
endif
endif
ifdef CARGO_INCREMENTAL
cargo_incremental := CARGO_INCREMENTAL=$(CARGO_INCREMENTAL)
endif
rustflags_neon =
ifeq (neon,$(MOZ_FPU))
rustflags_neon += -C target_feature=+neon
endif
rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon)
ifdef MOZ_USING_SCCACHE
sccache_wrap := RUSTC_WRAPPER='$(CCACHE)'
endif
ifdef MOZ_CODE_COVERAGE
ifeq (gcc,$(CC_TYPE))
CODE_COVERAGE_GCC=1
endif
endif
ifndef MOZ_ASAN
ifndef MOZ_TSAN
ifndef MOZ_UBSAN
ifneq (1,$(CODE_COVERAGE_GCC))
ifndef FUZZING_INTERFACES
# Pass the compilers and flags in use to cargo for use in build scripts.
# * Don't do this for ASAN/TSAN builds because we don't pass our custom linker (see below)
# which will muck things up.
# * Don't do this for GCC code coverage builds because the way rustc invokes the linker doesn't
# work with GCC 6: https://bugzilla.mozilla.org/show_bug.cgi?id=1477305
#
# We don't pass HOST_{CC,CXX} down in any form because our host value might not match
# what cargo chooses and there's no way to control cargo's selection, so we just have to
# hope that if something needs to build a host C source file it can find a usable compiler!
#
# We're passing these for consumption by the `cc` crate, which doesn't use the same
# convention as cargo itself:
# https://github.com/alexcrichton/cc-rs/blob/baa71c0e298d9ad7ac30f0ad78f20b4b3b3a8fb2/src/lib.rs#L1715
rust_cc_env_name := $(subst -,_,$(RUST_TARGET))
ifeq (WINNT,$(HOST_OS_ARCH))
# Don't do most of this on Windows because msys path translation makes a mess of the paths, and
# we put MSVC in PATH there anyway. But we do suppress warnings, since all such warnings
# are in third-party code.
cargo_c_compiler_envs := \
CFLAGS_$(rust_cc_env_name)="-w" \
$(NULL)
else
cargo_c_compiler_envs := \
CC_$(rust_cc_env_name)="$(CC)" \
CXX_$(rust_cc_env_name)="$(CXX)" \
CFLAGS_$(rust_cc_env_name)="$(COMPUTED_CFLAGS)" \
CXXFLAGS_$(rust_cc_env_name)="$(COMPUTED_CXXFLAGS)" \
AR_$(rust_cc_env_name)="$(AR)" \
$(NULL)
endif # WINNT
endif # FUZZING_INTERFACES
endif # MOZ_CODE_COVERAGE
endif # MOZ_UBSAN
endif # MOZ_TSAN
endif # MOZ_ASAN
# We use the + prefix to pass down the jobserver fds to cargo, but we
# don't use the prefix when make -n is used, so that cargo doesn't run
# in that case)
define RUN_CARGO
$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(sccache_wrap) \
CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \
RUSTFLAGS='$(2)' \
RUSTC=$(RUSTC) \
RUSTDOC=$(RUSTDOC) \
RUSTFMT=$(RUSTFMT) \
$(cargo_c_compiler_envs) \
MOZ_SRC=$(topsrcdir) \
MOZ_DIST=$(ABS_DIST) \
LIBCLANG_PATH="$(MOZ_LIBCLANG_PATH)" \
CLANG_PATH="$(MOZ_CLANG_PATH)" \
PKG_CONFIG_ALLOW_CROSS=1 \
RUST_BACKTRACE=full \
MOZ_TOPOBJDIR=$(topobjdir) \
$(cargo_incremental) \
$(3) \
$(CARGO) $(1) $(cargo_build_flags)
endef
# This function is intended to be called by:
#
# $(call CARGO_BUILD,EXTRA_ENV_VAR1=X EXTRA_ENV_VAR2=Y ...)
#
# but, given the idiosyncracies of make, can also be called without arguments:
#
# $(call CARGO_BUILD)
define CARGO_BUILD_HOST
$(call RUN_CARGO,rustc,$(rustflags_override),$(1))
endef
define CARGO_CHECK_HOST
$(call RUN_CARGO,check,$(rustflags_override),$(1))
endef
define CARGO_BUILD
$(call RUN_CARGO,rustc,$(rustflags_override) $(RUSTFLAGS),$(1))
endef
define CARGO_CHECK
$(call RUN_CARGO,check,$(rustflags_override) $(RUSTFLAGS),$(1))
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/TSan builds results in crashes while running
# some crates's build scripts (!), so disable it for now.
ifndef MOZ_ASAN
ifndef MOZ_TSAN
ifndef MOZ_UBSAN
ifndef FUZZING_INTERFACES
# Cargo needs the same linker flags as the C/C++ compiler,
# but not the final libraries. Filter those out because they
# cause problems on macOS 10.7; see bug 1365993 for details.
# Also, we don't want to pass PGO flags until cargo supports them.
target_cargo_env_vars := \
MOZ_CARGO_WRAP_LDFLAGS="$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))" \
MOZ_CARGO_WRAP_LD="$(CC)" \
$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
endif # FUZZING_INTERFACES
endif # MOZ_UBSAN
endif # MOZ_TSAN
endif # MOZ_ASAN
endif # ifneq WINNT
ifdef RUST_LIBRARY_FILE
ifdef RUST_LIBRARY_FEATURES
rust_features_flag := --features "$(RUST_LIBRARY_FEATURES)"
endif
# Assume any system libraries rustc links against are already in the target's LIBS.
#
# We need to run cargo unconditionally, because cargo is the only thing that
# has full visibility into how changes in Rust sources might affect the final
# build.
#
# When we are building in --enable-release mode; we add an additional check to confirm
# that we are not importing any networking-related functions in rust code. This reduces
# the chance of proxy bypasses originating from rust code.
force-cargo-library-build:
$(REPORT_BUILD)
$(call CARGO_BUILD,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
ifndef DEVELOPER_OPTIONS
ifndef MOZ_DEBUG_RUST
ifeq ($(OS_ARCH), Linux)
$(call py_action,check_binary,--target --networking $(RUST_LIBRARY_FILE))
endif
endif
endif
$(RUST_LIBRARY_FILE): force-cargo-library-build
force-cargo-library-check:
$(call CARGO_CHECK,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag)
else
force-cargo-library-check:
@true
endif # RUST_LIBRARY_FILE
ifdef RUST_TESTS
rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
ifdef RUST_TEST_FEATURES
rust_features_flag := --features "$(RUST_TEST_FEATURES)"
endif
# Don't stop at the first failure. We want to list all failures together.
rust_test_flag := --no-fail-fast
force-cargo-test-run:
$(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_features_flag),$(rustflags_override) $(RUSTFLAGS),$(target_cargo_env_vars))
endif
ifdef HOST_RUST_LIBRARY_FILE
ifdef HOST_RUST_LIBRARY_FEATURES
host_rust_features_flag := --features "$(HOST_RUST_LIBRARY_FEATURES)"
endif
force-cargo-host-library-build:
$(REPORT_BUILD)
$(call CARGO_BUILD_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag)
$(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build
force-cargo-host-library-check:
$(call CARGO_CHECK_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag)
else
force-cargo-host-library-check:
@true
endif # HOST_RUST_LIBRARY_FILE
ifdef RUST_PROGRAMS
force-cargo-program-build:
$(REPORT_BUILD)
$(call CARGO_BUILD,$(target_cargo_env_vars)) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
$(RUST_PROGRAMS): force-cargo-program-build
force-cargo-program-check:
$(call CARGO_CHECK,$(target_cargo_env_vars)) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
else
force-cargo-program-check:
@true
endif # RUST_PROGRAMS
ifdef HOST_RUST_PROGRAMS
force-cargo-host-program-build:
$(REPORT_BUILD)
$(call CARGO_BUILD_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
$(HOST_RUST_PROGRAMS): force-cargo-host-program-build
force-cargo-host-program-check:
$(REPORT_BUILD)
$(call CARGO_CHECK_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
else
force-cargo-host-program-check:
@true
endif # HOST_RUST_PROGRAMS

View File

@ -800,284 +800,10 @@ else ifdef MOZ_CRASHREPORTER
$(foreach file,$(DUMP_SYMS_TARGETS),$(eval $(call syms_template,$(file),$(notdir $(file))_syms.track)))
endif
cargo_host_flag := --target=$(RUST_HOST_TARGET)
cargo_target_flag := --target=$(RUST_TARGET)
# Permit users to pass flags to cargo from their mozconfigs (e.g. --color=always).
cargo_build_flags = $(CARGOFLAGS)
ifndef MOZ_DEBUG_RUST
cargo_build_flags += --release
ifneq (,$(RUST_TESTS)$(RUST_LIBRARY_FILE)$(HOST_RUST_LIBRARY_FILE)$(RUST_PROGRAMS)$(HOST_RUST_PROGRAMS))
include $(MOZILLA_DIR)/config/makefiles/rust.mk
endif
# The Spidermonkey library can be built from a package tarball outside the
# tree, so we want to let Cargo create lock files in this case. When built
# within a tree, the Rust dependencies have been vendored in so Cargo won't
# touch the lock file.
ifndef JS_STANDALONE
cargo_build_flags += --frozen
endif
cargo_build_flags += --manifest-path $(CARGO_FILE)
ifdef BUILD_VERBOSE_LOG
cargo_build_flags += -vv
endif
# Enable color output if original stdout was a TTY and color settings
# aren't already present. This essentially restores the default behavior
# of cargo when running via `mach`.
ifdef MACH_STDOUT_ISATTY
ifeq (,$(findstring --color,$(cargo_build_flags)))
cargo_build_flags += --color=always
endif
endif
# These flags are passed via `cargo rustc` and only apply to the final rustc
# invocation (i.e., only the top-level crate, not its dependencies).
cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
ifndef DEVELOPER_OPTIONS
ifndef MOZ_DEBUG_RUST
# Enable link-time optimization for release builds.
cargo_rustc_flags += -C lto
endif
endif
ifdef CARGO_INCREMENTAL
cargo_incremental := CARGO_INCREMENTAL=$(CARGO_INCREMENTAL)
endif
rustflags_neon =
ifeq (neon,$(MOZ_FPU))
rustflags_neon += -C target_feature=+neon
endif
rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon)
ifdef MOZ_USING_SCCACHE
sccache_wrap := RUSTC_WRAPPER='$(CCACHE)'
endif
ifdef MOZ_CODE_COVERAGE
ifeq (gcc,$(CC_TYPE))
CODE_COVERAGE_GCC=1
endif
endif
ifndef MOZ_ASAN
ifndef MOZ_TSAN
ifndef MOZ_UBSAN
ifneq (1,$(CODE_COVERAGE_GCC))
ifndef FUZZING_INTERFACES
# Pass the compilers and flags in use to cargo for use in build scripts.
# * Don't do this for ASAN/TSAN builds because we don't pass our custom linker (see below)
# which will muck things up.
# * Don't do this for GCC code coverage builds because the way rustc invokes the linker doesn't
# work with GCC 6: https://bugzilla.mozilla.org/show_bug.cgi?id=1477305
#
# We don't pass HOST_{CC,CXX} down in any form because our host value might not match
# what cargo chooses and there's no way to control cargo's selection, so we just have to
# hope that if something needs to build a host C source file it can find a usable compiler!
#
# We're passing these for consumption by the `cc` crate, which doesn't use the same
# convention as cargo itself:
# https://github.com/alexcrichton/cc-rs/blob/baa71c0e298d9ad7ac30f0ad78f20b4b3b3a8fb2/src/lib.rs#L1715
rust_cc_env_name := $(subst -,_,$(RUST_TARGET))
ifeq (WINNT,$(HOST_OS_ARCH))
# Don't do most of this on Windows because msys path translation makes a mess of the paths, and
# we put MSVC in PATH there anyway. But we do suppress warnings, since all such warnings
# are in third-party code.
cargo_c_compiler_envs := \
CFLAGS_$(rust_cc_env_name)="-w" \
$(NULL)
else
cargo_c_compiler_envs := \
CC_$(rust_cc_env_name)="$(CC)" \
CXX_$(rust_cc_env_name)="$(CXX)" \
CFLAGS_$(rust_cc_env_name)="$(COMPUTED_CFLAGS)" \
CXXFLAGS_$(rust_cc_env_name)="$(COMPUTED_CXXFLAGS)" \
AR_$(rust_cc_env_name)="$(AR)" \
$(NULL)
endif # WINNT
endif # FUZZING_INTERFACES
endif # MOZ_CODE_COVERAGE
endif # MOZ_UBSAN
endif # MOZ_TSAN
endif # MOZ_ASAN
# We use the + prefix to pass down the jobserver fds to cargo, but we
# don't use the prefix when make -n is used, so that cargo doesn't run
# in that case)
define RUN_CARGO
$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)env $(sccache_wrap) \
CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) \
RUSTFLAGS='$(2)' \
RUSTC=$(RUSTC) \
RUSTDOC=$(RUSTDOC) \
RUSTFMT=$(RUSTFMT) \
$(cargo_c_compiler_envs) \
MOZ_SRC=$(topsrcdir) \
MOZ_DIST=$(ABS_DIST) \
LIBCLANG_PATH="$(MOZ_LIBCLANG_PATH)" \
CLANG_PATH="$(MOZ_CLANG_PATH)" \
PKG_CONFIG_ALLOW_CROSS=1 \
RUST_BACKTRACE=full \
MOZ_TOPOBJDIR=$(topobjdir) \
$(cargo_incremental) \
$(3) \
$(CARGO) $(1) $(cargo_build_flags)
endef
# This function is intended to be called by:
#
# $(call CARGO_BUILD,EXTRA_ENV_VAR1=X EXTRA_ENV_VAR2=Y ...)
#
# but, given the idiosyncracies of make, can also be called without arguments:
#
# $(call CARGO_BUILD)
define CARGO_BUILD_HOST
$(call RUN_CARGO,rustc,$(rustflags_override),$(1))
endef
define CARGO_CHECK_HOST
$(call RUN_CARGO,check,$(rustflags_override),$(1))
endef
define CARGO_BUILD
$(call RUN_CARGO,rustc,$(rustflags_override) $(RUSTFLAGS),$(1))
endef
define CARGO_CHECK
$(call RUN_CARGO,check,$(rustflags_override) $(RUSTFLAGS),$(1))
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/TSan builds results in crashes while running
# some crates's build scripts (!), so disable it for now.
ifndef MOZ_ASAN
ifndef MOZ_TSAN
ifndef MOZ_UBSAN
ifndef FUZZING_INTERFACES
# Cargo needs the same linker flags as the C/C++ compiler,
# but not the final libraries. Filter those out because they
# cause problems on macOS 10.7; see bug 1365993 for details.
# Also, we don't want to pass PGO flags until cargo supports them.
target_cargo_env_vars := \
MOZ_CARGO_WRAP_LDFLAGS="$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))" \
MOZ_CARGO_WRAP_LD="$(CC)" \
$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
endif # FUZZING_INTERFACES
endif # MOZ_UBSAN
endif # MOZ_TSAN
endif # MOZ_ASAN
endif # ifneq WINNT
ifdef RUST_LIBRARY_FILE
ifdef RUST_LIBRARY_FEATURES
rust_features_flag := --features "$(RUST_LIBRARY_FEATURES)"
endif
# Assume any system libraries rustc links against are already in the target's LIBS.
#
# We need to run cargo unconditionally, because cargo is the only thing that
# has full visibility into how changes in Rust sources might affect the final
# build.
#
# When we are building in --enable-release mode; we add an additional check to confirm
# that we are not importing any networking-related functions in rust code. This reduces
# the chance of proxy bypasses originating from rust code.
force-cargo-library-build:
$(REPORT_BUILD)
$(call CARGO_BUILD,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
ifndef DEVELOPER_OPTIONS
ifndef MOZ_DEBUG_RUST
ifeq ($(OS_ARCH), Linux)
$(call py_action,check_binary,--target --networking $(RUST_LIBRARY_FILE))
endif
endif
endif
$(RUST_LIBRARY_FILE): force-cargo-library-build
force-cargo-library-check:
$(call CARGO_CHECK,$(target_cargo_env_vars)) --lib $(cargo_target_flag) $(rust_features_flag)
else
force-cargo-library-check:
@true
endif # RUST_LIBRARY_FILE
ifdef RUST_TESTS
rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
ifdef RUST_TEST_FEATURES
rust_features_flag := --features "$(RUST_TEST_FEATURES)"
endif
# Don't stop at the first failure. We want to list all failures together.
rust_test_flag := --no-fail-fast
force-cargo-test-run:
$(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_features_flag),$(rustflags_override) $(RUSTFLAGS),$(target_cargo_env_vars))
endif
ifdef HOST_RUST_LIBRARY_FILE
ifdef HOST_RUST_LIBRARY_FEATURES
host_rust_features_flag := --features "$(HOST_RUST_LIBRARY_FEATURES)"
endif
force-cargo-host-library-build:
$(REPORT_BUILD)
$(call CARGO_BUILD_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag)
$(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build
force-cargo-host-library-check:
$(call CARGO_CHECK_HOST) --lib $(cargo_host_flag) $(host_rust_features_flag)
else
force-cargo-host-library-check:
@true
endif # HOST_RUST_LIBRARY_FILE
ifdef RUST_PROGRAMS
force-cargo-program-build:
$(REPORT_BUILD)
$(call CARGO_BUILD,$(target_cargo_env_vars)) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
$(RUST_PROGRAMS): force-cargo-program-build
force-cargo-program-check:
$(call CARGO_CHECK,$(target_cargo_env_vars)) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
else
force-cargo-program-check:
@true
endif # RUST_PROGRAMS
ifdef HOST_RUST_PROGRAMS
force-cargo-host-program-build:
$(REPORT_BUILD)
$(call CARGO_BUILD_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
$(HOST_RUST_PROGRAMS): force-cargo-host-program-build
force-cargo-host-program-check:
$(REPORT_BUILD)
$(call CARGO_CHECK_HOST) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
else
force-cargo-host-program-check:
@true
endif # HOST_RUST_PROGRAMS
$(SOBJS):
$(REPORT_BUILD)
$(AS) $(ASOUTOPTION)$@ $(SFLAGS) $($(notdir $<)_FLAGS) -c $<