Bug 1875768 - Call the appropriate postfork handler on MacOS r=glandium
[gecko.git] / build / moz.configure / rust.configure
blobc90a9da1c6e7130e0e46c658effcafd123b07cc7
1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
2 # vim: set filetype=python:
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # Rust is required by `rust_compiler` below. We allow_missing here
9 # to propagate failures to the better error message there.
10 option(env="RUSTC", nargs=1, help="Path to the rust compiler")
11 option(env="CARGO", nargs=1, help="Path to the Cargo package manager")
13 rustc = check_prog(
14     "_RUSTC",
15     ["rustc"],
16     what="rustc",
17     paths=rust_search_path,
18     input="RUSTC",
19     allow_missing=True,
21 cargo = check_prog(
22     "_CARGO",
23     ["cargo"],
24     what="cargo",
25     paths=rust_search_path,
26     input="CARGO",
27     allow_missing=True,
31 @template
32 def unwrap_rustup(prog, name):
33     # rustc and cargo can either be rustup wrappers, or they can be the actual,
34     # plain executables. For cargo, on OSX, rustup sets DYLD_LIBRARY_PATH (at
35     # least until https://github.com/rust-lang/rustup.rs/pull/1752 is merged
36     # and shipped) and that can wreak havoc (see bug 1536486). Similarly, for
37     # rustc, rustup silently honors toolchain overrides set by vendored crates
38     # (see bug 1547196).
39     #
40     # In either case, we need to find the plain executables.
41     #
42     # To achieve that, try to run `PROG +stable`. When the rustup wrapper is in
43     # use, it either prints PROG's help and exits with status 0, or prints
44     # an error message (error: toolchain 'stable' is not installed) and exits
45     # with status 1. In the cargo case, when plain cargo is in use, it exits
46     # with a different error message (e.g. "error: no such subcommand:
47     # `+stable`"), and exits with status 101.
48     #
49     # Unfortunately, in the rustc case, when plain rustc is in use,
50     # `rustc +stable` will exit with status 1, complaining about a missing
51     # "+stable" file. We'll examine the error output to try and distinguish
52     # between failing rustup and failing rustc.
53     @depends(prog, dependable(name))
54     @imports(_from="__builtin__", _import="open")
55     @imports("os")
56     def unwrap(prog, name):
57         if not prog:
58             return
60         def from_rustup_which():
61             out = check_cmd_output("rustup", "which", name, executable=prog).rstrip()
62             # If for some reason the above failed to return something, keep the
63             # PROG we found originally.
64             if out:
65                 log.info("Actually using '%s'", out)
66                 return out
68             log.info("No `rustup which` output, using '%s'", prog)
69             return prog
71         (retcode, stdout, stderr) = get_cmd_output(prog, "+stable")
73         if name == "cargo" and retcode != 101:
74             prog = from_rustup_which()
75         elif name == "rustc":
76             if retcode == 0:
77                 prog = from_rustup_which()
78             elif "+stable" in stderr:
79                 # PROG looks like plain `rustc`.
80                 pass
81             else:
82                 # Assume PROG looks like `rustup`. This case is a little weird,
83                 # insofar as the user doesn't have the "stable" toolchain
84                 # installed, but go ahead and unwrap anyway: the user might
85                 # have only certain versions, beta, or nightly installed, and
86                 # we'll catch invalid versions later.
87                 prog = from_rustup_which()
89         return normalize_path(prog)
91     return unwrap
94 rustc = unwrap_rustup(rustc, "rustc")
95 cargo = unwrap_rustup(cargo, "cargo")
98 set_config("CARGO", cargo)
99 set_config("RUSTC", rustc)
102 @depends_if(rustc)
103 @checking("rustc version", lambda info: info.version)
104 def rustc_info(rustc):
105     if not rustc:
106         return
107     out = check_cmd_output(rustc, "--version", "--verbose").splitlines()
108     info = dict((s.strip() for s in line.split(":", 1)) for line in out[1:])
109     return namespace(
110         version=Version(info.get("release", "0")),
111         commit=info.get("commit-hash", "unknown"),
112         host=info["host"],
113         llvm_version=Version(info.get("LLVM version", "0")),
114     )
117 set_config(
118     "RUSTC_VERSION",
119     depends(rustc_info)(lambda info: str(info.version) if info else None),
123 set_config(
124     "RUSTC_LLVM_VERSION",
125     depends(rustc_info)(lambda info: str(info.llvm_version) if info else None),
128 set_config(
129     "MOZ_CLANG_NEWER_THAN_RUSTC_LLVM",
130     depends(c_compiler, rustc_info)(
131         lambda c_compiler, rustc_info: rustc_info
132         and c_compiler.type == "clang"
133         and c_compiler.version.major > rustc_info.llvm_version.major
134     ),
138 @depends_if(cargo)
139 @checking("cargo version", lambda info: info.version)
140 @imports("re")
141 def cargo_info(cargo):
142     if not cargo:
143         return
144     out = check_cmd_output(cargo, "--version", "--verbose").splitlines()
145     info = dict((s.strip() for s in line.split(":", 1)) for line in out[1:])
146     version = info.get("release")
147     # Older versions of cargo didn't support --verbose, in which case, they
148     # only output a not-really-pleasant-to-parse output. Fortunately, they
149     # don't error out, so we can just try some regexp matching on the output
150     # we already got.
151     if version is None:
152         VERSION_FORMAT = r"^cargo (\d\.\d+\.\d+).*"
154         m = re.search(VERSION_FORMAT, out[0])
155         # Fail fast if cargo changes its output on us.
156         if not m:
157             die("Could not determine cargo version from output: %s", out)
158         version = m.group(1)
160     return namespace(
161         version=Version(version),
162     )
165 @depends(rustc_info, cargo_info, target)
166 @imports(_from="mozboot.util", _import="MINIMUM_RUST_VERSION")
167 @imports(_from="textwrap", _import="dedent")
168 def rust_compiler(rustc_info, cargo_info, target):
169     if not rustc_info:
170         die(
171             dedent(
172                 """\
173         Rust compiler not found.
174         To compile rust language sources, you must have 'rustc' in your path.
175         See https://www.rust-lang.org/ for more information.
177         You can install rust by running './mach bootstrap'
178         or by directly running the installer from https://rustup.rs/
179         """
180             )
181         )
182     rustc_min_version = Version(MINIMUM_RUST_VERSION)
183     cargo_min_version = rustc_min_version
185     version = rustc_info.version
186     is_nightly = "nightly" in version.version
187     is_version_number_match = (
188         version.major == rustc_min_version.major
189         and version.minor == rustc_min_version.minor
190         and version.patch == rustc_min_version.patch
191     )
193     if version < rustc_min_version or (is_version_number_match and is_nightly):
194         die(
195             dedent(
196                 """\
197         Rust compiler {} is too old.
199         To compile Rust language sources please install at least
200         version {} of the 'rustc' toolchain (or, if using nightly,
201         at least one version newer than {}) and make sure it is
202         first in your path.
204         You can verify this by typing 'rustc --version'.
206         If you have the 'rustup' tool installed you can upgrade
207         to the latest release by typing 'rustup update'. The
208         installer is available from https://rustup.rs/
209         """.format(
210                     version, rustc_min_version, rustc_min_version
211                 )
212             )
213         )
215     if target.kernel == "WINNT" and (version.major, version.minor) == (1, 56):
216         die(
217             dedent(
218                 """\
219         Rust compiler 1.56.* is not supported for Windows builds.
221         Use a newer or an older version.
223         See https://github.com/rust-lang/rust/issues/88576.
224         """
225             )
226         )
228     if not cargo_info:
229         die(
230             dedent(
231                 """\
232         Cargo package manager not found.
233         To compile Rust language sources, you must have 'cargo' in your path.
234         See https://www.rust-lang.org/ for more information.
236         You can install cargo by running './mach bootstrap'
237         or by directly running the installer from https://rustup.rs/
238         """
239             )
240         )
242     version = cargo_info.version
243     if version < cargo_min_version:
244         die(
245             dedent(
246                 """\
247         Cargo package manager {} is too old.
249         To compile Rust language sources please install at least
250         version {} of 'cargo' and make sure it is first in your path.
252         You can verify this by typing 'cargo --version'.
253         """
254             ).format(version, cargo_min_version)
255         )
257     return True
260 @depends(rustc, when=rust_compiler)
261 @imports(_from="__builtin__", _import="ValueError")
262 def rust_supported_targets(rustc):
263     out = check_cmd_output(rustc, "--print", "target-list").splitlines()
264     data = {}
265     for t in out:
266         try:
267             info = split_triplet(t, allow_wasi=True)
268         except ValueError:
269             if t.startswith("thumb"):
270                 cpu, rest = t.split("-", 1)
271                 retry = "-".join(("arm", rest))
272             else:
273                 continue
274             try:
275                 info = split_triplet(retry, allow_wasi=True)
276             except ValueError:
277                 continue
278         key = (info.cpu, info.endianness, info.os)
279         data.setdefault(key, []).append(namespace(rust_target=t, target=info))
280     return data
283 def detect_rustc_target(
284     host_or_target, compiler_info, arm_target, rust_supported_targets
286     # Rust's --target options are similar to, but not exactly the same
287     # as, the autoconf-derived targets we use.  An example would be that
288     # Rust uses distinct target triples for targetting the GNU C++ ABI
289     # and the MSVC C++ ABI on Win32, whereas autoconf has a single
290     # triple and relies on the user to ensure that everything is
291     # compiled for the appropriate ABI.  We need to perform appropriate
292     # munging to get the correct option to rustc.
293     # We correlate the autoconf-derived targets with the list of targets
294     # rustc gives us with --print target-list.
295     candidates = rust_supported_targets.get(
296         (host_or_target.cpu, host_or_target.endianness, host_or_target.os), []
297     )
299     def find_candidate(candidates):
300         if len(candidates) == 1:
301             return candidates[0].rust_target
302         elif not candidates:
303             return None
305         # We have multiple candidates. There are two cases where we can try to
306         # narrow further down using extra information from the build system.
307         # - For windows targets, correlate with the C compiler type
308         if host_or_target.kernel == "WINNT":
309             if host_or_target.abi:
310                 if host_or_target.abi == "msvc":
311                     suffix = "windows-msvc"
312                 elif host_or_target.abi == "mingw":
313                     suffix = "windows-gnu"
314             elif compiler_info.type in ("gcc", "clang"):
315                 suffix = "windows-gnu"
316             else:
317                 suffix = "windows-msvc"
318             narrowed = [
319                 c for c in candidates if c.rust_target.endswith("-{}".format(suffix))
320             ]
321             if len(narrowed) == 1:
322                 return narrowed[0].rust_target
323             elif narrowed:
324                 candidates = narrowed
326             vendor_aliases = {"pc": ("w64", "windows")}
327             narrowed = [
328                 c
329                 for c in candidates
330                 if host_or_target.vendor in vendor_aliases.get(c.target.vendor, ())
331             ]
333             if len(narrowed) == 1:
334                 return narrowed[0].rust_target
336         # - For arm targets, correlate with arm_target
337         #   we could be more thorough with the supported rust targets, but they
338         #   don't support OSes that are supported to build Gecko anyways.
339         #   Also, sadly, the only interface to check the rust target cpu features
340         #   is --print target-spec-json, and it's unstable, so we have to rely on
341         #   our own knowledge of what each arm target means.
342         if host_or_target.cpu == "arm" and host_or_target.endianness == "little":
343             prefixes = []
344             if arm_target.arm_arch >= 7:
345                 if arm_target.thumb2 and arm_target.fpu == "neon":
346                     prefixes.append("thumbv7neon")
347                 if arm_target.thumb2:
348                     prefixes.append("thumbv7a")
349                 prefixes.append("armv7")
350             if arm_target.arm_arch >= 6:
351                 prefixes.append("armv6")
352                 if host_or_target.os != "Android":
353                     # arm-* rust targets are armv6... except arm-linux-androideabi
354                     prefixes.append("arm")
355             if arm_target.arm_arch >= 5:
356                 prefixes.append("armv5te")
357                 if host_or_target.os == "Android":
358                     # arm-* rust targets are armv6... except arm-linux-androideabi
359                     prefixes.append("arm")
360             if arm_target.arm_arch >= 4:
361                 prefixes.append("armv4t")
362             # rust freebsd targets are the only ones that don't have a 'hf' suffix
363             # for hard-float. Technically, that means if the float abi ever is not
364             # hard-float, this will pick a wrong target, but since rust only
365             # supports hard-float, let's assume that means freebsd only support
366             # hard-float.
367             if arm_target.float_abi == "hard" and host_or_target.os != "FreeBSD":
368                 suffix = "hf"
369             else:
370                 suffix = ""
371             for p in prefixes:
372                 for c in candidates:
373                     if c.rust_target.startswith(
374                         "{}-".format(p)
375                     ) and c.rust_target.endswith(suffix):
376                         return c.rust_target
378         # See if we can narrow down on the exact alias.
379         # We use the sub_configure_alias to keep support mingw32 triplets as input.
380         narrowed = [
381             c
382             for c in candidates
383             if c.target.sub_configure_alias == host_or_target.sub_configure_alias
384         ]
385         if len(narrowed) == 1:
386             return narrowed[0].rust_target
387         elif narrowed:
388             candidates = narrowed
390         # See if we can narrow down with the raw OS
391         narrowed = [c for c in candidates if c.target.raw_os == host_or_target.raw_os]
392         if len(narrowed) == 1:
393             return narrowed[0].rust_target
394         elif narrowed:
395             candidates = narrowed
397         # See if we can narrow down with the raw OS and raw CPU
398         narrowed = [
399             c
400             for c in candidates
401             if c.target.raw_os == host_or_target.raw_os
402             and c.target.raw_cpu == host_or_target.raw_cpu
403         ]
404         if len(narrowed) == 1:
405             return narrowed[0].rust_target
407         # Finally, see if the vendor can be used to disambiguate.
408         narrowed = [c for c in candidates if c.target.vendor == host_or_target.vendor]
409         if len(narrowed) == 1:
410             return narrowed[0].rust_target
412         return None
414     rustc_target = find_candidate(candidates)
416     if rustc_target is None:
417         die("Don't know how to translate {} for rustc".format(host_or_target.alias))
419     return rustc_target
422 @imports("os")
423 @imports(_from="textwrap", _import="dedent")
424 @imports(_from="mozbuild.configure.util", _import="LineIO")
425 @imports(_from="__builtin__", _import="open")
426 def assert_rust_compile(host_or_target, rustc_target, rustc):
427     # Check to see whether our rustc has a reasonably functional stdlib
428     # for our chosen target.
429     target_arg = "--target=" + rustc_target
430     with create_temporary_file(suffix=".rs") as in_path, create_temporary_file(
431         suffix=".rlib"
432     ) as out_path:
433         with open(in_path, "w") as fd:
434             source = b'pub extern fn hello() { println!("Hello world"); }'
435             log.debug("Creating `%s` with content:", in_path)
436             with LineIO(lambda l: log.debug("| %s", l)) as out:
437                 out.write(source)
439             fd.write(source.decode())
441         cmd = [
442             rustc,
443             "--crate-type",
444             "staticlib",
445             target_arg,
446             "-o",
447             out_path,
448             in_path,
449         ]
451         def failed():
452             die(
453                 dedent(
454                     """\
455             Cannot compile for {} with {}
456             The target may be unsupported, or you may not have
457             a rust std library for that target installed. Try:
459               rustup target add {}
460             """.format(
461                         host_or_target.alias, rustc, rustc_target
462                     )
463                 )
464             )
466         check_cmd_output(*cmd, onerror=failed)
467         if not os.path.exists(out_path) or os.path.getsize(out_path) == 0:
468             failed()
471 @depends(
472     rustc,
473     host,
474     host_c_compiler,
475     rustc_info.host,
476     rust_supported_targets,
477     arm_target,
478     when=rust_compiler,
480 @checking("for rust host triplet")
481 @imports(_from="textwrap", _import="dedent")
482 def rust_host_triple(
483     rustc, host, compiler_info, rustc_host, rust_supported_targets, arm_target
485     rustc_target = detect_rustc_target(
486         host, compiler_info, arm_target, rust_supported_targets
487     )
488     if rustc_target != rustc_host:
489         if host.alias == rustc_target:
490             configure_host = host.alias
491         else:
492             configure_host = "{}/{}".format(host.alias, rustc_target)
493         die(
494             dedent(
495                 """\
496         The rust compiler host ({rustc}) is not suitable for the configure host ({configure}).
498         You can solve this by:
499         * Set your configure host to match the rust compiler host by editing your
500         mozconfig and adding "ac_add_options --host={rustc}".
501         * Or, install the rust toolchain for {configure}, if supported, by running
502         "rustup default stable-{rustc_target}"
503         """.format(
504                     rustc=rustc_host,
505                     configure=configure_host,
506                     rustc_target=rustc_target,
507                 )
508             )
509         )
510     assert_rust_compile(host, rustc_target, rustc)
511     return rustc_target
514 @depends(
515     rustc, target, c_compiler, rust_supported_targets, arm_target, when=rust_compiler
517 @checking("for rust target triplet")
518 def rust_target_triple(
519     rustc, target, compiler_info, rust_supported_targets, arm_target
521     rustc_target = detect_rustc_target(
522         target, compiler_info, arm_target, rust_supported_targets
523     )
524     assert_rust_compile(target, rustc_target, rustc)
525     return rustc_target
528 set_config("RUST_TARGET", rust_target_triple)
529 set_config("RUST_HOST_TARGET", rust_host_triple)
532 # This is used for putting source info into symbol files.
533 set_config("RUSTC_COMMIT", depends(rustc_info)(lambda i: i.commit))
535 # Rustdoc is required by Rust tests below.
536 option(env="RUSTDOC", nargs=1, help="Path to the rustdoc program")
538 rustdoc = check_prog(
539     "RUSTDOC",
540     ["rustdoc"],
541     paths=rust_search_path,
542     input="RUSTDOC",
543     allow_missing=True,
546 # This option is separate from --enable-tests because Rust tests are particularly
547 # expensive in terms of compile time (especially for code in libxul).
548 option(
549     "--enable-rust-tests",
550     help="Enable building and running of Rust tests during `make check`",
554 @depends("--enable-rust-tests", rustdoc)
555 def rust_tests(enable_rust_tests, rustdoc):
556     if enable_rust_tests and not rustdoc:
557         die("--enable-rust-tests requires rustdoc")
558     return bool(enable_rust_tests)
561 set_config("MOZ_RUST_TESTS", rust_tests)
564 @depends(target, c_compiler, rustc)
565 @imports("os")
566 def rustc_natvis_ldflags(target, compiler_info, rustc):
567     if target.kernel == "WINNT" and compiler_info.type == "clang-cl":
568         sysroot = check_cmd_output(rustc, "--print", "sysroot").strip()
569         etc = os.path.join(sysroot, "lib/rustlib/etc")
570         ldflags = []
571         if os.path.isdir(etc):
572             for f in os.listdir(etc):
573                 if f.endswith(".natvis"):
574                     ldflags.append("-NATVIS:" + normsep(os.path.join(etc, f)))
575         return ldflags
578 set_config("RUSTC_NATVIS_LDFLAGS", rustc_natvis_ldflags)
581 option(
582     "--enable-rust-debug",
583     default=depends(when="--enable-debug")(lambda: True),
584     help="{Build|Do not build} Rust code with debug assertions turned " "on.",
588 @depends(when="--enable-rust-debug")
589 def debug_rust():
590     return True
593 set_config("MOZ_DEBUG_RUST", debug_rust)
594 set_define("MOZ_DEBUG_RUST", debug_rust)
596 # ==============================================================
598 option(env="RUSTFLAGS", nargs=1, help="Rust compiler flags")
599 set_config("RUSTFLAGS", depends("RUSTFLAGS")(lambda flags: flags))
602 # Rust compiler flags
603 # ==============================================================
606 @depends(moz_optimize)
607 def rustc_opt_level_default(moz_optimize):
608     return "2" if moz_optimize.optimize else "0"
611 option(
612     env="RUSTC_OPT_LEVEL",
613     default=rustc_opt_level_default,
614     nargs=1,
615     help="Rust compiler optimization level (-C opt-level=%s)",
619 @depends("RUSTC_OPT_LEVEL")
620 def rustc_opt_level(opt_level_option):
621     return opt_level_option[0]
624 set_config("CARGO_PROFILE_RELEASE_OPT_LEVEL", rustc_opt_level)
625 set_config("CARGO_PROFILE_DEV_OPT_LEVEL", rustc_opt_level)
628 @depends(
629     rustc_opt_level,
630     debug_rust,
631     target,
632     "--enable-debug-symbols",
633     "--enable-frame-pointers",
634     path_remapping,
635     path_remappings,
637 def rust_compile_flags(
638     opt_level,
639     debug_rust,
640     target,
641     debug_symbols,
642     frame_pointers,
643     path_remapping,
644     path_remappings,
646     # Cargo currently supports only two interesting profiles for building:
647     # development and release. Those map (roughly) to --enable-debug and
648     # --disable-debug in Gecko, respectively.
649     #
650     # But we'd also like to support an additional axis of control for
651     # optimization level. Since Cargo only supports 2 profiles, we're in
652     # a bit of a bind.
653     #
654     # Code here derives various compiler options given other configure options.
655     # The options defined here effectively override defaults specified in
656     # Cargo.toml files.
658     debug_assertions = None
659     debug_info = None
661     # opt-level=0 implies -C debug-assertions, which may not be desired
662     # unless Rust debugging is enabled.
663     if opt_level == "0" and not debug_rust:
664         debug_assertions = False
666     if debug_symbols:
667         debug_info = "2"
669     opts = []
671     if debug_assertions is not None:
672         opts.append("debug-assertions=%s" % ("yes" if debug_assertions else "no"))
673     if debug_info is not None:
674         opts.append("debuginfo=%s" % debug_info)
675     if frame_pointers:
676         opts.append("force-frame-pointers=yes")
677     # CFG for arm64 is crashy, see `def security_hardening_cflags`.
678     if target.kernel == "WINNT" and target.cpu != "aarch64":
679         opts.append("control-flow-guard=yes")
681     flags = []
682     for opt in opts:
683         flags.extend(["-C", opt])
685     if "rust" in path_remapping:
686         # rustc has supported --remap-path-prefix since version 1.26, well
687         # before our required minimum Rust version, so there's no need to
688         # feature-detect or gate on versions.
689         for old, new in path_remappings:
690             flags.append(f"--remap-path-prefix={old}={new}")
692     return flags
695 # Rust incremental compilation
696 # ==============================================================
699 option("--disable-cargo-incremental", help="Disable incremental rust compilation.")
702 @depends(
703     developer_options,
704     debug_rust,
705     "MOZ_AUTOMATION",
706     code_coverage,
707     "--disable-cargo-incremental",
708     using_sccache,
709     "RUSTC_WRAPPER",
711 @imports("os")
712 def cargo_incremental(
713     developer_options,
714     debug_rust,
715     automation,
716     code_coverage,
717     enabled,
718     using_sccache,
719     rustc_wrapper,
721     """Return a value for the CARGO_INCREMENTAL environment variable."""
723     if not enabled:
724         return "0"
725     elif enabled.origin != "default":
726         return "1"
728     # We never want to use incremental compilation in automation.  sccache
729     # handles our automation use case much better than incremental compilation
730     # would.
731     if automation:
732         return "0"
734     # Coverage instrumentation doesn't play well with incremental compilation
735     # https://github.com/rust-lang/rust/issues/50203.
736     if code_coverage:
737         return "0"
739     # Incremental compilation doesn't work as well as it should, and if we're
740     # using sccache, it's better to use sccache than incremental compilation.
741     if not using_sccache and rustc_wrapper:
742         rustc_wrapper = os.path.basename(rustc_wrapper[0])
743         if os.path.splitext(rustc_wrapper)[0].lower() == "sccache":
744             using_sccache = True
745     if using_sccache:
746         return "0"
748     # Incremental compilation is automatically turned on for debug builds, so
749     # we don't need to do anything special here.
750     if debug_rust:
751         return
753     # Don't enable on --enable-release builds, because of the runtime
754     # performance cost.
755     if not developer_options:
756         return
758     # We're clear to use incremental compilation!
759     return "1"
762 set_config("CARGO_INCREMENTAL", cargo_incremental)
765 @depends(rust_compile_flags, "--enable-warnings-as-errors")
766 def rust_flags(compile_flags, warnings_as_errors):
767     warning_flags = []
769     # Note that cargo passes --cap-lints warn to rustc for third-party code, so
770     # we don't need a very complicated setup.
771     if warnings_as_errors:
772         warning_flags.append("-Dwarnings")
773     else:
774         warning_flags.extend(("--cap-lints", "warn"))
776     return compile_flags + warning_flags
779 set_config("MOZ_RUST_DEFAULT_FLAGS", rust_flags)