Bug 1838739 - Initialize result of SetAsGPUOutOfMemoryError. r=webgpu-reviewers,nical
[gecko.git] / config / makefiles / rust.mk
blobefbe4827383b9e3b80fd04e2f08dd7ae9321ddf6
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 # You can obtain one at http://mozilla.org/MPL/2.0/.
5 # /!\ In this file, we export multiple variables globally via make rather than
6 # in recipes via the `env` command to avoid round-trips to msys on Windows, which
7 # tend to break environment variable values in interesting ways.
9 # /!\ Avoid the use of double-quotes in this file, so that the cargo
10 # commands can be executed directly by make, without doing a round-trip
11 # through a shell.
13 cargo_host_flag := --target=$(RUST_HOST_TARGET)
14 cargo_target_flag := --target=$(RUST_TARGET)
16 # Permit users to pass flags to cargo from their mozconfigs (e.g. --color=always).
17 cargo_build_flags = $(CARGOFLAGS)
18 ifndef MOZ_DEBUG_RUST
19 cargo_build_flags += --release
20 endif
22 # The Spidermonkey library can be built from a package tarball outside the
23 # tree, so we want to let Cargo create lock files in this case. When built
24 # within a tree, the Rust dependencies have been vendored in so Cargo won't
25 # touch the lock file.
26 ifndef JS_STANDALONE
27 cargo_build_flags += --frozen
28 endif
30 cargo_build_flags += --manifest-path $(CARGO_FILE)
31 ifdef BUILD_VERBOSE_LOG
32 cargo_build_flags += -vv
33 endif
35 ifneq (,$(USE_CARGO_JSON_MESSAGE_FORMAT))
36 cargo_build_flags += --message-format=json
37 endif
39 # Enable color output if original stdout was a TTY and color settings
40 # aren't already present. This essentially restores the default behavior
41 # of cargo when running via `mach`.
42 ifdef MACH_STDOUT_ISATTY
43 ifeq (,$(findstring --color,$(cargo_build_flags)))
44 ifdef NO_ANSI
45 cargo_build_flags += --color=never
46 else
47 cargo_build_flags += --color=always
48 endif
49 endif
50 endif
52 # Without -j > 1, make will not pass jobserver info down to cargo. Force
53 # one job when requested as a special case.
54 cargo_build_flags += $(filter -j1,$(MAKEFLAGS))
56 # We also need to rebuild the rust stdlib so that it's instrumented. Because
57 # build-std is still pretty experimental, we need to explicitly request
58 # the panic_abort crate for `panic = "abort"` support.
59 ifdef MOZ_TSAN
60 cargo_build_flags += -Zbuild-std=std,panic_abort
61 RUSTFLAGS += -Zsanitizer=thread
62 endif
64 rustflags_sancov =
65 ifdef LIBFUZZER
66 ifndef MOZ_TSAN
67 ifndef FUZZING_JS_FUZZILLI
68 # These options should match what is implicitly enabled for `clang -fsanitize=fuzzer`
69 # here: https://github.com/llvm/llvm-project/blob/release/13.x/clang/lib/Driver/SanitizerArgs.cpp#L422
71 # -sanitizer-coverage-inline-8bit-counters Increments 8-bit counter for every edge.
72 # -sanitizer-coverage-level=4 Enable coverage for all blocks, critical edges, and indirect calls.
73 # -sanitizer-coverage-trace-compares Tracing of CMP and similar instructions.
74 # -sanitizer-coverage-pc-table Create a static PC table.
76 # In TSan builds, we must not pass any of these, because sanitizer coverage is incompatible with TSan.
77 rustflags_sancov += -Cpasses=sancov-module -Cllvm-args=-sanitizer-coverage-inline-8bit-counters -Cllvm-args=-sanitizer-coverage-level=4 -Cllvm-args=-sanitizer-coverage-trace-compares -Cllvm-args=-sanitizer-coverage-pc-table
78 endif
79 endif
80 endif
82 # These flags are passed via `cargo rustc` and only apply to the final rustc
83 # invocation (i.e., only the top-level crate, not its dependencies).
84 cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
85 ifndef DEVELOPER_OPTIONS
86 ifndef MOZ_DEBUG_RUST
87 # Enable link-time optimization for release builds, but not when linking
88 # gkrust_gtest. And not when doing cross-language LTO.
89 ifndef MOZ_LTO_RUST_CROSS
90 # Never enable when sancov is enabled to work around https://github.com/rust-lang/rust/issues/90300.
91 ifndef rustflags_sancov
92 # Never enable when coverage is enabled to work around https://github.com/rust-lang/rust/issues/90045.
93 ifndef MOZ_CODE_COVERAGE
94 ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE)))
95 cargo_rustc_flags += -Clto$(if $(filter full,$(MOZ_LTO_RUST_CROSS)),=fat)
96 endif
97 # We need -Cembed-bitcode=yes for all crates when using -Clto.
98 RUSTFLAGS += -Cembed-bitcode=yes
99 endif
100 endif
101 endif
102 endif
103 endif
105 ifdef CARGO_INCREMENTAL
106 export CARGO_INCREMENTAL
107 endif
109 rustflags_neon =
110 ifeq (neon,$(MOZ_FPU))
111 ifneq (,$(filter thumbv7neon-,$(RUST_TARGET)))
112 # Enable neon and disable restriction to 16 FPU registers when neon is enabled
113 # but we're not using a thumbv7neon target, where it's already the default.
114 # (CPUs with neon have 32 FPU registers available)
115 rustflags_neon += -C target_feature=+neon,-d16
116 endif
117 endif
119 rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon)
121 ifdef DEVELOPER_OPTIONS
122 # By default the Rust compiler will perform a limited kind of ThinLTO on each
123 # crate. For local builds this additional optimization is not worth the
124 # increase in compile time so we opt out of it.
125 rustflags_override += -Clto=off
126 endif
128 ifdef MOZ_USING_SCCACHE
129 export RUSTC_WRAPPER=$(CCACHE)
130 endif
132 ifndef CROSS_COMPILE
133 ifdef MOZ_TSAN
134 PASS_ONLY_BASE_CFLAGS_TO_RUST=1
135 else
136 ifneq (,$(MOZ_ASAN)$(MOZ_UBSAN))
137 ifneq ($(OS_ARCH), Linux)
138 PASS_ONLY_BASE_CFLAGS_TO_RUST=1
139 endif # !Linux
140 endif # MOZ_ASAN || MOZ_UBSAN
141 endif # MOZ_TSAN
142 endif # !CROSS_COMPILE
144 ifeq (WINNT,$(HOST_OS_ARCH))
145 ifdef MOZ_CODE_COVERAGE
146 PASS_ONLY_BASE_CFLAGS_TO_RUST=1
147 endif # MOZ_CODE_COVERAGE
148 endif # WINNT
150 # We start with host variables because the rust host and the rust target might be the same,
151 # in which case we want the latter to take priority.
153 # We're passing these for consumption by the `cc` crate, which doesn't use the same
154 # convention as cargo itself:
155 # https://github.com/alexcrichton/cc-rs/blob/baa71c0e298d9ad7ac30f0ad78f20b4b3b3a8fb2/src/lib.rs#L1715
156 rust_host_cc_env_name := $(subst -,_,$(RUST_HOST_TARGET))
158 # HOST_CC/HOST_CXX/CC/CXX usually contain base flags for e.g. the build target.
159 # We want to pass those through CFLAGS_*/CXXFLAGS_* instead, so that they end up
160 # after whatever cc-rs adds to the compiler command line, so that they win.
161 # Ideally, we'd use CRATE_CC_NO_DEFAULTS=1, but that causes other problems at the
162 # moment.
163 export CC_$(rust_host_cc_env_name)=$(filter-out $(HOST_CC_BASE_FLAGS),$(HOST_CC))
164 export CXX_$(rust_host_cc_env_name)=$(filter-out $(HOST_CXX_BASE_FLAGS),$(HOST_CXX))
165 export AR_$(rust_host_cc_env_name)=$(HOST_AR)
167 rust_cc_env_name := $(subst -,_,$(RUST_TARGET))
169 export CC_$(rust_cc_env_name)=$(filter-out $(CC_BASE_FLAGS),$(CC))
170 export CXX_$(rust_cc_env_name)=$(filter-out $(CXX_BASE_FLAGS),$(CXX))
171 export AR_$(rust_cc_env_name)=$(AR)
173 ifeq (WINNT,$(HOST_OS_ARCH))
174 HOST_CC_BASE_FLAGS += -DUNICODE
175 HOST_CXX_BASE_FLAGS += -DUNICODE
176 CC_BASE_FLAGS += -DUNICODE
177 CXX_BASE_FLAGS += -DUNICODE
178 endif
180 ifneq (1,$(PASS_ONLY_BASE_CFLAGS_TO_RUST))
181 # -DMOZILLA_CONFIG_H is added to prevent mozilla-config.h from injecting anything
182 # in C/C++ compiles from rust. That's not needed in the other branch because the
183 # base flags don't force-include mozilla-config.h.
184 export CFLAGS_$(rust_host_cc_env_name)=$(HOST_CC_BASE_FLAGS) $(COMPUTED_HOST_CFLAGS) -DMOZILLA_CONFIG_H
185 export CXXFLAGS_$(rust_host_cc_env_name)=$(HOST_CXX_BASE_FLAGS) $(COMPUTED_HOST_CXXFLAGS) -DMOZILLA_CONFIG_H
186 export CFLAGS_$(rust_cc_env_name)=$(CC_BASE_FLAGS) $(COMPUTED_CFLAGS) -DMOZILLA_CONFIG_H
187 export CXXFLAGS_$(rust_cc_env_name)=$(CXX_BASE_FLAGS) $(COMPUTED_CXXFLAGS) -DMOZILLA_CONFIG_H
188 else
189 # Because cargo doesn't allow to distinguish builds happening for build
190 # scripts/procedural macros vs. those happening for the rust target,
191 # we can't blindly pass all our flags down for cc-rs to use them, because of the
192 # side effects they can have on what otherwise should be host builds.
193 # So for sanitizer and coverage builds, we only pass the base compiler flags.
194 # This means C code built by rust is not going to be covered by sanitizers
195 # and coverage. But at least we control what compiler is being used,
196 # rather than relying on cc-rs guesses, which, sometimes fail us.
197 export CFLAGS_$(rust_host_cc_env_name)=$(HOST_CC_BASE_FLAGS)
198 export CXXFLAGS_$(rust_host_cc_env_name)=$(HOST_CXX_BASE_FLAGS)
199 export CFLAGS_$(rust_cc_env_name)=$(CC_BASE_FLAGS)
200 export CXXFLAGS_$(rust_cc_env_name)=$(CXX_BASE_FLAGS)
201 endif
203 # When host == target, cargo will compile build scripts with sanitizers enabled
204 # if sanitizers are enabled, which may randomly fail when they execute
205 # because of https://github.com/google/sanitizers/issues/1322.
206 # Work around by disabling __tls_get_addr interception (bug 1635327).
207 ifeq ($(RUST_TARGET),$(RUST_HOST_TARGET))
208 define sanitizer_options
209 ifdef MOZ_$1
210 export $1_OPTIONS:=$$($1_OPTIONS:%=%:)intercept_tls_get_addr=0
211 endif
212 endef
213 $(foreach san,ASAN TSAN UBSAN,$(eval $(call sanitizer_options,$(san))))
214 endif
216 # Force the target down to all bindgen callers, even those that may not
217 # read BINDGEN_SYSTEM_FLAGS some way or another.
218 export BINDGEN_EXTRA_CLANG_ARGS:=$(filter --target=%,$(BINDGEN_SYSTEM_FLAGS))
219 export CARGO_TARGET_DIR
220 export RUSTFLAGS
221 export RUSTC
222 export RUSTDOC
223 export RUSTFMT
224 export LIBCLANG_PATH=$(MOZ_LIBCLANG_PATH)
225 export CLANG_PATH=$(MOZ_CLANG_PATH)
226 export PKG_CONFIG
227 export PKG_CONFIG_ALLOW_CROSS=1
228 export PKG_CONFIG_PATH
229 ifneq (,$(PKG_CONFIG_SYSROOT_DIR))
230 export PKG_CONFIG_SYSROOT_DIR
231 endif
232 ifneq (,$(PKG_CONFIG_LIBDIR))
233 export PKG_CONFIG_LIBDIR
234 endif
235 export RUST_BACKTRACE=full
236 export MOZ_TOPOBJDIR=$(topobjdir)
237 export MOZ_FOLD_LIBS
238 export PYTHON3
239 export CARGO_PROFILE_RELEASE_OPT_LEVEL
240 export CARGO_PROFILE_DEV_OPT_LEVEL
242 # Set COREAUDIO_SDK_PATH for third_party/rust/coreaudio-sys/build.rs
243 ifeq ($(OS_ARCH), Darwin)
244 ifdef MACOS_SDK_DIR
245 export COREAUDIO_SDK_PATH=$(MACOS_SDK_DIR)
246 endif
247 endif
249 ifndef RUSTC_BOOTSTRAP
250 RUSTC_BOOTSTRAP := mozglue_static,qcms
251 ifdef MOZ_RUST_SIMD
252 RUSTC_BOOTSTRAP := $(RUSTC_BOOTSTRAP),encoding_rs,packed_simd_2
253 endif
254 export RUSTC_BOOTSTRAP
255 endif
257 target_rust_ltoable := force-cargo-library-build $(ADD_RUST_LTOABLE)
258 target_rust_nonltoable := force-cargo-test-run force-cargo-program-build
260 ifdef MOZ_PGO_RUST
261 ifdef MOZ_PROFILE_GENERATE
262 # Our top-level Cargo.toml sets panic to abort, so we technically don't need -C panic=abort,
263 # but the autocfg crate takes RUSTFLAGS verbatim and runs its compiler tests without
264 # -C panic=abort (because it doesn't know it's what cargo uses), which fail on Windows
265 # because -C panic=unwind (the compiler default) is not compatible with -C profile-generate
266 # (https://github.com/rust-lang/rust/issues/61002).
267 rust_pgo_flags := -C panic=abort -C profile-generate=$(topobjdir)
268 ifeq (1,$(words $(filter 5.% 6.% 7.% 8.% 9.% 10.% 11.%,$(CC_VERSION) $(RUSTC_LLVM_VERSION))))
269 # Disable value profiling when:
270 # (RUSTC_LLVM_VERSION < 12 and CC_VERSION >= 12) or (RUSTC_LLVM_VERSION >= 12 and CC_VERSION < 12)
271 rust_pgo_flags += -C llvm-args=--disable-vp=true
272 endif
273 # The C compiler may be passed extra llvm flags for PGO that we also want to pass to rust as well.
274 # In PROFILE_GEN_CFLAGS, they look like "-mllvm foo", and we want "-C llvm-args=foo", so first turn
275 # "-mllvm foo" into "-mllvm:foo" so that it becomes a unique argument, that we can then filter for,
276 # excluding other flags, and then turn into the right string.
277 rust_pgo_flags += $(patsubst -mllvm:%,-C llvm-args=%,$(filter -mllvm:%,$(subst -mllvm ,-mllvm:,$(PROFILE_GEN_CFLAGS))))
278 else # MOZ_PROFILE_USE
279 rust_pgo_flags := -C profile-use=$(PGO_PROFILE_PATH)
280 endif
281 endif
283 $(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) $(rust_pgo_flags) \
284 $(if $(MOZ_LTO_RUST_CROSS),\
285 -Clinker-plugin-lto \
287 $(target_rust_nonltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS)
289 TARGET_RECIPES := $(target_rust_ltoable) $(target_rust_nonltoable)
291 HOST_RECIPES := \
292 $(foreach a,library program,$(foreach b,build check udeps clippy,force-cargo-host-$(a)-$(b)))
294 $(HOST_RECIPES): RUSTFLAGS:=$(rustflags_override)
296 # If this is a release build we want rustc to generate one codegen unit per
297 # crate. This results in better optimization and less code duplication at the
298 # cost of longer compile times.
299 ifndef DEVELOPER_OPTIONS
300 $(TARGET_RECIPES) $(HOST_RECIPES): RUSTFLAGS += -C codegen-units=1
301 endif
303 # We use the + prefix to pass down the jobserver fds to cargo, but we
304 # don't use the prefix when make -n is used, so that cargo doesn't run
305 # in that case)
306 define RUN_CARGO_INNER
307 $(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)$(CARGO) $(1) $(cargo_build_flags) $(CARGO_EXTRA_FLAGS) $(cargo_extra_cli_flags)
308 endef
310 ifdef CARGO_CONTINUE_ON_ERROR
311 define RUN_CARGO
312 -$(RUN_CARGO_INNER)
313 endef
314 else
315 define RUN_CARGO
316 $(RUN_CARGO_INNER)
317 endef
318 endif
320 # This function is intended to be called by:
322 # $(call CARGO_BUILD,EXTRA_ENV_VAR1=X EXTRA_ENV_VAR2=Y ...)
324 # but, given the idiosyncracies of make, can also be called without arguments:
326 # $(call CARGO_BUILD)
327 define CARGO_BUILD
328 $(call RUN_CARGO,rustc)
329 endef
331 cargo_host_linker_env_var := CARGO_TARGET_$(call varize,$(RUST_HOST_TARGET))_LINKER
332 cargo_linker_env_var := CARGO_TARGET_$(call varize,$(RUST_TARGET))_LINKER
334 export MOZ_CLANG_NEWER_THAN_RUSTC_LLVM
335 export MOZ_CARGO_WRAP_LDFLAGS
336 export MOZ_CARGO_WRAP_LD
337 export MOZ_CARGO_WRAP_LD_CXX
338 export MOZ_CARGO_WRAP_HOST_LDFLAGS
339 export MOZ_CARGO_WRAP_HOST_LD
340 export MOZ_CARGO_WRAP_HOST_LD_CXX
341 # Exporting from make always exports a value. Setting a value per-recipe
342 # would export an empty value for the host recipes. When not doing a
343 # cross-compile, the --target for those is the same, and cargo will use
344 # CARGO_TARGET_*_LINKER for its linker, so we always pass the
345 # cargo-linker wrapper, and fill MOZ_CARGO_WRAP_{HOST_,}LD* more or less
346 # appropriately for all recipes.
347 ifeq (WINNT,$(HOST_OS_ARCH))
348 # Use .bat wrapping on Windows hosts, and shell wrapping on other hosts.
349 # Like for CC/C*FLAGS, we want the target values to trump the host values when
350 # both variables are the same.
351 export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker.bat
352 export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker.bat
353 WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS_BAT)
354 else
355 export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker
356 export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker
357 WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS)
358 endif
360 # Cargo needs the same linker flags as the C/C++ compiler,
361 # but not the final libraries. Filter those out because they
362 # cause problems on macOS 10.7; see bug 1365993 for details.
363 # Also, we don't want to pass PGO flags until cargo supports them.
364 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))
366 # When building with sanitizer, rustc links its own runtime, which conflicts
367 # with the one that passing -fsanitize=* to the linker would add.
368 # Ideally, we'd always do this filtering, but because the flags may also apply
369 # to build scripts because cargo doesn't allow the distinction, we only filter
370 # when building programs, except when using thread sanitizer where we filter
371 # everywhere.
372 ifneq (,$(filter -Zsanitizer=%,$(RUSTFLAGS)))
373 $(if $(filter -Zsanitizer=thread,$(RUSTFLAGS)),$(TARGET_RECIPES),force-cargo-program-build): MOZ_CARGO_WRAP_LDFLAGS:=$(filter-out -fsanitize=%,$(MOZ_CARGO_WRAP_LDFLAGS))
374 endif
376 # Rustc assumes that *-windows-gnu targets build with mingw-gcc and manually
377 # add runtime libraries that don't exist with mingw-clang. We created dummy
378 # libraries in $(topobjdir)/build/win32, but that's not enough, because some
379 # of the wanted symbols that come from these libraries are available in a
380 # different library, that we add manually. We also need to avoid rustc
381 # passing -nodefaultlibs to clang so that it adds clang_rt.
382 ifeq (WINNT_clang,$(OS_ARCH)_$(CC_TYPE))
383 force-cargo-program-build: MOZ_CARGO_WRAP_LDFLAGS+=-L$(topobjdir)/build/win32 -lunwind
384 force-cargo-program-build: CARGO_RUSTCFLAGS += -C default-linker-libraries=yes
385 endif
387 # Rustc passes -nodefaultlibs to the linker (clang) on mac, which prevents
388 # clang from adding the necessary sanitizer runtimes when building with
389 # C/C++ sanitizer but without rust sanitizer.
390 ifeq (Darwin,$(OS_ARCH))
391 ifeq (,$(filter -Zsanitizer=%,$(RUSTFLAGS)))
392 ifneq (,$(filter -fsanitize=%,$(LDFLAGS)))
393 force-cargo-program-build: CARGO_RUSTCFLAGS += -C default-linker-libraries=yes
394 endif
395 endif
396 endif
398 $(HOST_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
399 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
401 ifeq (,$(filter clang-cl,$(CC_TYPE)))
402 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(CC)
403 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(CXX)
404 else
405 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(LINKER)
406 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(LINKER)
407 endif
409 ifeq (,$(filter clang-cl,$(HOST_CC_TYPE)))
410 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_CC)
411 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(HOST_CXX)
412 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_CC)
413 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD_CXX:=$(HOST_CXX)
414 else
415 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_LINKER)
416 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD_CXX:=$(HOST_LINKER)
417 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_LINKER)
418 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD_CXX:=$(HOST_LINKER)
419 endif
421 ifdef RUST_LIBRARY_FILE
423 ifdef RUST_LIBRARY_FEATURES
424 rust_features_flag := --features '$(RUST_LIBRARY_FEATURES)'
425 endif
427 ifeq (WASI,$(OS_ARCH))
428 # The rust wasi target defaults to statically link the wasi crt, but when we
429 # build static libraries from rust and link them with C/C++ code, we also link
430 # a wasi crt, which may conflict with rust's.
431 force-cargo-library-build: CARGO_RUSTCFLAGS += -C target-feature=-crt-static
432 endif
434 # Assume any system libraries rustc links against are already in the target's LIBS.
436 # We need to run cargo unconditionally, because cargo is the only thing that
437 # has full visibility into how changes in Rust sources might affect the final
438 # build.
439 force-cargo-library-build:
440 $(REPORT_BUILD)
441 $(call CARGO_BUILD) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
443 RUST_LIBRARY_DEP_FILE := $(basename $(RUST_LIBRARY_FILE)).d
444 RUST_LIBRARY_DEPS := $(wordlist 2, 10000000, $(if $(wildcard $(RUST_LIBRARY_DEP_FILE)),$(shell cat $(RUST_LIBRARY_DEP_FILE))))
445 $(RUST_LIBRARY_FILE): $(CARGO_FILE) $(if $(RUST_LIBRARY_DEPS),$(RUST_LIBRARY_DEPS), force-cargo-library-build)
446 $(if $(RUST_LIBRARY_DEPS),+$(MAKE) force-cargo-library-build,:)
447 # When we are building in --enable-release mode; we add an additional check to confirm
448 # that we are not importing any networking-related functions in rust code. This reduces
449 # the chance of proxy bypasses originating from rust code.
450 # The check only works when rust code is built with -Clto but without MOZ_LTO_RUST_CROSS.
451 # Sanitizers and sancov also fail because compiler-rt hooks network functions.
452 ifndef MOZ_PROFILE_GENERATE
453 ifeq ($(OS_ARCH), Linux)
454 ifeq (,$(rustflags_sancov)$(MOZ_ASAN)$(MOZ_TSAN)$(MOZ_UBSAN))
455 ifndef MOZ_LTO_RUST_CROSS
456 ifneq (,$(filter -Clto,$(cargo_rustc_flags)))
457 $(call py_action,check_binary,--target --networking $@)
458 endif
459 endif
460 endif
461 endif
462 endif
464 define make_default_rule
465 $(1):
467 endef
468 $(foreach dep, $(filter %.h,$(RUST_LIBRARY_DEPS)),$(eval $(call make_default_rule,$(dep))))
471 SUGGEST_INSTALL_ON_FAILURE = (ret=$$?; if [ $$ret = 101 ]; then echo If $1 is not installed, install it using: cargo install $1; fi; exit $$ret)
473 ifndef CARGO_NO_AUTO_ARG
474 force-cargo-library-%:
475 $(call RUN_CARGO,$*) --lib $(cargo_target_flag) $(rust_features_flag) || $(call SUGGEST_INSTALL_ON_FAILURE,cargo-$*)
476 else
477 force-cargo-library-%:
478 $(call RUN_CARGO,$*) || $(call SUGGEST_INSTALL_ON_FAILURE,cargo-$*)
479 endif
481 else
482 force-cargo-library-%:
483 @true
485 endif # RUST_LIBRARY_FILE
487 ifdef RUST_TESTS
489 rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
491 ifdef RUST_TEST_FEATURES
492 rust_test_features_flag := --features '$(RUST_TEST_FEATURES)'
493 endif
495 # Don't stop at the first failure. We want to list all failures together.
496 rust_test_flag := --no-fail-fast
498 force-cargo-test-run:
499 $(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_test_features_flag))
501 endif # RUST_TESTS
503 ifdef HOST_RUST_LIBRARY_FILE
505 ifdef HOST_RUST_LIBRARY_FEATURES
506 host_rust_features_flag := --features '$(HOST_RUST_LIBRARY_FEATURES)'
507 endif
509 force-cargo-host-library-build:
510 $(REPORT_BUILD)
511 $(call CARGO_BUILD) --lib $(cargo_host_flag) $(host_rust_features_flag)
513 $(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build ;
515 ifndef CARGO_NO_AUTO_ARG
516 force-cargo-host-library-%:
517 $(call RUN_CARGO,$*) --lib $(cargo_host_flag) $(host_rust_features_flag)
518 else
519 force-cargo-host-library-%:
520 $(call RUN_CARGO,$*) --lib $(filter-out --release $(cargo_host_flag)) $(host_rust_features_flag)
521 endif
523 else
524 force-cargo-host-library-%:
525 @true
526 endif # HOST_RUST_LIBRARY_FILE
528 ifdef RUST_PROGRAMS
530 force-cargo-program-build: $(call resfile,module)
531 $(REPORT_BUILD)
532 $(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) -- $(addprefix -C link-arg=$(CURDIR)/,$(call resfile,module)) $(CARGO_RUSTCFLAGS)
534 # RUST_PROGRAM_DEPENDENCIES(RUST_PROGRAM)
535 # Generates a rule suitable to rebuild RUST_PROGRAM only if its dependencies are
536 # obsolete.
537 # It relies on the fact that upon build, cargo generates a dependency file named
538 # `$(RUST_PROGRAM).d'. Unfortunately the lhs of the rule has an absolute path,
539 # so we extract it under the name $(RUST_PROGRAM)_deps below.
541 # If the dependencies are empty, the file was not created so we force a rebuild.
542 # Otherwise we add it to the dependency list.
544 # The actual rule is a bit tricky. The `+' prefix allow for recursive parallel
545 # make, and it's skipped (`:') if we already triggered a rebuild as part of the
546 # dependency chain.
548 define RUST_PROGRAM_DEPENDENCIES
549 $(1)_deps := $(wordlist 2, 10000000, $(if $(wildcard $(1).d),$(shell cat $(1).d)))
550 $(1): $(CARGO_FILE) $(call resfile,module) $(if $$($(1)_deps),$$($(1)_deps),force-cargo-program-build)
551 $(if $$($(1)_deps),+$(MAKE) force-cargo-program-build,:)
552 $(foreach dep,$(filter %.h,$$($(1)_deps)),$(eval $(call make_default_rule,$(dep))))
553 endef
555 $(foreach RUST_PROGRAM,$(RUST_PROGRAMS), $(eval $(call RUST_PROGRAM_DEPENDENCIES,$(RUST_PROGRAM))))
557 ifndef CARGO_NO_AUTO_ARG
558 force-cargo-program-%:
559 $(call RUN_CARGO,$*) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
560 else
561 force-cargo-program-%:
562 $(call RUN_CARGO,$*)
563 endif
565 else
566 force-cargo-program-%:
567 @true
568 endif # RUST_PROGRAMS
569 ifdef HOST_RUST_PROGRAMS
571 force-cargo-host-program-build:
572 $(REPORT_BUILD)
573 $(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
575 $(HOST_RUST_PROGRAMS): force-cargo-host-program-build ;
577 ifndef CARGO_NO_AUTO_ARG
578 force-cargo-host-program-%:
579 $(REPORT_BUILD)
580 $(call RUN_CARGO,$*) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
581 else
582 force-cargo-host-program-%:
583 $(call RUN_CARGO,$*) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(filter-out --release $(cargo_target_flag))
584 endif
586 else
587 force-cargo-host-program-%:
588 @true
590 endif # HOST_RUST_PROGRAMS