Source code

Revision control

Other Tools

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/.
4
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.
8
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.
12
13
cargo_host_flag := --target=$(RUST_HOST_TARGET)
14
cargo_target_flag := --target=$(RUST_TARGET)
15
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
21
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
29
30
cargo_build_flags += --manifest-path $(CARGO_FILE)
31
ifdef BUILD_VERBOSE_LOG
32
cargo_build_flags += -vv
33
endif
34
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
49
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
55
56
# These flags are passed via `cargo rustc` and only apply to the final rustc
57
# invocation (i.e., only the top-level crate, not its dependencies).
58
cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
59
ifndef DEVELOPER_OPTIONS
60
ifndef MOZ_DEBUG_RUST
61
# Enable link-time optimization for release builds, but not when linking
62
# gkrust_gtest.
63
ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE)))
64
cargo_rustc_flags += -Clto
65
endif
66
endif
67
endif
68
69
ifdef CARGO_INCREMENTAL
70
export CARGO_INCREMENTAL
71
endif
72
73
rustflags_neon =
74
ifeq (neon,$(MOZ_FPU))
75
# Enable neon and disable restriction to 16 FPU registers
76
# (CPUs with neon have 32 FPU registers available)
77
rustflags_neon += -C target_feature=+neon,-d16
78
endif
79
80
rustflags_sancov =
81
ifdef FUZZING_INTERFACES
82
ifndef MOZ_TSAN
83
# These options should match what is implicitly enabled for `clang -fsanitize=fuzzer`
85
#
86
# -sanitizer-coverage-inline-8bit-counters Increments 8-bit counter for every edge.
87
# -sanitizer-coverage-level=4 Enable coverage for all blocks, critical edges, and indirect calls.
88
# -sanitizer-coverage-trace-compares Tracing of CMP and similar instructions.
89
# -sanitizer-coverage-pc-table Create a static PC table.
90
#
91
# In TSan builds, we must not pass any of these, because sanitizer coverage is incompatible with TSan.
92
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
93
endif
94
endif
95
96
rustflags_override = $(MOZ_RUST_DEFAULT_FLAGS) $(rustflags_neon)
97
98
ifdef DEVELOPER_OPTIONS
99
# By default the Rust compiler will perform a limited kind of ThinLTO on each
100
# crate. For local builds this additional optimization is not worth the
101
# increase in compile time so we opt out of it.
102
rustflags_override += -Clto=off
103
endif
104
105
ifdef MOZ_USING_SCCACHE
106
export RUSTC_WRAPPER=$(CCACHE)
107
endif
108
109
ifneq (,$(MOZ_ASAN)$(MOZ_TSAN)$(MOZ_UBSAN))
110
ifndef CROSS_COMPILE
111
NATIVE_SANITIZERS=1
112
endif # CROSS_COMPILE
113
endif
114
115
# We start with host variables because the rust host and the rust target might be the same,
116
# in which case we want the latter to take priority.
117
118
# We're passing these for consumption by the `cc` crate, which doesn't use the same
119
# convention as cargo itself:
121
rust_host_cc_env_name := $(subst -,_,$(RUST_HOST_TARGET))
122
123
export CC_$(rust_host_cc_env_name)=$(HOST_CC)
124
export CXX_$(rust_host_cc_env_name)=$(HOST_CXX)
125
# We don't have a HOST_AR. If rust needs one, assume it's going to pick an appropriate one.
126
127
rust_cc_env_name := $(subst -,_,$(RUST_TARGET))
128
129
export CC_$(rust_cc_env_name)=$(CC)
130
export CXX_$(rust_cc_env_name)=$(CXX)
131
export AR_$(rust_cc_env_name)=$(AR)
132
ifeq (,$(NATIVE_SANITIZERS)$(MOZ_CODE_COVERAGE))
133
# -DMOZILLA_CONFIG_H is added to prevent mozilla-config.h from injecting anything
134
# in C/C++ compiles from rust. That's not needed in the other branch because the
135
# base flags don't force-include mozilla-config.h.
136
export CFLAGS_$(rust_host_cc_env_name)=$(COMPUTED_HOST_CFLAGS) -DMOZILLA_CONFIG_H
137
export CXXFLAGS_$(rust_host_cc_env_name)=$(COMPUTED_HOST_CXXFLAGS) -DMOZILLA_CONFIG_H
138
export CFLAGS_$(rust_cc_env_name)=$(COMPUTED_CFLAGS) -DMOZILLA_CONFIG_H
139
export CXXFLAGS_$(rust_cc_env_name)=$(COMPUTED_CXXFLAGS) -DMOZILLA_CONFIG_H
140
else
141
# Because cargo doesn't allow to distinguish builds happening for build
142
# scripts/procedural macros vs. those happening for the rust target,
143
# we can't blindly pass all our flags down for cc-rs to use them, because of the
144
# side effects they can have on what otherwise should be host builds.
145
# So for sanitizer and coverage builds, we only pass the base compiler flags.
146
# This means C code built by rust is not going to be covered by sanitizer
147
# and coverage. But at least we control what compiler is being used,
148
# rather than relying on cc-rs guesses, which, sometimes fail us.
149
export CFLAGS_$(rust_host_cc_env_name)=$(HOST_CC_BASE_FLAGS)
150
export CXXFLAGS_$(rust_host_cc_env_name)=$(HOST_CXX_BASE_FLAGS)
151
export CFLAGS_$(rust_cc_env_name)=$(CC_BASE_FLAGS)
152
export CXXFLAGS_$(rust_cc_env_name)=$(CXX_BASE_FLAGS)
153
endif
154
155
export CARGO_TARGET_DIR
156
export RUSTFLAGS
157
export RUSTC
158
export RUSTDOC
159
export RUSTFMT
160
export MOZ_SRC=$(topsrcdir)
161
export MOZ_DIST=$(ABS_DIST)
162
export LIBCLANG_PATH=$(MOZ_LIBCLANG_PATH)
163
export CLANG_PATH=$(MOZ_CLANG_PATH)
164
export PKG_CONFIG
165
export PKG_CONFIG_ALLOW_CROSS=1
166
export RUST_BACKTRACE=full
167
export MOZ_TOPOBJDIR=$(topobjdir)
168
169
# Set COREAUDIO_SDK_PATH for third_party/rust/coreaudio-sys/build.rs
170
ifeq ($(OS_ARCH), Darwin)
171
ifdef MACOS_SDK_DIR
172
export COREAUDIO_SDK_PATH=$(MACOS_SDK_DIR)
173
endif
174
endif
175
176
target_rust_ltoable := force-cargo-library-build
177
target_rust_nonltoable := force-cargo-test-run force-cargo-library-check $(foreach b,build check,force-cargo-program-$(b))
178
179
ifdef MOZ_PGO_RUST
180
rust_pgo_flags := $(if $(MOZ_PROFILE_GENERATE),-C profile-generate=$(topobjdir)) $(if $(MOZ_PROFILE_USE),-C profile-use=$(PGO_PROFILE_PATH))
181
endif
182
183
$(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS) $(if $(MOZ_LTO_RUST),-Clinker-plugin-lto) $(rust_pgo_flags)
184
$(target_rust_nonltoable): RUSTFLAGS:=$(rustflags_override) $(rustflags_sancov) $(RUSTFLAGS)
185
186
TARGET_RECIPES := $(target_rust_ltoable) $(target_rust_nonltoable)
187
188
HOST_RECIPES := \
189
$(foreach a,library program,$(foreach b,build check,force-cargo-host-$(a)-$(b)))
190
191
$(HOST_RECIPES): RUSTFLAGS:=$(rustflags_override)
192
193
cargo_env = $(subst -,_,$(subst a,A,$(subst b,B,$(subst c,C,$(subst d,D,$(subst e,E,$(subst f,F,$(subst g,G,$(subst h,H,$(subst i,I,$(subst j,J,$(subst k,K,$(subst l,L,$(subst m,M,$(subst n,N,$(subst o,O,$(subst p,P,$(subst q,Q,$(subst r,R,$(subst s,S,$(subst t,T,$(subst u,U,$(subst v,V,$(subst w,W,$(subst x,X,$(subst y,Y,$(subst z,Z,$1)))))))))))))))))))))))))))
194
195
# We use the + prefix to pass down the jobserver fds to cargo, but we
196
# don't use the prefix when make -n is used, so that cargo doesn't run
197
# in that case)
198
define RUN_CARGO
199
$(if $(findstring n,$(filter-out --%, $(MAKEFLAGS))),,+)$(CARGO) $(1) $(cargo_build_flags)
200
endef
201
202
# This function is intended to be called by:
203
#
204
# $(call CARGO_BUILD,EXTRA_ENV_VAR1=X EXTRA_ENV_VAR2=Y ...)
205
#
206
# but, given the idiosyncracies of make, can also be called without arguments:
207
#
208
# $(call CARGO_BUILD)
209
define CARGO_BUILD
210
$(call RUN_CARGO,rustc)
211
endef
212
213
define CARGO_CHECK
214
$(call RUN_CARGO,check)
215
endef
216
217
cargo_host_linker_env_var := CARGO_TARGET_$(call cargo_env,$(RUST_HOST_TARGET))_LINKER
218
cargo_linker_env_var := CARGO_TARGET_$(call cargo_env,$(RUST_TARGET))_LINKER
219
220
# Defining all of this for ASan/TSan builds results in crashes while running
221
# some crates's build scripts (!), so disable it for now.
223
ifndef NATIVE_SANITIZERS
224
# Cargo needs the same linker flags as the C/C++ compiler,
225
# but not the final libraries. Filter those out because they
226
# cause problems on macOS 10.7; see bug 1365993 for details.
227
# Also, we don't want to pass PGO flags until cargo supports them.
228
export MOZ_CARGO_WRAP_LDFLAGS
229
export MOZ_CARGO_WRAP_LD
230
export MOZ_CARGO_WRAP_HOST_LDFLAGS
231
export MOZ_CARGO_WRAP_HOST_LD
232
# Exporting from make always exports a value. Setting a value per-recipe
233
# would export an empty value for the host recipes. When not doing a
234
# cross-compile, the --target for those is the same, and cargo will use
235
# CARGO_TARGET_*_LINKER for its linker, so we always pass the
236
# cargo-linker wrapper, and fill MOZ_CARGO_WRAP_{HOST_,}LD* more or less
237
# appropriately for all recipes.
238
ifeq (WINNT,$(HOST_OS_ARCH))
239
# Use .bat wrapping on Windows hosts, and shell wrapping on other hosts.
240
# Like for CC/C*FLAGS, we want the target values to trump the host values when
241
# both variables are the same.
242
export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker.bat
243
export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker.bat
244
WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS_BAT)
245
else
246
export $(cargo_host_linker_env_var):=$(topsrcdir)/build/cargo-host-linker
247
export $(cargo_linker_env_var):=$(topsrcdir)/build/cargo-linker
248
WRAP_HOST_LINKER_LIBPATHS:=$(HOST_LINKER_LIBPATHS)
249
endif
250
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))
251
252
$(HOST_RECIPES): MOZ_CARGO_WRAP_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
253
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LDFLAGS:=$(HOST_LDFLAGS) $(WRAP_HOST_LINKER_LIBPATHS)
254
255
ifeq (,$(filter clang-cl,$(CC_TYPE)))
256
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(CC)
257
else
258
$(TARGET_RECIPES): MOZ_CARGO_WRAP_LD:=$(LINKER)
259
endif
260
261
ifeq (,$(filter clang-cl,$(HOST_CC_TYPE)))
262
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_CC)
263
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_CC)
264
else
265
$(HOST_RECIPES): MOZ_CARGO_WRAP_LD:=$(HOST_LINKER)
266
$(TARGET_RECIPES) $(HOST_RECIPES): MOZ_CARGO_WRAP_HOST_LD:=$(HOST_LINKER)
267
endif
268
269
endif # NATIVE_SANITIZERS
270
271
ifdef RUST_LIBRARY_FILE
272
273
ifdef RUST_LIBRARY_FEATURES
274
rust_features_flag := --features '$(RUST_LIBRARY_FEATURES)'
275
endif
276
277
# Assume any system libraries rustc links against are already in the target's LIBS.
278
#
279
# We need to run cargo unconditionally, because cargo is the only thing that
280
# has full visibility into how changes in Rust sources might affect the final
281
# build.
282
force-cargo-library-build:
283
$(REPORT_BUILD)
284
$(call CARGO_BUILD) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
285
286
$(RUST_LIBRARY_FILE): force-cargo-library-build
287
# When we are building in --enable-release mode; we add an additional check to confirm
288
# that we are not importing any networking-related functions in rust code. This reduces
289
# the chance of proxy bypasses originating from rust code.
290
# The check only works when rust code is built with -Clto.
291
# Enabling sancov or TSan also causes this to fail.
292
ifndef MOZ_PROFILE_GENERATE
293
ifndef MOZ_TSAN
294
ifeq ($(OS_ARCH), Linux)
295
ifeq (,$(rustflags_sancov))
296
ifneq (,$(filter -Clto,$(cargo_rustc_flags)))
297
$(call py_action,check_binary,--target --networking $@)
298
endif
299
endif
300
endif
301
endif
302
endif
303
304
force-cargo-library-check:
305
$(call CARGO_CHECK) --lib $(cargo_target_flag) $(rust_features_flag)
306
else
307
force-cargo-library-check:
308
@true
309
endif # RUST_LIBRARY_FILE
310
311
ifdef RUST_TESTS
312
313
rust_test_options := $(foreach test,$(RUST_TESTS),-p $(test))
314
315
ifdef RUST_TEST_FEATURES
316
rust_test_features_flag := --features '$(RUST_TEST_FEATURES)'
317
endif
318
319
# Don't stop at the first failure. We want to list all failures together.
320
rust_test_flag := --no-fail-fast
321
322
force-cargo-test-run:
323
$(call RUN_CARGO,test $(cargo_target_flag) $(rust_test_flag) $(rust_test_options) $(rust_test_features_flag))
324
325
endif
326
327
ifdef HOST_RUST_LIBRARY_FILE
328
329
ifdef HOST_RUST_LIBRARY_FEATURES
330
host_rust_features_flag := --features '$(HOST_RUST_LIBRARY_FEATURES)'
331
endif
332
333
force-cargo-host-library-build:
334
$(REPORT_BUILD)
335
$(call CARGO_BUILD) --lib $(cargo_host_flag) $(host_rust_features_flag)
336
337
$(HOST_RUST_LIBRARY_FILE): force-cargo-host-library-build
338
339
force-cargo-host-library-check:
340
$(call CARGO_CHECK) --lib $(cargo_host_flag) $(host_rust_features_flag)
341
else
342
force-cargo-host-library-check:
343
@true
344
endif # HOST_RUST_LIBRARY_FILE
345
346
ifdef RUST_PROGRAMS
347
348
GARBAGE_DIRS += $(RUST_TARGET)
349
350
force-cargo-program-build: $(RESFILE)
351
$(REPORT_BUILD)
352
$(call CARGO_BUILD) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag) -- $(if $(RESFILE),-C link-arg=$(CURDIR)/$(RESFILE))
353
354
$(RUST_PROGRAMS): force-cargo-program-build
355
356
force-cargo-program-check:
357
$(call CARGO_CHECK) $(addprefix --bin ,$(RUST_CARGO_PROGRAMS)) $(cargo_target_flag)
358
else
359
force-cargo-program-check:
360
@true
361
endif # RUST_PROGRAMS
362
ifdef HOST_RUST_PROGRAMS
363
364
GARBAGE_DIRS += $(RUST_HOST_TARGET)
365
366
force-cargo-host-program-build:
367
$(REPORT_BUILD)
368
$(call CARGO_BUILD) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
369
370
$(HOST_RUST_PROGRAMS): force-cargo-host-program-build
371
372
force-cargo-host-program-check:
373
$(REPORT_BUILD)
374
$(call CARGO_CHECK) $(addprefix --bin ,$(HOST_RUST_CARGO_PROGRAMS)) $(cargo_host_flag)
375
else
376
force-cargo-host-program-check:
377
@true
378
endif # HOST_RUST_PROGRAMS