Bug 1690340 - Part 4: Insert the "Page Source" before the "Extensions for Developers...
[gecko.git] / config / makefiles / rust.mk
blobb77e0c49ac542d50680a56e6b7aafba37d108a16
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 # Enable color output if original stdout was a TTY and color settings
36 # aren't already present. This essentially restores the default behavior
37 # of cargo when running via `mach`.
38 ifdef MACH_STDOUT_ISATTY
39 ifeq (,$(findstring --color,$(cargo_build_flags)))
40 ifeq (WINNT,$(HOST_OS_ARCH))
41 # Bug 1417003: color codes are non-trivial on Windows. For now,
42 # prefer black and white to broken color codes.
43 cargo_build_flags += --color=never
44 else
45 cargo_build_flags += --color=always
46 endif
47 endif
48 endif
50 # Without -j > 1, make will not pass jobserver info down to cargo. Force
51 # one job when requested as a special case.
52 ifeq (1,$(MOZ_PARALLEL_BUILD))
53 cargo_build_flags += -j1
54 endif
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 # These flags are passed via `cargo rustc` and only apply to the final rustc
65 # invocation (i.e., only the top-level crate, not its dependencies).
66 cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
67 ifndef DEVELOPER_OPTIONS
68 ifndef MOZ_DEBUG_RUST
69 # Enable link-time optimization for release builds, but not when linking
70 # gkrust_gtest. And not when doing cross-language LTO.
71 ifndef MOZ_LTO_RUST_CROSS
72 ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE)))
73 cargo_rustc_flags += -Clto
74 endif
75 # We need -Cembed-bitcode=yes for all crates when using -Clto.
76 RUSTFLAGS += -Cembed-bitcode=yes
77 endif
78 endif
79 endif
81 ifdef CARGO_INCREMENTAL
82 export CARGO_INCREMENTAL
83 endif
85 rustflags_neon =
86 ifeq (neon,$(MOZ_FPU))
87 # Enable neon and disable restriction to 16 FPU registers
88 # (CPUs with neon have 32 FPU registers available)
89 rustflags_neon += -C target_feature=+neon,-d16
90 endif
92 rustflags_sancov =
93 ifdef LIBFUZZER
94 ifndef MOZ_TSAN
95 # These options should match what is implicitly enabled for `clang -fsanitize=fuzzer`
96 # here: https://github.com/llvm/llvm-project/blob/release/8.x/clang/lib/Driver/SanitizerArgs.cpp#L354
98 # -sanitizer-coverage-inline-8bit-counters Increments 8-bit counter for every edge.
99 # -sanitizer-coverage-level=4 Enable coverage for all blocks, critical edges, and indirect calls.
100 # -sanitizer-coverage-trace-compares Tracing of CMP and similar instructions.
101 # -sanitizer-coverage-pc-table Create a static PC table.
103 # In TSan builds, we must not pass any of these, because sanitizer coverage is incompatible with TSan.
104 rustflags_sancov += -Cpasses=sancov -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
105 endif
106 endif
108 rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon)
110 ifdef DEVELOPER_OPTIONS
111 # By default the Rust compiler will perform a limited kind of ThinLTO on each
112 # crate. For local builds this additional optimization is not worth the
113 # increase in compile time so we opt out of it.
114 rustflags_override += -Clto=off
115 endif
117 ifdef MOZ_USING_SCCACHE
118 export RUSTC_WRAPPER=$(CCACHE)
119 endif
121 ifneq (,$(MOZ_ASAN)$(MOZ_TSAN)$(MOZ_UBSAN))
122 ifndef CROSS_COMPILE
123 NATIVE_SANITIZERS=1
124 endif # CROSS_COMPILE
125 endif
127 # We start with host variables because the rust host and the rust target might be the same,
128 # in which case we want the latter to take priority.
130 # We're passing these for consumption by the `cc` crate, which doesn't use the same
131 # convention as cargo itself:
132 # https://github.com/alexcrichton/cc-rs/blob/baa71c0e298d9ad7ac30f0ad78f20b4b3b3a8fb2/src/lib.rs#L1715
133 rust_host_cc_env_name := $(subst -,_,$(RUST_HOST_TARGET))
135 # HOST_CC/HOST_CXX/CC/CXX usually contain base flags for e.g. the build target.
136 # We want to pass those through CFLAGS_*/CXXFLAGS_* instead, so that they end up
137 # after whatever cc-rs adds to the compiler command line, so that they win.
138 # Ideally, we'd use CRATE_CC_NO_DEFAULTS=1, but that causes other problems at the
139 # moment.
140 export CC_$(rust_host_cc_env_name)=$(filter-out $(HOST_CC_BASE_FLAGS),$(HOST_CC))
141 export CXX_$(rust_host_cc_env_name)=$(filter-out $(HOST_CXX_BASE_FLAGS),$(HOST_CXX))
142 # We don't have a HOST_AR. If rust needs one, assume it's going to pick an appropriate one.
144 rust_cc_env_name := $(subst -,_,$(RUST_TARGET))
146 export CC_$(rust_cc_env_name)=$(filter-out $(CC_BASE_FLAGS),$(CC))
147 export CXX_$(rust_cc_env_name)=$(filter-out $(CXX_BASE_FLAGS),$(CXX))
148 export AR_$(rust_cc_env_name)=$(AR)
150 ifeq (WINNT,$(HOST_OS_ARCH))
151 HOST_CC_BASE_FLAGS += -DUNICODE
152 HOST_CXX_BASE_FLAGS += -DUNICODE
153 CC_BASE_FLAGS += -DUNICODE
154 CXX_BASE_FLAGS += -DUNICODE
155 endif
157 ifeq (,$(NATIVE_SANITIZERS)$(MOZ_CODE_COVERAGE))
158 # -DMOZILLA_CONFIG_H is added to prevent mozilla-config.h from injecting anything
159 # in C/C++ compiles from rust. That's not needed in the other branch because the
160 # base flags don't force-include mozilla-config.h.
161 export CFLAGS_$(rust_host_cc_env_name)=$(HOST_CC_BASE_FLAGS) $(COMPUTED_HOST_CFLAGS) -DMOZILLA_CONFIG_H
162 export CXXFLAGS_$(rust_host_cc_env_name)=$(HOST_CXX_BASE_FLAGS) $(COMPUTED_HOST_CXXFLAGS) -DMOZILLA_CONFIG_H
163 export CFLAGS_$(rust_cc_env_name)=$(CC_BASE_FLAGS) $(COMPUTED_CFLAGS) -DMOZILLA_CONFIG_H
164 export CXXFLAGS_$(rust_cc_env_name)=$(CXX_BASE_FLAGS) $(COMPUTED_CXXFLAGS) -DMOZILLA_CONFIG_H
165 else
166 # Because cargo doesn't allow to distinguish builds happening for build
167 # scripts/procedural macros vs. those happening for the rust target,
168 # we can't blindly pass all our flags down for cc-rs to use them, because of the
169 # side effects they can have on what otherwise should be host builds.
170 # So for sanitizer and coverage builds, we only pass the base compiler flags.
171 # This means C code built by rust is not going to be covered by sanitizer
172 # and coverage. But at least we control what compiler is being used,
173 # rather than relying on cc-rs guesses, which, sometimes fail us.
174 export CFLAGS_$(rust_host_cc_env_name)=$(HOST_CC_BASE_FLAGS)
175 export CXXFLAGS_$(rust_host_cc_env_name)=$(HOST_CXX_BASE_FLAGS)
176 export CFLAGS_$(rust_cc_env_name)=$(CC_BASE_FLAGS)
177 export CXXFLAGS_$(rust_cc_env_name)=$(CXX_BASE_FLAGS)
178 endif
180 # Force the target down to all bindgen callers, even those that may not
181 # read BINDGEN_SYSTEM_FLAGS some way or another.
182 export BINDGEN_EXTRA_CLANG_ARGS:=$(filter --target=%,$(BINDGEN_SYSTEM_FLAGS))
183 export CARGO_TARGET_DIR
184 export RUSTFLAGS
185 export RUSTC
186 export RUSTDOC
187 export RUSTFMT
188 export MOZ_SRC=$(topsrcdir)
189 export MOZ_DIST=$(ABS_DIST)
190 export LIBCLANG_PATH=$(MOZ_LIBCLANG_PATH)
191 export CLANG_PATH=$(MOZ_CLANG_PATH)
192 export PKG_CONFIG
193 export PKG_CONFIG_ALLOW_CROSS=1
194 ifneq (,$(PKG_CONFIG_SYSROOT_DIR))
195 export PKG_CONFIG_SYSROOT_DIR
196 endif
197 ifneq (,$(PKG_CONFIG_LIBDIR))
198 export PKG_CONFIG_LIBDIR
199 endif
200 export RUST_BACKTRACE=full
201 export MOZ_TOPOBJDIR=$(topobjdir)
202 export PYTHON3
204 # Set COREAUDIO_SDK_PATH for third_party/rust/coreaudio-sys/build.rs
205 ifeq ($(OS_ARCH), Darwin)
206 ifdef MACOS_SDK_DIR
207 export COREAUDIO_SDK_PATH=$(MACOS_SDK_DIR)
208 endif
209 endif
211 target_rust_ltoable := force-cargo-library-build
212 target_rust_nonltoable := force-cargo-test-run force-cargo-library-check $(foreach b,build check,force-cargo-program-$(b))
214 ifdef MOZ_PGO_RUST
215 ifdef MOZ_PROFILE_GENERATE
216 # Our top-level Cargo.toml sets panic to abort, so we technically don't need -C panic=abort,
217 # but the autocfg crate takes RUSTFLAGS verbatim and runs its compiler tests without
218 # -C panic=abort (because it doesn't know it's what cargo uses), which fail on Windows
219 # because -C panic=unwind (the compiler default) is not compatible with -C profile-generate
220 # (https://github.com/rust-lang/rust/issues/61002).
221 rust_pgo_flags := -C panic=abort -C profile-generate=$(topobjdir)
222 # The C compiler may be passed extra llvm flags for PGO that we also want to pass to rust as well.
223 # In PROFILE_GEN_CFLAGS, they look like "-mllvm foo", and we want "-C llvm-args=foo", so first turn
224 # "-mllvm foo" into "-mllvm:foo" so that it becomes a unique argument, that we can then filter for,
225 # excluding other flags, and then turn into the right string.
226 rust_pgo_flags += $(patsubst -mllvm:%,-C llvm-args=%,$(filter -mllvm:%,$(subst -mllvm ,-mllvm:,$(PROFILE_GEN_CFLAGS))))
227 else # MOZ_PROFILE_USE
228 rust_pgo_flags := -C profile-use=$(PGO_PROFILE_PATH)
229 endif
230 endif
232 $(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) $(if $(MOZ_LTO_RUST_CROSS),-Clinker-plugin-lto) $(rust_pgo_flags)
233 $(target_rust_nonltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS)
235 TARGET_RECIPES := $(target_rust_ltoable) $(target_rust_nonltoable)
237 HOST_RECIPES := \
238 $(foreach a,library program,$(foreach b,build check,force-cargo-host-$(a)-$(b)))
240 $(HOST_RECIPES): RUSTFLAGS:=$(rustflags_override)
242 # If this is a release build we want rustc to generate one codegen unit per
243 # crate. This results in better optimization and less code duplication at the
244 # cost of longer compile times.
245 ifndef DEVELOPER_OPTIONS
246 $(TARGET_RECIPES) $(HOST_RECIPES): RUSTFLAGS += -C codegen-units=1
247 endif
249 # We use the + prefix to pass down the jobserver fds to cargo, but we
250 # don't use the prefix when make -n is used, so that cargo doesn't run
251 # in that case)
252 define RUN_CARGO
253 $(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)$(CARGO) $(1) $(cargo_build_flags)
254 endef
256 # This function is intended to be called by:
258 # $(call CARGO_BUILD,EXTRA_ENV_VAR1=X EXTRA_ENV_VAR2=Y ...)
260 # but, given the idiosyncracies of make, can also be called without arguments:
262 # $(call CARGO_BUILD)
263 define CARGO_BUILD
264 $(call RUN_CARGO,rustc)
265 endef
267 define CARGO_CHECK
268 $(call RUN_CARGO,check)
269 endef
271 cargo_host_linker_env_var := CARGO_TARGET_$(call varize,$(RUST_HOST_TARGET))_LINKER
272 cargo_linker_env_var := CARGO_TARGET_$(call varize,$(RUST_TARGET))_LINKER
274 # Cargo needs the same linker flags as the C/C++ compiler,
275 # but not the final libraries. Filter those out because they
276 # cause problems on macOS 10.7; see bug 1365993 for details.
277 # Also, we don't want to pass PGO flags until cargo supports them.
278 export MOZ_CARGO_WRAP_LDFLAGS
279 export MOZ_CARGO_WRAP_LD
280 export MOZ_CARGO_WRAP_HOST_LDFLAGS
281 export MOZ_CARGO_WRAP_HOST_LD
282 # Exporting from make always exports a value. Setting a value per-recipe
283 # would export an empty value for the host recipes. When not doing a
284 # cross-compile, the --target for those is the same, and cargo will use
285 # CARGO_TARGET_*_LINKER for its linker, so we always pass the
286 # cargo-linker wrapper, and fill MOZ_CARGO_WRAP_{HOST_,}LD* more or less
287 # appropriately for all recipes.
288 ifeq (WINNT,$(HOST_OS_ARCH))
289 # Use .bat wrapping on Windows hosts, and shell wrapping on other hosts.
290 # Like for CC/C*FLAGS, we want the target values to trump the host values when
291 # both variables are the same.
292 export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker.bat
293 export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker.bat
294 WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS_BAT)
295 else
296 export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker
297 export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker
298 WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS)
299 endif
301 # Defining all of this for ASan/TSan builds results in crashes while running
302 # some crates's build scripts (!), so disable it for now.
303 # See https://github.com/rust-lang/cargo/issues/5754
304 ifndef NATIVE_SANITIZERS
305 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))
306 endif # NATIVE_SANITIZERS
308 $(HOST_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
309 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
311 ifeq (,$(filter clang-cl,$(CC_TYPE)))
312 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(CC)
313 else
314 $(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(LINKER)
315 endif
317 ifeq (,$(filter clang-cl,$(HOST_CC_TYPE)))
318 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_CC)
319 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_CC)
320 else
321 $(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_LINKER)
322 $(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_LINKER)
323 endif
325 ifdef RUST_LIBRARY_FILE
327 ifdef RUST_LIBRARY_FEATURES
328 rust_features_flag := --features '$(RUST_LIBRARY_FEATURES)'
329 endif
331 # Assume any system libraries rustc links against are already in the target's LIBS.
333 # We need to run cargo unconditionally, because cargo is the only thing that
334 # has full visibility into how changes in Rust sources might affect the final
335 # build.
336 force-cargo-library-build:
337 $(REPORT_BUILD)
338 $(call CARGO_BUILD) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
340 $(RUST_LIBRARY_FILE): force-cargo-library-build
341 # When we are building in --enable-release mode; we add an additional check to confirm
342 # that we are not importing any networking-related functions in rust code. This reduces
343 # the chance of proxy bypasses originating from rust code.
344 # The check only works when rust code is built with -Clto but without MOZ_LTO_RUST_CROSS.
345 # Sanitizers and sancov also fail because compiler-rt hooks network functions.
346 ifndef MOZ_PROFILE_GENERATE
347 ifeq ($(OS_ARCH), Linux)
348 ifeq (,$(rustflags_sancov)$(MOZ_ASAN)$(MOZ_TSAN)$(MOZ_UBSAN))
349 ifndef MOZ_LTO_RUST_CROSS
350 ifneq (,$(filter -Clto,$(cargo_rustc_flags)))
351 $(call py_action,check_binary,--target --networking $@)
352 endif
353 endif
354 endif
355 endif
356 endif
358 force-cargo-library-check:
359 $(call CARGO_CHECK) --lib $(cargo_target_flag) $(rust_features_flag)
360 else
361 force-cargo-library-check:
362 @true
363 endif # RUST_LIBRARY_FILE
365 ifdef RUST_TESTS
367 rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
369 ifdef RUST_TEST_FEATURES
370 rust_test_features_flag := --features '$(RUST_TEST_FEATURES)'
371 endif
373 # Don't stop at the first failure. We want to list all failures together.
374 rust_test_flag := --no-fail-fast
376 force-cargo-test-run:
377 $(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_test_features_flag))
379 endif
381 ifdef HOST_RUST_LIBRARY_FILE
383 ifdef HOST_RUST_LIBRARY_FEATURES
384 host_rust_features_flag := --features '$(HOST_RUST_LIBRARY_FEATURES)'
385 endif
387 force-cargo-host-library-build:
388 $(REPORT_BUILD)
389 $(call CARGO_BUILD) --lib $(cargo_host_flag) $(host_rust_features_flag)
391 $(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build ;
393 force-cargo-host-library-check:
394 $(call CARGO_CHECK) --lib $(cargo_host_flag) $(host_rust_features_flag)
395 else
396 force-cargo-host-library-check:
397 @true
398 endif # HOST_RUST_LIBRARY_FILE
400 ifdef RUST_PROGRAMS
402 force-cargo-program-build: $(call resfile,module)
403 $(REPORT_BUILD)
404 $(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) -- $(addprefix -C link-arg=$(CURDIR)/,$(call resfile,module))
406 $(RUST_PROGRAMS): force-cargo-program-build ;
408 force-cargo-program-check:
409 $(call CARGO_CHECK) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
410 else
411 force-cargo-program-check:
412 @true
413 endif # RUST_PROGRAMS
414 ifdef HOST_RUST_PROGRAMS
416 force-cargo-host-program-build:
417 $(REPORT_BUILD)
418 $(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
420 $(HOST_RUST_PROGRAMS): force-cargo-host-program-build ;
422 force-cargo-host-program-check:
423 $(REPORT_BUILD)
424 $(call CARGO_CHECK) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
425 else
426 force-cargo-host-program-check:
427 @true
428 endif # HOST_RUST_PROGRAMS