Bug 1770086 - Cleanup static on shutdown r=alwu
[gecko.git] / toolkit / moz.configure
blob0dd52bd5203b71c1e2fcac5fa2e1b791c770e043
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/.
7 # Set the MOZ_CONFIGURE_OPTIONS variable with all the options that
8 # were passed somehow (environment, command line, mozconfig)
9 @dependable
10 @imports(_from="mozbuild.shellutil", _import="quote")
11 @imports(_from="mozbuild.util", _import="ensure_unicode")
12 @imports(_from="mozbuild.util", _import="system_encoding")
13 @imports("__sandbox__")
14 def all_configure_options():
15     result = []
16     previous = None
17     for option in __sandbox__._options.values():
18         # __sandbox__._options contains items for both option.name and
19         # option.env. But it's also an OrderedDict, meaning both are
20         # consecutive.
21         # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not
22         # interesting.
23         if option == previous or option.env in ("OLD_CONFIGURE", "MOZCONFIG"):
24             continue
25         previous = option
26         value = __sandbox__._value_for(option)
27         # We only want options that were explicitly given on the command
28         # line, the environment, or mozconfig, and that differ from the
29         # defaults.
30         if (
31             value is not None
32             and value.origin not in ("default", "implied")
33             and value != option.default
34         ):
35             result.append(
36                 ensure_unicode(__sandbox__._raw_options[option], system_encoding)
37             )
38         # We however always include options that are sent to old configure
39         # because we don't know their actual defaults. (Keep the conditions
40         # separate for ease of understanding and ease of removal)
41         elif (
42             option.help == "Help missing for old configure options"
43             and option in __sandbox__._raw_options
44         ):
45             result.append(
46                 ensure_unicode(__sandbox__._raw_options[option], system_encoding)
47             )
49     # We shouldn't need this, but currently, quote will return a byte string
50     # if result is empty, and that's not wanted here.
51     if not result:
52         return ""
54     return quote(*result)
57 set_config("MOZ_CONFIGURE_OPTIONS", all_configure_options)
60 @depends(target)
61 def fold_libs(target):
62     return target.os in ("WINNT", "OSX", "Android")
65 set_config("MOZ_FOLD_LIBS", fold_libs)
67 # Profiling
68 # ==============================================================
69 # Some of the options here imply an option from js/moz.configure,
70 # so, need to be declared before the include.
72 option(
73     "--enable-jprof",
74     env="MOZ_JPROF",
75     help="Enable jprof profiling tool (needs mozilla/tools/jprof)",
79 @depends("--enable-jprof")
80 def jprof(value):
81     if value:
82         return True
85 set_config("MOZ_JPROF", jprof)
86 set_define("MOZ_JPROF", jprof)
87 imply_option("--enable-profiling", jprof)
90 @depends(target)
91 def gecko_profiler(target):
92     if target.os == "Android":
93         return target.cpu in ("aarch64", "arm", "x86", "x86_64")
94     elif target.kernel == "Linux":
95         return target.cpu in ("aarch64", "arm", "x86", "x86_64", "mips64")
96     elif target.kernel == "FreeBSD":
97         return target.cpu in ("aarch64", "x86_64")
98     return target.os in ("OSX", "WINNT")
101 @depends(gecko_profiler)
102 def gecko_profiler_define(value):
103     if value:
104         return True
107 set_config("MOZ_GECKO_PROFILER", gecko_profiler_define)
108 set_define("MOZ_GECKO_PROFILER", gecko_profiler_define)
111 # Whether code to parse ELF binaries should be compiled for the Gecko profiler
112 # (for symbol table dumping).
113 @depends(gecko_profiler, target)
114 def gecko_profiler_parse_elf(value, target):
115     # Currently we only want to build this code on Linux (including Android) and BSD.
116     # For Android, this is in order to dump symbols from Android system, where
117     # on other platforms there exist alternatives that don't require bloating
118     # up our binary size. For Linux more generally, we use this in profile
119     # pre-symbolication support, since MozDescribeCodeAddress doesn't do
120     # anything useful on that platform. (Ideally, we would update
121     # MozDescribeCodeAddress to call into some Rust crates that parse ELF and
122     # DWARF data, but build system issues currently prevent Rust from being
123     # used in mozglue.)
124     if value and (target.kernel == "Linux" or target.kernel == "FreeBSD"):
125         return True
128 set_config("MOZ_GECKO_PROFILER_PARSE_ELF", gecko_profiler_parse_elf)
129 set_define("MOZ_GECKO_PROFILER_PARSE_ELF", gecko_profiler_parse_elf)
131 # enable this by default if the profiler is enabled
132 # Note: also requires jemalloc
133 set_config("MOZ_PROFILER_MEMORY", gecko_profiler_define)
134 set_define("MOZ_PROFILER_MEMORY", gecko_profiler_define)
137 @depends(
138     "--enable-debug",
139     milestone,
140     build_project,
141     # Artifact builds are included because the downloaded artifacts can
142     # have DMD enabled.
143     when=artifact_builds | depends(when="--enable-replace-malloc")(lambda: True),
145 def dmd_default(debug, milestone, build_project):
146     return bool(build_project == "browser" and (debug or milestone.is_nightly))
149 option(
150     "--enable-dmd",
151     env="MOZ_DMD",
152     default=dmd_default,
153     help="{Enable|Disable} Dark Matter Detector (heap profiler). "
154     "Also enables jemalloc, replace-malloc and profiling",
158 @depends("--enable-dmd")
159 def dmd(value):
160     if value:
161         return True
164 set_config("MOZ_DMD", dmd)
165 set_define("MOZ_DMD", dmd)
166 add_old_configure_assignment("MOZ_DMD", dmd)
167 imply_option("--enable-profiling", dmd)
168 imply_option("--enable-jemalloc", dmd, when=compile_environment)
169 imply_option("--enable-replace-malloc", dmd, when=compile_environment)
171 # midir-based Web MIDI support
172 # ==============================================================
173 @depends(target)
174 def midir_linux_support(target):
175     return target.kernel == "Linux" and target.os != "Android"
178 @depends(target, midir_linux_support)
179 def midir_support(target, midir_linux_support):
180     if target.os in ("WINNT", "OSX") or midir_linux_support:
181         return True
184 set_config("MOZ_WEBMIDI_MIDIR_IMPL", midir_support)
186 # Enable various cubeb backends
187 # ==============================================================
188 @depends(target)
189 def audio_backends_default(target):
190     if target.os == "Android":
191         return (
192             "aaudio",
193             "opensl",
194         )
195     elif target.os in ("DragonFly", "FreeBSD", "SunOS"):
196         return ("oss",)
197     elif target.os == "OpenBSD":
198         return ("sndio",)
199     elif target.os == "OSX":
200         return ("audiounit",)
201     elif target.os == "WINNT":
202         return ("wasapi",)
203     else:
204         return ("pulseaudio",)
207 option(
208     "--enable-audio-backends",
209     nargs="+",
210     choices=(
211         "aaudio",
212         "alsa",
213         "audiounit",
214         "jack",
215         "opensl",
216         "oss",
217         "pulseaudio",
218         "sndio",
219         "wasapi",
220     ),
221     default=audio_backends_default,
222     help="{Enable|Disable} various cubeb backends",
226 @depends("--enable-audio-backends", target)
227 def imply_aaudio(values, target):
228     if any("aaudio" in value for value in values) and target.os != "Android":
229         die("Cannot enable AAudio on %s", target.os)
230     return any("aaudio" in value for value in values) or None
233 @depends("--enable-audio-backends", target)
234 def imply_alsa(values, target):
235     if (
236         any("alsa" in value for value in values)
237         and target.kernel != "Linux"
238         and target.os != "FreeBSD"
239     ):
240         die("Cannot enable ALSA on %s", target.os)
241     return any("alsa" in value for value in values) or None
244 @depends("--enable-audio-backends", target)
245 def imply_audiounit(values, target):
246     if (
247         any("audiounit" in value for value in values)
248         and target.os != "OSX"
249         and target.kernel != "Darwin"
250     ):
251         die("Cannot enable AudioUnit on %s", target.os)
252     return any("audiounit" in value for value in values) or None
255 @depends("--enable-audio-backends")
256 def imply_jack(values):
257     return any("jack" in value for value in values) or None
260 @depends("--enable-audio-backends", target)
261 def imply_opensl(values, target):
262     if any("opensl" in value for value in values) and target.os != "Android":
263         die("Cannot enable OpenSL on %s", target.os)
264     return any("opensl" in value for value in values) or None
267 @depends("--enable-audio-backends", target)
268 def imply_oss(values, target):
269     if any("oss" in value for value in values) and (
270         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
271     ):
272         die("Cannot enable OSS on %s", target.os)
273     return any("oss" in value for value in values) or None
276 @depends("--enable-audio-backends", target)
277 def imply_pulseaudio(values, target):
278     if any("pulseaudio" in value for value in values) and (
279         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
280     ):
281         die("Cannot enable PulseAudio on %s", target.os)
282     return any("pulseaudio" in value for value in values) or None
285 @depends("--enable-audio-backends", target)
286 def imply_sndio(values, target):
287     if any("sndio" in value for value in values) and (
288         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
289     ):
290         die("Cannot enable sndio on %s", target.os)
291     return any("sndio" in value for value in values) or None
294 @depends("--enable-audio-backends", target)
295 def imply_wasapi(values, target):
296     if any("wasapi" in value for value in values) and target.os != "WINNT":
297         die("Cannot enable WASAPI on %s", target.os)
298     return any("wasapi" in value for value in values) or None
301 set_config("MOZ_AAUDIO", imply_aaudio, when="--enable-audio-backends")
303 imply_option("--enable-alsa", imply_alsa, reason="--enable-audio-backends")
305 set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")
307 imply_option("--enable-jack", imply_jack, reason="--enable-audio-backends")
309 set_config("MOZ_OPENSL", imply_opensl, when="--enable-audio-backends")
311 set_config("MOZ_OSS", imply_oss, when="--enable-audio-backends")
313 imply_option("--enable-pulseaudio", imply_pulseaudio, reason="--enable-audio-backends")
315 imply_option("--enable-sndio", imply_sndio, reason="--enable-audio-backends")
317 set_config("MOZ_WASAPI", imply_wasapi, when="--enable-audio-backends")
319 # ALSA cubeb backend
320 # ==============================================================
321 option("--enable-alsa", env="MOZ_ALSA", help="Enable ALSA audio backend.")
324 @depends("--enable-alsa", midir_linux_support)
325 def enable_alsa_or_midir_linux_support(alsa_enabled, midir_linux_support):
326     return alsa_enabled or midir_linux_support
329 pkg_check_modules("MOZ_ALSA", "alsa", when=enable_alsa_or_midir_linux_support)
331 set_config("MOZ_ALSA", True, when="--enable-alsa")
333 # JACK cubeb backend
334 # ==============================================================
335 system_lib_option("--enable-jack", env="MOZ_JACK", help="Enable JACK audio backend.")
337 jack = pkg_check_modules("MOZ_JACK", "jack", when="--enable-jack")
339 set_config("MOZ_JACK", depends_if(jack)(lambda _: True))
341 # PulseAudio cubeb backend
342 # ==============================================================
343 option(
344     "--enable-pulseaudio",
345     env="MOZ_PULSEAUDIO",
346     help="{Enable|Disable} PulseAudio audio backend.",
349 pulseaudio = pkg_check_modules("MOZ_PULSEAUDIO", "libpulse", when="--enable-pulseaudio")
351 set_config("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
353 # sndio cubeb backend
354 # ==============================================================
355 system_lib_option("--enable-sndio", env="MOZ_SNDIO", help="Enable sndio audio backend.")
357 sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
359 set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
361 # Javascript engine
362 # ==============================================================
363 include("../js/moz.configure")
366 # NodeJS
367 # ==============================================================
368 include("../build/moz.configure/node.configure")
370 # L10N
371 # ==============================================================
372 option("--with-l10n-base", nargs=1, env="L10NBASEDIR", help="Path to l10n repositories")
375 @depends("--with-l10n-base", "MOZ_AUTOMATION", build_environment)
376 @imports(_from="os.path", _import="isdir")
377 @imports(_from="os.path", _import="expanduser")
378 @imports(_from="os", _import="environ")
379 def l10n_base(value, automation, build_env):
380     if value:
381         path = value[0]
382         if not isdir(path):
383             die("Invalid value --with-l10n-base, %s doesn't exist", path)
384     elif automation:
385         path = os.path.join(build_env.topsrcdir, "../l10n-central")
386     else:
387         path = os.path.join(
388             environ.get(
389                 "MOZBUILD_STATE_PATH", expanduser(os.path.join("~", ".mozbuild"))
390             ),
391             "l10n-central",
392         )
393     return os.path.realpath(os.path.abspath(path))
396 set_config("L10NBASEDIR", l10n_base)
399 # Default toolkit
400 # ==============================================================
401 @depends(target)
402 def toolkit_choices(target):
403     if target.os == "WINNT":
404         return ("cairo-windows",)
405     elif target.os == "OSX":
406         return ("cairo-cocoa",)
407     elif target.os == "Android":
408         return ("cairo-android",)
409     else:
410         return (
411             "cairo-gtk3",
412             "cairo-gtk3-wayland",
413             "cairo-gtk3-wayland-only",
414             "cairo-gtk3-x11-wayland",
415         )
418 @depends(toolkit_choices)
419 def toolkit_default(choices):
420     return choices[0]
423 option(
424     "--enable-default-toolkit",
425     nargs=1,
426     choices=toolkit_choices,
427     default=toolkit_default,
428     help="Select default toolkit",
432 @depends("--enable-default-toolkit")
433 def full_toolkit(value):
434     if value:
435         return value[0]
438 @depends(full_toolkit)
439 def toolkit(toolkit):
440     if toolkit.startswith("cairo-gtk3"):
441         widget_toolkit = "gtk"
442     else:
443         widget_toolkit = toolkit.replace("cairo-", "")
444     return widget_toolkit
447 set_config("MOZ_WIDGET_TOOLKIT", toolkit)
448 add_old_configure_assignment("MOZ_WIDGET_TOOLKIT", toolkit)
451 @depends(toolkit)
452 def toolkit_define(toolkit):
453     if toolkit != "windows":
454         return "MOZ_WIDGET_%s" % toolkit.upper()
457 set_define(toolkit_define, True)
460 @depends(toolkit)
461 def toolkit_gtk(toolkit):
462     return toolkit == "gtk"
465 # Wayland support
466 # ==============================================================
467 wayland_headers = pkg_check_modules(
468     "MOZ_WAYLAND",
469     "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1 libdrm >= 2.4",
470     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3"),
471     when=toolkit_gtk,
475 @depends(wayland_headers, toolkit_gtk, artifact_builds)
476 def wayland_headers(wayland, toolkit_gtk, artifacts):
477     if toolkit_gtk and artifacts:
478         return True
479     return wayland
482 set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
483 set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
485 # GL Provider
486 # ==============================================================
487 option("--with-gl-provider", nargs=1, help="Set GL provider backend type")
490 @depends("--with-gl-provider")
491 def gl_provider(value):
492     if value:
493         return value[0]
496 @depends(gl_provider)
497 def gl_provider_define(provider):
498     if provider:
499         return "GLContextProvider%s" % provider
502 set_define("MOZ_GL_PROVIDER", gl_provider_define)
505 @depends(gl_provider, wayland_headers, toolkit_gtk)
506 def gl_default_provider(value, wayland, toolkit_gtk):
507     if value:
508         return value
509     elif wayland:
510         return "EGL"
511     elif toolkit_gtk:
512         return "GLX"
515 set_config("MOZ_GL_PROVIDER", gl_provider)
516 set_config("MOZ_GL_DEFAULT_PROVIDER", gl_default_provider)
519 @depends(gl_default_provider)
520 def gl_provider_define(provider):
521     if provider:
522         return "GL_PROVIDER_%s" % provider
525 set_define(gl_provider_define, True)
528 # PDF printing
529 # ==============================================================
530 @depends(toolkit)
531 def pdf_printing(toolkit):
532     if toolkit in ("windows", "gtk", "android"):
533         return True
536 set_config("MOZ_PDF_PRINTING", pdf_printing)
537 set_define("MOZ_PDF_PRINTING", pdf_printing)
540 # Event loop instrumentation
541 # ==============================================================
542 option(env="MOZ_INSTRUMENT_EVENT_LOOP", help="Force-enable event loop instrumentation")
545 @depends("MOZ_INSTRUMENT_EVENT_LOOP", toolkit)
546 def instrument_event_loop(value, toolkit):
547     if value or (
548         toolkit in ("windows", "gtk", "cocoa", "android") and value.origin == "default"
549     ):
550         return True
553 set_config("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
554 set_define("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
557 # Fontconfig Freetype
558 # ==============================================================
559 option(env="USE_FC_FREETYPE", help="Force-enable the use of fontconfig freetype")
562 @depends("USE_FC_FREETYPE", toolkit)
563 def fc_freetype(value, toolkit):
564     if value or (toolkit == "gtk" and value.origin == "default"):
565         return True
568 add_old_configure_assignment("USE_FC_FREETYPE", fc_freetype)
569 set_define("USE_FC_FREETYPE", fc_freetype)
571 # Pango
572 # ==============================================================
573 pkg_check_modules("MOZ_PANGO", "pango >= 1.22.0", when=toolkit_gtk)
575 # Fontconfig
576 # ==============================================================
577 fontconfig_info = pkg_check_modules(
578     "_FONTCONFIG", "fontconfig >= 2.7.0", when=fc_freetype
582 @depends(fc_freetype)
583 def check_for_freetype2(fc_freetype):
584     if fc_freetype:
585         return True
588 # Check for freetype2. Flags are combined with fontconfig flags.
589 freetype2_info = pkg_check_modules(
590     "_FT2", "freetype2 >= 9.10.3", when=check_for_freetype2
594 @depends(fontconfig_info, freetype2_info)
595 def freetype2_combined_info(fontconfig_info, freetype2_info):
596     if not freetype2_info:
597         return
598     if not fontconfig_info:
599         return freetype2_info
600     return namespace(
601         cflags=freetype2_info.cflags + fontconfig_info.cflags,
602         libs=freetype2_info.libs + fontconfig_info.libs,
603     )
606 set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
608 # Apple platform decoder support
609 # ==============================================================
610 @depends(toolkit)
611 def applemedia(toolkit):
612     if toolkit in ("cocoa", "uikit"):
613         return True
616 set_config("MOZ_APPLEMEDIA", applemedia)
617 set_define("MOZ_APPLEMEDIA", applemedia)
619 # Windows Media Foundation support
620 # ==============================================================
621 option("--disable-wmf", help="Disable support for Windows Media Foundation")
624 @depends("--disable-wmf", target)
625 def wmf(value, target):
626     enabled = bool(value)
627     if value.origin == "default":
628         # Enable Windows Media Foundation support by default.
629         # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
630         # guaranteed to have a recent-enough SDK to build WMF.
631         enabled = target.os == "WINNT"
632     if enabled and target.os != "WINNT":
633         die("Cannot enable Windows Media Foundation support on %s", target.os)
634     if enabled:
635         return True
638 set_config("MOZ_WMF", wmf)
639 set_define("MOZ_WMF", wmf)
641 # FFmpeg H264/AAC Decoding Support
642 # ==============================================================
643 option("--disable-ffmpeg", help="Disable FFmpeg for fragmented H264/AAC decoding")
646 @depends("--disable-ffmpeg", target)
647 def ffmpeg(value, target):
648     enabled = bool(value)
649     if value.origin == "default":
650         enabled = target.os not in ("Android", "WINNT")
651     if enabled:
652         return True
655 set_config("MOZ_FFMPEG", ffmpeg)
656 set_define("MOZ_FFMPEG", ffmpeg)
657 imply_option("--enable-fmp4", ffmpeg, "--enable-ffmpeg")
659 # AV1 Video Codec Support
660 # ==============================================================
661 option("--disable-av1", help="Disable av1 video support")
664 @depends("--enable-av1")
665 def av1(value):
666     if value:
667         return True
670 @depends(target, when=av1 & compile_environment)
671 def dav1d_asm(target):
672     if target.cpu in ("aarch64", "x86", "x86_64"):
673         return True
676 @depends(target, when=av1 & compile_environment)
677 def dav1d_nasm(target):
678     if target.cpu in ("x86", "x86_64"):
679         return namespace(version="2.14", what="AV1")
682 set_config("MOZ_DAV1D_ASM", dav1d_asm)
683 set_define("MOZ_DAV1D_ASM", dav1d_asm)
684 set_config("MOZ_AV1", av1)
685 set_define("MOZ_AV1", av1)
687 # JXL Image Codec Support
688 # ==============================================================
689 option("--disable-jxl", help="Disable jxl image support")
692 @depends("--disable-jxl", milestone.is_nightly)
693 def jxl(value, is_nightly):
694     if is_nightly and value:
695         return True
698 set_config("MOZ_JXL", jxl)
699 set_define("MOZ_JXL", jxl)
701 # Built-in fragmented MP4 support.
702 # ==============================================================
703 option(
704     "--disable-fmp4",
705     env="MOZ_FMP4",
706     help="Disable support for in built Fragmented MP4 parsing",
710 @depends("--disable-fmp4", target, wmf, applemedia)
711 def fmp4(value, target, wmf, applemedia):
712     enabled = bool(value)
713     if value.origin == "default":
714         # target.os == 'Android' includes all B2G versions
715         enabled = wmf or applemedia or target.os == "Android"
716     if enabled:
717         return True
720 set_config("MOZ_FMP4", fmp4)
721 set_define("MOZ_FMP4", fmp4)
722 add_old_configure_assignment("MOZ_FMP4", fmp4)
725 @depends(target)
726 def sample_type_is_s16(target):
727     # Use integers over floats for audio on Android regardless of the CPU
728     # architecture, because audio backends for Android don't support floats.
729     # We also use integers on ARM because it's more efficient.
730     if target.os == "Android" or target.cpu == "arm":
731         return True
734 @depends(sample_type_is_s16)
735 def sample_type_is_float(t):
736     if not t:
737         return True
740 set_config("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
741 set_define("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
742 set_config("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
743 set_define("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
745 set_define("MOZ_VORBIS", sample_type_is_float)
746 set_config("MOZ_VORBIS", sample_type_is_float)
747 set_define("MOZ_TREMOR", sample_type_is_s16)
748 set_config("MOZ_TREMOR", sample_type_is_s16)
750 # OpenMAX IL Decoding Support
751 # ==============================================================
752 option("--enable-openmax", help="Enable OpenMAX IL for video/audio decoding")
755 @depends("--enable-openmax")
756 def openmax(value):
757     enabled = bool(value)
758     if enabled:
759         return True
762 set_config("MOZ_OMX", openmax)
763 set_define("MOZ_OMX", openmax)
765 # EME Support
766 # ==============================================================
767 @depends(target)
768 def eme_choices(target):
769     if (
770         target.kernel in ("WINNT", "Linux")
771         and target.os != "Android"
772         and target.cpu in ("x86", "x86_64")
773     ):
774         return ("widevine",)
775     if target.kernel == "WINNT" and target.cpu == "aarch64":
776         return ("widevine",)
777     if target.os in ("OSX"):
778         return ("widevine",)
781 # Widevine is enabled by default in desktop browser builds, except
782 # on aarch64 Windows.
783 @depends(build_project, eme_choices, target)
784 def eme_default(build_project, choices, target):
785     if build_project == "browser":
786         if target.kernel != "WINNT" or target.cpu != "aarch64":
787             return choices
790 option(
791     "--enable-eme",
792     nargs="+",
793     choices=eme_choices,
794     default=eme_default,
795     when=eme_choices,
796     help="{Enable|Disable} support for Encrypted Media Extensions",
800 @depends("--enable-eme", fmp4, when=eme_choices)
801 def eme(enabled, fmp4):
802     if enabled and enabled.origin != "default" and not fmp4:
803         die("Encrypted Media Extension support requires " "Fragmented MP4 support")
806 @depends("--enable-eme", when=eme_choices)
807 def eme_modules(value):
808     return value
811 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
812 # None.
813 set_config("MOZ_EME_MODULES", eme_modules | dependable([]))
816 @depends(eme_modules, target, when=eme_modules)
817 def eme_win32_artifact(modules, target):
818     if "widevine" in modules and target.kernel == "WINNT" and target.cpu == "aarch64":
819         return True
822 set_config("MOZ_EME_WIN32_ARTIFACT", eme_win32_artifact)
824 option(
825     name="--enable-chrome-format",
826     help="Select FORMAT of chrome files during packaging.",
827     nargs=1,
828     choices=("omni", "jar", "flat"),
829     default="omni",
833 @depends("--enable-chrome-format")
834 def packager_format(value):
835     return value[0]
838 set_config("MOZ_PACKAGER_FORMAT", packager_format)
840 # The packager minifies two different types of files: non-JS (mostly property
841 # files for l10n), and JS.  Setting MOZ_PACKAGER_MINIFY only minifies the
842 # former.  Firefox doesn't yet minify JS, due to concerns about debuggability.
844 # Also, the JS minification setup really only works correctly on Android:
845 # we need extra setup to use the newly-built shell for Linux and Windows,
846 # and cross-compilation for macOS requires some extra care.
849 @depends(target_is_android, "--enable-debug", milestone.is_nightly)
850 def enable_minify_default(is_android, debug, is_nightly):
851     if is_android and not debug and not is_nightly:
852         return ("properties", "js")
853     return ("properties",)
856 option(
857     name="--enable-minify",
858     help="Select types of files to minify during packaging.",
859     nargs="*",
860     choices=("properties", "js"),
861     default=enable_minify_default,
865 @depends("--enable-minify")
866 def enable_minify(value):
867     if "js" in value and "properties" not in value:
868         die("--enable-minify=js requires --enable-minify=properties.")
869     return namespace(
870         properties="properties" in value,
871         js="js" in value,
872     )
875 set_config("MOZ_PACKAGER_MINIFY", True, when=enable_minify.properties)
876 set_config("MOZ_PACKAGER_MINIFY_JS", True, when=enable_minify.js)
879 @depends(host, build_project)
880 def jar_maker_format(host, build_project):
881     # Multilocales for mobile/android use the same mergedirs for all locales,
882     # so we can't use symlinks for those builds.
883     if host.os == "WINNT" or build_project == "mobile/android":
884         return "flat"
885     return "symlink"
888 set_config("MOZ_JAR_MAKER_FILE_FORMAT", jar_maker_format)
891 @depends(toolkit)
892 def omnijar_name(toolkit):
893     # Fennec's static resources live in the assets/ folder of the
894     # APK.  Adding a path to the name here works because we only
895     # have one omnijar file in the final package (which is not the
896     # case on desktop).
897     return "assets/omni.ja" if toolkit == "android" else "omni.ja"
900 set_config("OMNIJAR_NAME", omnijar_name)
902 project_flag("MOZ_PLACES", help="Build Places if required", set_as_define=True)
904 project_flag(
905     "MOZ_SERVICES_HEALTHREPORT",
906     help="Build Firefox Health Reporter Service",
907     set_for_old_configure=True,
908     set_as_define=True,
911 project_flag(
912     "MOZ_NORMANDY",
913     help="Enable Normandy recipe runner",
914     set_for_old_configure=True,
915     set_as_define=True,
918 project_flag("MOZ_SERVICES_SYNC", help="Build Sync Services if required")
920 project_flag(
921     "MOZ_ANDROID_HISTORY",
922     help="Enable Android History instead of Places",
923     set_as_define=True,
926 project_flag(
927     "MOZ_DEDICATED_PROFILES",
928     help="Enable dedicated profiles per install",
929     set_as_define=True,
932 project_flag(
933     "MOZ_BLOCK_PROFILE_DOWNGRADE",
934     help="Block users from starting profiles last used by a newer build",
935     set_as_define=True,
939 @depends("MOZ_PLACES", "MOZ_ANDROID_HISTORY")
940 def check_places_and_android_history(places, android_history):
941     if places and android_history:
942         die("Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.")
945 option(
946     env="MOZ_TELEMETRY_REPORTING",
947     default=mozilla_official,
948     help="Enable telemetry reporting",
951 set_define("MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING")
952 add_old_configure_assignment(
953     "MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING"
957 @depends("MOZ_TELEMETRY_REPORTING", milestone.is_nightly)
958 def telemetry_on_by_default(reporting, is_nightly):
959     return reporting and is_nightly
962 set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
965 # gpsd support
966 # ==============================================================
967 system_lib_option("--enable-gpsd", env="MOZ_GPSD", help="Enable gpsd support")
970 @depends("--enable-gpsd")
971 def gpsd(value):
972     return bool(value)
975 system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
977 set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
979 # Miscellaneous programs
980 # ==============================================================
982 check_prog("TAR", ("gnutar", "gtar", "tar"))
983 check_prog("UNZIP", ("unzip",))
984 check_prog("GN", ("gn",), allow_missing=True)
986 # Key files
987 # ==============================================================
988 include("../build/moz.configure/keyfiles.configure")
990 simple_keyfile("Mozilla API")
992 simple_keyfile("Google Location Service API")
994 simple_keyfile("Google Safebrowsing API")
996 id_and_secret_keyfile("Bing API")
998 simple_keyfile("Adjust SDK")
1000 id_and_secret_keyfile("Leanplum SDK")
1002 simple_keyfile("Pocket API")
1005 # WebRender Debugger integration
1006 # ==============================================================
1008 option(
1009     "--enable-webrender-debugger", help="Build the websocket debug server in WebRender"
1012 set_config(
1013     "MOZ_WEBRENDER_DEBUGGER", depends_if("--enable-webrender-debugger")(lambda _: True)
1016 # Additional system headers defined at the application level
1017 # ==============================================================
1019 option(
1020     "--enable-app-system-headers",
1021     env="MOZ_APP_SYSTEM_HEADERS",
1022     help="Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild",
1026 @depends("--enable-app-system-headers")
1027 def app_system_headers(value):
1028     if value:
1029         return True
1032 set_config("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1033 set_define("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1035 # Printing
1036 # ==============================================================
1037 option("--disable-printing", help="Disable printing support")
1040 @depends("--disable-printing")
1041 def printing(value):
1042     if value:
1043         return True
1046 set_config("NS_PRINTING", printing)
1047 set_define("NS_PRINTING", printing)
1048 set_define("NS_PRINT_PREVIEW", printing)
1050 # Speech-dispatcher support
1051 # ==============================================================
1052 @depends(toolkit)
1053 def no_speechd_on_non_gtk(toolkit):
1054     if toolkit != "gtk":
1055         return False
1058 imply_option(
1059     "--enable-synth-speechd", no_speechd_on_non_gtk, reason="--enable-default-toolkit"
1062 option("--disable-synth-speechd", help="Disable speech-dispatcher support")
1064 set_config("MOZ_SYNTH_SPEECHD", depends_if("--disable-synth-speechd")(lambda _: True))
1066 # Speech API
1067 # ==============================================================
1068 option("--disable-webspeech", help="Disable support for HTML Speech API")
1071 @depends("--disable-webspeech")
1072 def webspeech(value):
1073     if value:
1074         return True
1077 set_config("MOZ_WEBSPEECH", webspeech)
1078 set_define("MOZ_WEBSPEECH", webspeech)
1079 add_old_configure_assignment("MOZ_WEBSPEECH", webspeech)
1081 # Speech API test backend
1082 # ==============================================================
1083 option(
1084     "--enable-webspeechtestbackend",
1085     default=webspeech,
1086     help="{Enable|Disable} support for HTML Speech API Test Backend",
1090 @depends_if("--enable-webspeechtestbackend")
1091 def webspeech_test_backend(value):
1092     return True
1095 set_config("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1096 set_define("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1098 # Graphics
1099 # ==============================================================
1100 @depends(target, milestone)
1101 def skia_pdf_default(target, milestone):
1102     return milestone.is_nightly and target.os != "WINNT"
1105 option("--enable-skia-pdf", default=skia_pdf_default, help="{Enable|Disable} Skia PDF")
1107 set_config("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1108 set_define("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1110 set_config(
1111     "SKIA_INCLUDES",
1112     [
1113         "/gfx/skia",
1114         "/gfx/skia/skia",
1115     ],
1118 system_lib_option(
1119     "--with-system-webp", help="Use system libwebp (located with pkgconfig)"
1122 system_webp = pkg_check_modules(
1123     "MOZ_WEBP", "libwebp >= 1.0.2 libwebpdemux >= 1.0.2", when="--with-system-webp"
1126 set_config("MOZ_SYSTEM_WEBP", depends(when=system_webp)(lambda: True))
1128 # Build Freetype in the tree
1129 # ==============================================================
1130 @depends(target, "--enable-skia-pdf")
1131 def tree_freetype(target, skia_pdf):
1132     if target.os == "Android" or (skia_pdf and target.os == "WINNT"):
1133         return True
1136 set_define("MOZ_TREE_FREETYPE", tree_freetype)
1137 set_config("MOZ_TREE_FREETYPE", tree_freetype)
1139 set_define("HAVE_FT_BITMAP_SIZE_Y_PPEM", tree_freetype)
1140 set_define("HAVE_FT_GLYPHSLOT_EMBOLDEN", tree_freetype)
1141 set_define("HAVE_FT_LOAD_SFNT_TABLE", tree_freetype)
1144 @depends(freetype2_combined_info, tree_freetype, build_environment)
1145 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
1146     if tree_freetype:
1147         return namespace(
1148             cflags=("-I%s/modules/freetype2/include" % build_env.topsrcdir,), libs=()
1149         )
1150     if freetype2_combined_info:
1151         return freetype2_combined_info
1154 set_config("FT2_LIBS", ft2_info.libs)
1157 @depends(target, tree_freetype, freetype2_info)
1158 def enable_cairo_ft(target, tree_freetype, freetype2_info):
1159     # Avoid defining MOZ_ENABLE_CAIRO_FT on Windows platforms because
1160     # "cairo-ft-font.c" includes <dlfcn.h>, which only exists on posix platforms
1161     return freetype2_info or (tree_freetype and target.os != "WINNT")
1164 set_config("MOZ_ENABLE_CAIRO_FT", True, when=enable_cairo_ft)
1165 set_config("CAIRO_FT_CFLAGS", ft2_info.cflags, when=enable_cairo_ft)
1168 # WebDriver (HTTP / BiDi)
1169 # ==============================================================
1171 # WebDriver is a remote control interface that enables introspection and
1172 # control of user agents. It provides a platform- and language-neutral wire
1173 # protocol as a way for out-of-process programs to remotely instruct the
1174 # behavior of web browsers.
1176 # The Gecko implementation is backed by Marionette and Remote Agent.
1177 # Both protocols are not really toolkit features, as much as Gecko engine
1178 # features. But they are enabled based on the toolkit, so here it lives.
1180 # Marionette remote protocol
1181 # -----------------------------------------------------------
1183 # Marionette is the Gecko remote protocol used for various remote control,
1184 # automation, and testing purposes throughout Gecko-based applications like
1185 # Firefox, Thunderbird, and any mobile browser built upon GeckoView.
1187 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
1188 # implementation.
1190 # The source of Marionette lives in ../remote/marionette.
1192 # For more information, see:
1193 # https://firefox-source-docs.mozilla.org/testing/marionette/index.html
1195 # Remote Agent (WebDriver BiDi / partial CDP)
1196 # -----------------------------------------------------------
1198 # The primary purpose is the implementation of the WebDriver BiDi specification.
1199 # But it also complements the existing Firefox Developer Tools Remote Debugging
1200 # Protocol (RDP) by implementing a subset of the Chrome DevTools Protocol (CDP).
1202 # The source of Remote Agent lives in ../remote.
1204 # For more information, see:
1205 # https://firefox-source-docs.mozilla.org/remote/index.html
1208 option(
1209     "--disable-webdriver",
1210     help="Disable support for WebDriver remote protocols",
1214 @depends("--disable-webdriver")
1215 def webdriver(enabled):
1216     if enabled:
1217         return True
1220 set_config("ENABLE_WEBDRIVER", webdriver)
1221 set_define("ENABLE_WEBDRIVER", webdriver)
1224 # geckodriver WebDriver implementation
1225 # ==============================================================
1227 # Turn off geckodriver for build configs we don't handle yet,
1228 # but allow --enable-geckodriver to override when compile environment is available.
1229 # --disable-tests implies disabling geckodriver.
1230 # Disable building in CI
1233 @depends(
1234     "--enable-tests", target, cross_compiling, hazard_analysis, asan, "MOZ_AUTOMATION"
1236 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
1237     if not enable_tests:
1238         return False
1239     if hazard or target.os == "Android" or (asan and cross_compile):
1240         return False
1241     if automation:
1242         return False
1243     return True
1246 option(
1247     "--enable-geckodriver",
1248     default=geckodriver_default,
1249     when="--enable-compile-environment",
1250     help="{Build|Do not build} geckodriver",
1254 @depends("--enable-geckodriver", when="--enable-compile-environment")
1255 def geckodriver(enabled):
1256     if enabled:
1257         return True
1260 set_config("MOZ_GECKODRIVER", geckodriver)
1263 # WebRTC
1264 # ========================================================
1265 @depends(target)
1266 def webrtc_default(target):
1267     # Turn off webrtc for OS's we don't handle yet, but allow
1268     # --enable-webrtc to override.
1269     os_match = False
1270     for os_fragment in (
1271         "linux",
1272         "mingw",
1273         "android",
1274         "linuxandroid",
1275         "dragonfly",
1276         "freebsd",
1277         "netbsd",
1278         "openbsd",
1279         "darwin",
1280     ):
1281         if target.raw_os.startswith(os_fragment):
1282             os_match = True
1284     cpu_match = False
1285     if (
1286         target.cpu
1287         in (
1288             "x86_64",
1289             "arm",
1290             "aarch64",
1291             "x86",
1292             "ia64",
1293             "mips32",
1294             "mips64",
1295         )
1296         or target.cpu.startswith("ppc")
1297     ):
1298         cpu_match = True
1300     if os_match and cpu_match:
1301         return True
1302     return False
1305 option(
1306     "--disable-webrtc",
1307     default=webrtc_default,
1308     help="{Enable|Disable} support for WebRTC",
1312 @depends("--disable-webrtc")
1313 def webrtc(enabled):
1314     if enabled:
1315         return True
1318 set_config("MOZ_WEBRTC", webrtc)
1319 set_define("MOZ_WEBRTC", webrtc)
1320 set_config("MOZ_SCTP", webrtc)
1321 set_define("MOZ_SCTP", webrtc)
1322 set_config("MOZ_SRTP", webrtc)
1323 set_define("MOZ_SRTP", webrtc)
1324 set_config("MOZ_WEBRTC_SIGNALING", webrtc)
1325 set_define("MOZ_WEBRTC_SIGNALING", webrtc)
1326 set_config("MOZ_PEERCONNECTION", webrtc)
1327 set_define("MOZ_PEERCONNECTION", webrtc)
1328 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1329 # opt/production builds (via MOZ_CRASH())
1330 set_config("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1331 set_define("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1333 # RAW media
1334 # ==============================================================
1337 @depends(target, webrtc)
1338 def raw_media_default(target, webrtc):
1339     if target.os == "Android":
1340         return True
1341     if webrtc:
1342         return True
1345 option(
1346     "--enable-raw",
1347     default=raw_media_default,
1348     help="{Enable|Disable} support for RAW media",
1351 set_config("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1352 set_define("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1355 # X11
1356 # ==============================================================
1357 @depends(webrtc, when=toolkit_gtk)
1358 def x11_libs(webrtc):
1359     libs = [
1360         "x11",
1361         "xcb",
1362         "xcb-shm",
1363         "x11-xcb",
1364         "xext",
1365         "xrandr >= 1.4.0",
1366     ]
1367     if webrtc:
1368         # third_party/libwebrtc/webrtc/webrtc_gn/moz.build adds those
1369         # manually, ensure they're available.
1370         libs += [
1371             "xcomposite",
1372             "xcursor",
1373             "xdamage",
1374             "xfixes",
1375             "xi",
1376             "xtst",
1377         ]
1378     return libs
1381 x11_headers = pkg_check_modules(
1382     "MOZ_X11",
1383     x11_libs,
1384     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1385     when=depends(full_toolkit)(
1386         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1387     ),
1391 set_config("MOZ_X11", True, when=x11_headers)
1392 set_define("MOZ_X11", True, when=x11_headers)
1394 pkg_check_modules(
1395     "MOZ_X11_SM",
1396     ["ice", "sm"],
1397     cflags_only=True,
1398     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1399     when=depends(full_toolkit)(
1400         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1401     ),
1405 # ASan Reporter Addon
1406 # ==============================================================
1407 option(
1408     "--enable-address-sanitizer-reporter",
1409     help="Enable Address Sanitizer Reporter Extension",
1413 @depends("--enable-address-sanitizer-reporter")
1414 def enable_asan_reporter(value):
1415     if value:
1416         return True
1419 set_config("MOZ_ASAN_REPORTER", enable_asan_reporter)
1420 set_define("MOZ_ASAN_REPORTER", enable_asan_reporter)
1421 add_old_configure_assignment("MOZ_ASAN_REPORTER", enable_asan_reporter)
1423 # Elfhack
1424 # ==============================================================
1425 with only_when("--enable-compile-environment"):
1427     @depends(host, target)
1428     def has_elfhack(host, target):
1429         return (
1430             target.kernel == "Linux"
1431             and host.kernel == "Linux"
1432             and target.cpu in ("arm", "aarch64", "x86", "x86_64")
1433         )
1435     @depends("--enable-release", enable_linker)
1436     def default_elfhack(release, linker):
1437         # Disable elfhack when explicitly building with --enable-linker=lld
1438         if linker and linker.origin != "default" and linker[0] == "lld":
1439             return False
1440         return bool(release)
1442     with only_when(has_elfhack):
1443         option(
1444             "--disable-elf-hack",
1445             default=default_elfhack,
1446             help="{Enable|Disable} elf hacks",
1447         )
1449         set_config("USE_ELF_HACK", depends_if("--enable-elf-hack")(lambda _: True))
1452 @depends(build_environment)
1453 def idl_roots(build_env):
1454     return namespace(
1455         ipdl_root=os.path.join(build_env.topobjdir, "ipc", "ipdl"),
1456         webidl_root=os.path.join(build_env.topobjdir, "dom", "bindings"),
1457         xpcom_root=os.path.join(build_env.topobjdir, "xpcom", "components"),
1458     )
1461 set_config("WEBIDL_ROOT", idl_roots.webidl_root)
1462 set_config("IPDL_ROOT", idl_roots.ipdl_root)
1463 set_config("XPCOM_ROOT", idl_roots.xpcom_root)
1465 # Proxy bypass protection
1466 # ==============================================================
1468 option(
1469     "--enable-proxy-bypass-protection",
1470     help="Prevent suspected or confirmed proxy bypasses",
1474 @depends_if("--enable-proxy-bypass-protection")
1475 def proxy_bypass_protection(_):
1476     return True
1479 set_config("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1480 set_define("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1482 # Proxy direct failover
1483 # ==============================================================
1485 option(
1486     "--disable-proxy-direct-failover",
1487     help="Disable direct failover for system requests",
1491 @depends_if("--disable-proxy-direct-failover")
1492 def proxy_direct_failover(value):
1493     if value:
1494         return True
1497 set_config("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1498 set_define("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1500 # MIDL
1501 # ==============================================================
1504 @depends(c_compiler, toolchain_prefix)
1505 def midl_names(c_compiler, toolchain_prefix):
1506     if c_compiler and c_compiler.type in ["gcc", "clang"]:
1507         # mingw
1508         widl = ("widl",)
1509         if toolchain_prefix:
1510             prefixed = tuple("%s%s" % (p, "widl") for p in toolchain_prefix)
1511             widl = prefixed + widl
1512         return widl
1514     return ("midl.exe",)
1517 @depends(target, "--enable-compile-environment")
1518 def check_for_midl(target, compile_environment):
1519     if target.os != "WINNT":
1520         return
1522     if compile_environment:
1523         return True
1526 midl = check_prog(
1527     "MIDL",
1528     midl_names,
1529     when=check_for_midl,
1530     allow_missing=True,
1531     paths=sdk_bin_path,
1532     # MIDL being used from a python wrapper script, we can live with it
1533     # having spaces.
1534     allow_spaces=True,
1537 option(env="MIDL_FLAGS", nargs=1, help="Extra flags to pass to MIDL")
1540 @depends(
1541     "MIDL_FLAGS",
1542     target,
1543     midl,
1544     when=depends(midl, target)(lambda m, t: m and t.kernel == "WINNT"),
1546 def midl_flags(flags, target, midl):
1547     if flags:
1548         flags = flags[0].split()
1549     else:
1550         flags = []
1552     if not midl.endswith("widl"):
1553         env = {
1554             "x86": "win32",
1555             "x86_64": "x64",
1556             "aarch64": "arm64",
1557         }[target.cpu]
1558         return flags + ["-nologo", "-no_cpp", "-env", env]
1560     # widl
1561     return flags + {
1562         "x86": ["--win32", "-m32"],
1563         "x86_64": ["--win64", "-m64"],
1564     }[target.cpu]
1567 set_config("MIDL_FLAGS", midl_flags)
1569 # Accessibility
1570 # ==============================================================
1572 option("--disable-accessibility", help="Disable accessibility support")
1575 @depends("--enable-accessibility", check_for_midl, midl, c_compiler)
1576 def accessibility(value, check_for_midl, midl, c_compiler):
1577     enabled = bool(value)
1579     if not enabled:
1580         return
1582     if check_for_midl and not midl:
1583         if c_compiler and c_compiler.type in ("gcc", "clang"):
1584             die(
1585                 "You have accessibility enabled, but widl could not be found. "
1586                 "Add --disable-accessibility to your mozconfig or install widl. "
1587                 "See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details."
1588             )
1589         else:
1590             die(
1591                 "MIDL could not be found. "
1592                 "Building accessibility without MIDL is not supported."
1593             )
1595     return enabled
1598 set_config("ACCESSIBILITY", accessibility)
1599 set_define("ACCESSIBILITY", accessibility)
1602 @depends(moz_debug, developer_options)
1603 def a11y_log(debug, developer_options):
1604     return debug or developer_options
1607 set_config("A11Y_LOG", True, when=a11y_log)
1608 set_define("A11Y_LOG", True, when=a11y_log)
1611 # Addon signing
1612 # ==============================================================
1613 @depends(milestone)
1614 def require_signing(milestone):
1615     return milestone.is_release_or_beta and not milestone.is_esr
1618 option(
1619     env="MOZ_REQUIRE_SIGNING",
1620     default=require_signing,
1621     help="Enforce that add-ons are signed by the trusted root",
1624 set_config("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1625 set_define("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1627 option(
1628     "--with-unsigned-addon-scopes",
1629     nargs="+",
1630     choices=("app", "system"),
1631     help="Addon scopes where signature is not required",
1635 @depends("--with-unsigned-addon-scopes")
1636 def unsigned_addon_scopes(scopes):
1637     return namespace(
1638         app="app" in scopes or None,
1639         system="system" in scopes or None,
1640     )
1643 set_config("MOZ_UNSIGNED_APP_SCOPE", unsigned_addon_scopes.app)
1644 set_config("MOZ_UNSIGNED_SYSTEM_SCOPE", unsigned_addon_scopes.system)
1647 # Addon sideloading
1648 # ==============================================================
1649 option(
1650     "--allow-addon-sideload",
1651     default=milestone.is_esr,
1652     help="Addon sideloading is allowed",
1656 set_config("MOZ_ALLOW_ADDON_SIDELOAD", True, when="--allow-addon-sideload")
1658 # WebExtensions API WebIDL bindings
1659 # ==============================================================
1662 @depends(milestone)
1663 def extensions_webidl_bindings_default(milestone):
1664     # Only enable the webidl bindings for the WebExtensions APIs
1665     # in Nightly.
1666     return milestone.is_nightly
1669 option(
1670     "--enable-extensions-webidl-bindings",
1671     default=extensions_webidl_bindings_default,
1672     help="{Enable|Disable} building experimental WebExtensions WebIDL bindings",
1676 @depends("--enable-extensions-webidl-bindings")
1677 def extensions_webidl_enabled(value):
1678     return bool(value)
1681 set_config("MOZ_WEBEXT_WEBIDL_ENABLED", extensions_webidl_enabled)
1683 # Launcher process (Windows only)
1684 # ==============================================================
1687 @depends(target)
1688 def launcher_process_default(target):
1689     return target.os == "WINNT"
1692 option(
1693     "--enable-launcher-process",
1694     default=launcher_process_default,
1695     help="{Enable|Disable} launcher process by default",
1699 @depends("--enable-launcher-process", target)
1700 def launcher(value, target):
1701     enabled = bool(value)
1702     if enabled and target.os != "WINNT":
1703         die("Cannot enable launcher process on %s", target.os)
1704     if enabled:
1705         return True
1708 set_config("MOZ_LAUNCHER_PROCESS", launcher)
1709 set_define("MOZ_LAUNCHER_PROCESS", launcher)
1711 # llvm-dlltool (Windows only)
1712 # ==============================================================
1715 @depends(build_project, target, "--enable-compile-environment")
1716 def check_for_llvm_dlltool(build_project, target, compile_environment):
1717     if build_project != "browser":
1718         return
1720     if target.os != "WINNT":
1721         return
1723     return compile_environment
1726 llvm_dlltool = check_prog(
1727     "LLVM_DLLTOOL",
1728     ("llvm-dlltool",),
1729     what="llvm-dlltool",
1730     when=check_for_llvm_dlltool,
1731     paths=clang_search_path,
1735 @depends(target, when=llvm_dlltool)
1736 def llvm_dlltool_flags(target):
1737     arch = {
1738         "x86": "i386",
1739         "x86_64": "i386:x86-64",
1740         "aarch64": "arm64",
1741     }[target.cpu]
1743     return ["-m", arch]
1746 set_config("LLVM_DLLTOOL_FLAGS", llvm_dlltool_flags)
1748 # BITS download (Windows only)
1749 # ==============================================================
1751 option(
1752     "--enable-bits-download",
1753     when=target_is_windows,
1754     default=target_is_windows,
1755     help="{Enable|Disable} building BITS download support",
1758 set_define(
1759     "MOZ_BITS_DOWNLOAD",
1760     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1762 set_config(
1763     "MOZ_BITS_DOWNLOAD",
1764     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1767 # Bundled fonts on desktop platform
1768 # ==============================================================
1771 @depends(target)
1772 def bundled_fonts_default(target):
1773     return target.os == "WINNT" or target.kernel == "Linux"
1776 @depends(build_project)
1777 def allow_bundled_fonts(project):
1778     return project == "browser" or project == "comm/mail"
1781 option(
1782     "--enable-bundled-fonts",
1783     default=bundled_fonts_default,
1784     when=allow_bundled_fonts,
1785     help="{Enable|Disable} support for bundled fonts on desktop platforms",
1788 set_define(
1789     "MOZ_BUNDLED_FONTS",
1790     depends_if("--enable-bundled-fonts", when=allow_bundled_fonts)(lambda _: True),
1793 # Reflow counting
1794 # ==============================================================
1797 @depends(moz_debug)
1798 def reflow_perf(debug):
1799     if debug:
1800         return True
1803 option(
1804     "--enable-reflow-perf",
1805     default=reflow_perf,
1806     help="{Enable|Disable} reflow performance tracing",
1809 # The difference in conditions here comes from the initial implementation
1810 # in old-configure, which was unexplained there as well.
1811 set_define("MOZ_REFLOW_PERF", depends_if("--enable-reflow-perf")(lambda _: True))
1812 set_define("MOZ_REFLOW_PERF_DSP", reflow_perf)
1814 # Layout debugger
1815 # ==============================================================
1818 @depends(moz_debug)
1819 def layout_debugger(debug):
1820     if debug:
1821         return True
1824 option(
1825     "--enable-layout-debugger",
1826     default=layout_debugger,
1827     help="{Enable|Disable} layout debugger",
1830 set_config("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1831 set_define("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1834 # Shader Compiler for Windows (and MinGW Cross Compile)
1835 # ==============================================================
1837 with only_when(compile_environment):
1838     fxc = check_prog(
1839         "FXC",
1840         ("fxc.exe", "fxc2.exe"),
1841         when=depends(target)(lambda t: t.kernel == "WINNT"),
1842         paths=sdk_bin_path,
1843         # FXC being used from a python wrapper script, we can live with it
1844         # having spaces.
1845         allow_spaces=True,
1846     )
1849 # VPX
1850 # ===
1852 with only_when(compile_environment):
1853     system_lib_option(
1854         "--with-system-libvpx", help="Use system libvpx (located with pkgconfig)"
1855     )
1857     with only_when("--with-system-libvpx"):
1858         vpx = pkg_check_modules("MOZ_LIBVPX", "vpx >= 1.8.0")
1860         check_header(
1861             "vpx/vpx_decoder.h",
1862             flags=vpx.cflags,
1863             onerror=lambda: die(
1864                 "Couldn't find vpx/vpx_decoder.h, which is required to build "
1865                 "with system libvpx. Use --without-system-libvpx to build "
1866                 "with in-tree libvpx."
1867             ),
1868         )
1870         check_symbol(
1871             "vpx_codec_dec_init_ver",
1872             flags=vpx.libs,
1873             onerror=lambda: die(
1874                 "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1875                 "not found"
1876             ),
1877         )
1879         set_config("MOZ_SYSTEM_LIBVPX", True)
1881     @depends("--with-system-libvpx", target)
1882     def in_tree_vpx(system_libvpx, target):
1883         if system_libvpx:
1884             return
1886         arm_asm = (target.cpu == "arm") or None
1887         return namespace(arm_asm=arm_asm)
1889     @depends(target, when=in_tree_vpx)
1890     def vpx_nasm(target):
1891         if target.cpu in ("x86", "x86_64"):
1892             if target.kernel == "WINNT":
1893                 # Version 2.03 is needed for automatic safeseh support.
1894                 return namespace(version="2.03", what="VPX")
1895             return namespace(what="VPX")
1897     # Building with -mfpu=neon requires either the "softfp" or the
1898     # "hardfp" ABI. Depending on the compiler's default target, and the
1899     # CFLAGS, the default ABI might be neither, in which case it is the
1900     # "softfloat" ABI.
1901     # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
1902     # we can safely mix code built with both ABIs. So, if we detect
1903     # that compiling uses the "softfloat" ABI, force the use of the
1904     # "softfp" ABI instead.
1905     # Confusingly, the __SOFTFP__ preprocessor variable indicates the
1906     # "softfloat" ABI, not the "softfp" ABI.
1907     # Note: VPX_ASFLAGS is also used in CFLAGS.
1908     softfp = cxx_compiler.try_compile(
1909         body="""
1910         #ifndef __SOFTFP__
1911         #error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
1912         #endif""",
1913         when=in_tree_vpx.arm_asm,
1914     )
1916     @depends(in_tree_vpx, vpx_nasm, softfp, target)
1917     def vpx_as_flags(vpx, vpx_nasm, softfp, target):
1918         flags = []
1919         if vpx and vpx.arm_asm:
1920             # These flags are a lie; they're just used to enable the requisite
1921             # opcodes; actual arch detection is done at runtime.
1922             flags = ["-march=armv7-a", "-mfpu=neon"]
1923             if softfp:
1924                 flags.append("-mfloat-abi=softfp")
1925         elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64":
1926             flags = ["-DPIC"]
1927         return flags
1929     set_config("VPX_USE_NASM", True, when=vpx_nasm)
1930     set_config("VPX_ASFLAGS", vpx_as_flags)
1933 # JPEG
1934 # ====
1936 with only_when(compile_environment):
1937     system_lib_option(
1938         "--with-system-jpeg",
1939         nargs="?",
1940         help="Use system libjpeg (installed at given prefix)",
1941     )
1943     @depends_if("--with-system-jpeg")
1944     def jpeg_flags(value):
1945         if len(value):
1946             return namespace(
1947                 cflags=("-I%s/include" % value[0],),
1948                 ldflags=("-L%s/lib" % value[0], "-ljpeg"),
1949             )
1950         return namespace(
1951             ldflags=("-ljpeg",),
1952         )
1954     with only_when("--with-system-jpeg"):
1955         check_symbol(
1956             "jpeg_destroy_compress",
1957             flags=jpeg_flags.ldflags,
1958             onerror=lambda: die(
1959                 "--with-system-jpeg requested but symbol "
1960                 "jpeg_destroy_compress not found."
1961             ),
1962         )
1964         c_compiler.try_compile(
1965             includes=[
1966                 "stdio.h",
1967                 "sys/types.h",
1968                 "jpeglib.h",
1969             ],
1970             body="""
1971                 #if JPEG_LIB_VERSION < 62
1972                 #error Insufficient JPEG library version
1973                 #endif
1974             """,
1975             flags=jpeg_flags.cflags,
1976             check_msg="for sufficient jpeg library version",
1977             onerror=lambda: die(
1978                 "Insufficient JPEG library version for "
1979                 "--with-system-jpeg (62 required)"
1980             ),
1981         )
1983         c_compiler.try_compile(
1984             includes=[
1985                 "stdio.h",
1986                 "sys/types.h",
1987                 "jpeglib.h",
1988             ],
1989             body="""
1990                 #ifndef JCS_EXTENSIONS
1991                 #error libjpeg-turbo JCS_EXTENSIONS required
1992                 #endif
1993             """,
1994             flags=jpeg_flags.cflags,
1995             check_msg="for sufficient libjpeg-turbo JCS_EXTENSIONS",
1996             onerror=lambda: die(
1997                 "libjpeg-turbo JCS_EXTENSIONS required for " "--with-system-jpeg"
1998             ),
1999         )
2001         set_config("MOZ_JPEG_CFLAGS", jpeg_flags.cflags)
2002         set_config("MOZ_JPEG_LIBS", jpeg_flags.ldflags)
2004     @depends("--with-system-jpeg", target)
2005     def in_tree_jpeg_arm(system_jpeg, target):
2006         if system_jpeg:
2007             return
2009         if target.cpu == "arm":
2010             return ("-march=armv7-a", "-mfpu=neon")
2011         elif target.cpu == "aarch64":
2012             return ("-march=armv8-a",)
2014     @depends("--with-system-jpeg", target)
2015     def in_tree_jpeg_mips64(system_jpeg, target):
2016         if system_jpeg:
2017             return
2019         if target.cpu == "mips64":
2020             return ("-Wa,-mloongson-mmi", "-mloongson-ext")
2022     # Compiler check from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L419
2023     jpeg_mips64_mmi = c_compiler.try_compile(
2024         body='int c = 0, a = 0, b = 0; asm("paddb %0, %1, %2" : "=f" (c) : "f" (a), "f" (b));',
2025         check_msg="for loongson mmi support",
2026         flags=in_tree_jpeg_mips64,
2027         when=in_tree_jpeg_mips64,
2028     )
2030     @depends(
2031         "--with-system-jpeg",
2032         target,
2033         in_tree_jpeg_arm,
2034         in_tree_jpeg_mips64,
2035         jpeg_mips64_mmi,
2036     )
2037     def in_tree_jpeg(
2038         system_jpeg, target, in_tree_jpeg_arm, in_tree_jpeg_mips64, jpeg_mips64_mmi
2039     ):
2040         if system_jpeg:
2041             return
2043         if target.cpu in ("arm", "aarch64"):
2044             return in_tree_jpeg_arm
2045         elif target.kernel == "Darwin":
2046             if target.cpu == "x86":
2047                 return ("-DPIC", "-DMACHO")
2048             elif target.cpu == "x86_64":
2049                 return ("-D__x86_64__", "-DPIC", "-DMACHO")
2050         elif target.kernel == "WINNT":
2051             if target.cpu == "x86":
2052                 return ("-DPIC", "-DWIN32")
2053             elif target.cpu == "x86_64":
2054                 return ("-D__x86_64__", "-DPIC", "-DWIN64", "-DMSVC")
2055         elif target.cpu == "mips32":
2056             return ("-mdspr2",)
2057         elif target.cpu == "mips64" and jpeg_mips64_mmi:
2058             return in_tree_jpeg_mips64
2059         elif target.cpu == "x86":
2060             return ("-DPIC", "-DELF")
2061         elif target.cpu == "x86_64":
2062             return ("-D__x86_64__", "-DPIC", "-DELF")
2064     @depends(target, when=depends("--with-system-jpeg")(lambda x: not x))
2065     def jpeg_nasm(target):
2066         if target.cpu in ("x86", "x86_64"):
2067             # libjpeg-turbo 2.0.6 requires nasm 2.10.
2068             return namespace(version="2.10", what="JPEG")
2070     # Compiler checks from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L258
2071     jpeg_arm_neon_vld1_s16_x3 = c_compiler.try_compile(
2072         includes=["arm_neon.h"],
2073         body="int16_t input[12] = {}; int16x4x3_t output = vld1_s16_x3(input);",
2074         check_msg="for vld1_s16_x3 in arm_neon.h",
2075         flags=in_tree_jpeg_arm,
2076         when=in_tree_jpeg_arm,
2077     )
2079     jpeg_arm_neon_vld1_u16_x2 = c_compiler.try_compile(
2080         includes=["arm_neon.h"],
2081         body="uint16_t input[8] = {}; uint16x4x2_t output = vld1_u16_x2(input);",
2082         check_msg="for vld1_u16_x2 in arm_neon.h",
2083         flags=in_tree_jpeg_arm,
2084         when=in_tree_jpeg_arm,
2085     )
2087     jpeg_arm_neon_vld1q_u8_x4 = c_compiler.try_compile(
2088         includes=["arm_neon.h"],
2089         body="uint8_t input[64] = {}; uint8x16x4_t output = vld1q_u8_x4(input);",
2090         check_msg="for vld1q_u8_x4 in arm_neon.h",
2091         flags=in_tree_jpeg_arm,
2092         when=in_tree_jpeg_arm,
2093     )
2095     set_config("LIBJPEG_TURBO_USE_NASM", True, when=jpeg_nasm)
2096     set_config("LIBJPEG_TURBO_SIMD_FLAGS", in_tree_jpeg)
2097     set_config("LIBJPEG_TURBO_HAVE_VLD1_S16_X3", jpeg_arm_neon_vld1_s16_x3)
2098     set_config("LIBJPEG_TURBO_HAVE_VLD1_U16_X2", jpeg_arm_neon_vld1_u16_x2)
2099     set_config("LIBJPEG_TURBO_HAVE_VLD1Q_U8_X4", jpeg_arm_neon_vld1q_u8_x4)
2100     set_config(
2101         "LIBJPEG_TURBO_NEON_INTRINSICS",
2102         jpeg_arm_neon_vld1_s16_x3
2103         & jpeg_arm_neon_vld1_u16_x2
2104         & jpeg_arm_neon_vld1q_u8_x4,
2105     )
2108 # PNG
2109 # ===
2110 with only_when(compile_environment):
2111     system_lib_option(
2112         "--with-system-png",
2113         nargs="?",
2114         help="Use system libpng",
2115     )
2117     @depends("--with-system-png")
2118     def deprecated_system_png_path(value):
2119         if len(value) == 1:
2120             die(
2121                 "--with-system-png=PATH is not supported anymore. Please use "
2122                 "--with-system-png and set any necessary pkg-config environment variable."
2123             )
2125     png = pkg_check_modules("MOZ_PNG", "libpng >= 1.6.35", when="--with-system-png")
2127     check_symbol(
2128         "png_get_acTL",
2129         flags=png.libs,
2130         onerror=lambda: die(
2131             "--with-system-png won't work because the system's libpng doesn't have APNG support"
2132         ),
2133         when="--with-system-png",
2134     )
2136     set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
2139 # FFmpeg's ffvpx configuration
2140 # ==============================================================
2141 with only_when(compile_environment):
2143     @depends(target)
2144     def libav_fft(target):
2145         return target.kernel == "WINNT" or target.cpu == "x86_64"
2147     set_config("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2148     set_define("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2151 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
2152 with only_when(compile_environment | artifact_builds):
2154     @depends(target)
2155     def ffvpx(target):
2156         enable = use_nasm = True
2157         flac_only = False
2158         flags = []
2160         if target.kernel == "WINNT":
2161             if target.cpu == "x86":
2162                 # 32-bit windows need to prefix symbols with an underscore.
2163                 flags = ["-DPIC", "-DWIN32", "-DPREFIX", "-Pconfig_win32.asm"]
2164             elif target.cpu == "x86_64":
2165                 flags = [
2166                     "-D__x86_64__",
2167                     "-DPIC",
2168                     "-DWIN64",
2169                     "-DMSVC",
2170                     "-Pconfig_win64.asm",
2171                 ]
2172             elif target.cpu == "aarch64":
2173                 flags = ["-DPIC", "-DWIN64"]
2174                 use_nasm = False
2175         elif target.kernel == "Darwin":
2176             if target.cpu == "x86_64":
2177                 # 32/64-bit macosx asemblers need to prefix symbols with an
2178                 # underscore.
2179                 flags = [
2180                     "-D__x86_64__",
2181                     "-DPIC",
2182                     "-DMACHO",
2183                     "-DPREFIX",
2184                     "-Pconfig_darwin64.asm",
2185                 ]
2186             else:
2187                 flac_only = True
2188         elif target.cpu == "x86_64":
2189             flags = ["-D__x86_64__", "-DPIC", "-DELF", "-Pconfig_unix64.asm"]
2190         elif target.cpu in ("x86", "arm", "aarch64"):
2191             flac_only = True
2192         else:
2193             enable = False
2195         if flac_only or not enable:
2196             use_nasm = False
2198         if use_nasm:
2199             # default disabled components
2200             flags.append("-Pdefaults_disabled.asm")
2202         return namespace(
2203             enable=enable,
2204             use_nasm=use_nasm,
2205             flac_only=flac_only,
2206             flags=flags,
2207         )
2209     @depends(when=ffvpx.use_nasm)
2210     def ffvpx_nasm():
2211         # nasm 2.10 for AVX-2 support.
2212         return namespace(version="2.10", what="FFVPX")
2214     # ffvpx_nasm can't indirectly depend on vpx_as_flags, because it depends
2215     # on a compiler test, so we have to do a little bit of dance here.
2216     @depends(ffvpx, vpx_as_flags, target)
2217     def ffvpx(ffvpx, vpx_as_flags, target):
2218         if ffvpx and vpx_as_flags and target.cpu in ("arm", "aarch64"):
2219             ffvpx.flags.extend(vpx_as_flags)
2220         return ffvpx
2222     set_config("MOZ_FFVPX", True, when=ffvpx.enable)
2223     set_define("MOZ_FFVPX", True, when=ffvpx.enable)
2224     set_config("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2225     set_define("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2226     set_config("FFVPX_ASFLAGS", ffvpx.flags)
2227     set_config("FFVPX_USE_NASM", True, when=ffvpx.use_nasm)
2230 # nasm detection
2231 # ==============================================================
2232 @depends(dav1d_nasm, vpx_nasm, jpeg_nasm, ffvpx_nasm, when=compile_environment)
2233 def need_nasm(*requirements):
2234     requires = {
2235         x.what: x.version if hasattr(x, "version") else True for x in requirements if x
2236     }
2237     if requires:
2238         items = sorted(requires.keys())
2239         if len(items) > 1:
2240             what = " and ".join((", ".join(items[:-1]), items[-1]))
2241         else:
2242             what = items[0]
2243         versioned = {k: v for (k, v) in requires.items() if v is not True}
2244         return namespace(what=what, versioned=versioned)
2247 nasm = check_prog(
2248     "NASM",
2249     ["nasm"],
2250     allow_missing=True,
2251     bootstrap="nasm",
2252     when=need_nasm,
2256 @depends(nasm, need_nasm.what)
2257 def check_nasm(nasm, what):
2258     if not nasm and what:
2259         die("Nasm is required to build with %s, but it was not found." % what)
2260     return nasm
2263 @depends_if(check_nasm)
2264 @checking("nasm version")
2265 def nasm_version(nasm):
2266     version = (
2267         check_cmd_output(nasm, "-v", onerror=lambda: die("Failed to get nasm version."))
2268         .splitlines()[0]
2269         .split()[2]
2270     )
2271     return Version(version)
2274 @depends(nasm_version, need_nasm.versioned, when=need_nasm.versioned)
2275 def check_nasm_version(nasm_version, versioned):
2276     by_version = sorted(versioned.items(), key=lambda x: x[1])
2277     what, version = by_version[-1]
2278     if nasm_version < version:
2279         die(
2280             "Nasm version %s or greater is required to build with %s." % (version, what)
2281         )
2282     return nasm_version
2285 @depends(target, when=check_nasm_version)
2286 def nasm_asflags(target):
2287     asflags = {
2288         ("OSX", "x86"): ["-f", "macho32"],
2289         ("OSX", "x86_64"): ["-f", "macho64"],
2290         ("WINNT", "x86"): ["-f", "win32"],
2291         ("WINNT", "x86_64"): ["-f", "win64"],
2292     }.get((target.os, target.cpu), None)
2293     if asflags is None:
2294         # We're assuming every x86 platform we support that's
2295         # not Windows or Mac is ELF.
2296         if target.cpu == "x86":
2297             asflags = ["-f", "elf32"]
2298         elif target.cpu == "x86_64":
2299             asflags = ["-f", "elf64"]
2300     return asflags
2303 set_config("NASM_ASFLAGS", nasm_asflags)
2306 # ANGLE OpenGL->D3D translator for WebGL
2307 # ==============================================================
2309 with only_when(compile_environment & target_is_windows):
2311     def d3d_compiler_dll_result(value):
2312         if not value.path:
2313             return "provided by the OS"
2314         return value.path
2316     @depends(target, valid_windows_sdk_dir, fxc)
2317     @checking("for D3D compiler DLL", d3d_compiler_dll_result)
2318     @imports("os.path")
2319     def d3d_compiler_dll(target, windows_sdk_dir, fxc):
2320         suffix = {
2321             "x86_64": "x64",
2322         }.get(target.cpu, target.cpu)
2324         name = "d3dcompiler_47.dll"
2326         if target.cpu == "aarch64":
2327             # AArch64 Windows comes with d3dcompiler_47.dll installed
2328             return namespace(name=name, path=None)
2330         if windows_sdk_dir:
2331             path = os.path.join(windows_sdk_dir.path, "Redist", "D3D", suffix, name)
2332             error_extra = "in Windows SDK at {}".format(windows_sdk_dir.path)
2333         else:
2334             path = os.path.join(os.path.dirname(fxc), name)
2335             error_extra = "alongside FXC at {}".format(fxc)
2337         if os.path.exists(path):
2338             return namespace(name=name, path=path)
2339         die("Could not find {} {}".format(name, error_extra))
2341     set_config("MOZ_ANGLE_RENDERER", True)
2342     set_config(
2343         "MOZ_D3DCOMPILER_VISTA_DLL", d3d_compiler_dll.name, when=d3d_compiler_dll.path
2344     )
2345     set_config("MOZ_D3DCOMPILER_VISTA_DLL_PATH", d3d_compiler_dll.path)
2347 # Remoting protocol support
2348 # ==============================================================
2351 @depends(toolkit)
2352 def has_remote(toolkit):
2353     if toolkit in ("gtk", "windows", "cocoa"):
2354         return True
2357 set_config("MOZ_HAS_REMOTE", has_remote)
2358 set_define("MOZ_HAS_REMOTE", has_remote)
2360 # RLBox Library Sandboxing wasm support
2361 # ==============================================================
2364 def wasm_sandboxing_libraries():
2365     return (
2366         "graphite",
2367         "ogg",
2368         "hunspell",
2369         "expat",
2370         "woff2",
2371     )
2374 @depends(dependable(wasm_sandboxing_libraries))
2375 def default_wasm_sandboxing_libraries(libraries):
2376     non_default_libs = set()
2378     return tuple(l for l in libraries if l not in non_default_libs)
2381 option(
2382     "--with-wasm-sandboxed-libraries",
2383     env="WASM_SANDBOXED_LIBRARIES",
2384     help="{Enable wasm sandboxing for the selected libraries|Disable wasm sandboxing}",
2385     nargs="+",
2386     choices=dependable(wasm_sandboxing_libraries),
2387     default=default_wasm_sandboxing_libraries,
2391 @depends("--with-wasm-sandboxed-libraries")
2392 def requires_wasm_sandboxing(libraries):
2393     if libraries:
2394         return True
2397 set_config("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2398 set_define("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2400 with only_when(requires_wasm_sandboxing & compile_environment):
2401     option(
2402         "--with-wasi-sysroot",
2403         env="WASI_SYSROOT",
2404         nargs=1,
2405         help="Path to wasi sysroot for wasm sandboxing",
2406     )
2408     @depends("--with-wasi-sysroot", requires_wasm_sandboxing)
2409     def bootstrap_wasi_sysroot(wasi_sysroot, requires_wasm_sandboxing):
2410         return requires_wasm_sandboxing and not wasi_sysroot
2412     @depends(
2413         "--with-wasi-sysroot",
2414         bootstrap_path("sysroot-wasm32-wasi", when=bootstrap_wasi_sysroot),
2415         "--with-wasm-sandboxed-libraries",
2416     )
2417     @imports("os")
2418     def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot, sandboxed_libs):
2419         if not wasi_sysroot:
2420             if not bootstrapped_sysroot:
2421                 suggest_disable = ""
2422                 if sandboxed_libs.origin == "default":
2423                     suggest_disable = (
2424                         " Or build with --without-wasm-sandboxed-libraries."
2425                     )
2426                 die(
2427                     "Cannot find a wasi sysroot. Please give its location with "
2428                     "--with-wasi-sysroot." + suggest_disable
2429                 )
2430             return bootstrapped_sysroot
2432         wasi_sysroot = wasi_sysroot[0]
2433         if not os.path.isdir(wasi_sysroot):
2434             die("Argument to --with-wasi-sysroot must be a directory")
2435         if not os.path.isabs(wasi_sysroot):
2436             die("Argument to --with-wasi-sysroot must be an absolute path")
2438         return wasi_sysroot
2440     set_config("WASI_SYSROOT", wasi_sysroot)
2442     def wasm_compiler_with_flags(compiler, sysroot):
2443         if not sysroot:
2444             return
2445         elif compiler:
2446             return (
2447                 compiler.wrapper
2448                 + [compiler.compiler]
2449                 + compiler.flags
2450                 + ["--sysroot=%s" % sysroot]
2451             )
2453     wasm_cc = compiler("C", wasm, other_compiler=c_compiler)
2455     @depends(wasm_cc, wasi_sysroot)
2456     def wasm_cc_with_flags(wasm_cc, wasi_sysroot):
2457         return wasm_compiler_with_flags(wasm_cc, wasi_sysroot)
2459     set_config("WASM_CC", wasm_cc_with_flags)
2461     wasm_cxx = compiler(
2462         "C++",
2463         wasm,
2464         c_compiler=wasm_cc,
2465         other_compiler=cxx_compiler,
2466         other_c_compiler=c_compiler,
2467     )
2469     @depends(wasm_cxx, wasi_sysroot)
2470     def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot):
2471         return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot)
2473     set_config("WASM_CXX", wasm_cxx_with_flags)
2475     wasm_compile_flags = dependable(
2476         ["-fno-exceptions", "-fno-strict-aliasing", "-Qunused-arguments"]
2477     )
2478     option(env="WASM_CFLAGS", nargs=1, help="Options to pass to WASM_CC")
2480     @depends("WASM_CFLAGS", wasm_compile_flags)
2481     def wasm_cflags(value, wasm_compile_flags):
2482         if value:
2483             return wasm_compile_flags + value
2484         else:
2485             return wasm_compile_flags
2487     set_config("WASM_CFLAGS", wasm_cflags)
2489     option(env="WASM_CXXFLAGS", nargs=1, help="Options to pass to WASM_CXX")
2491     @depends("WASM_CXXFLAGS", wasm_compile_flags)
2492     def wasm_cxxflags(value, wasm_compile_flags):
2493         if value:
2494             return wasm_compile_flags + value
2495         else:
2496             return wasm_compile_flags
2498     set_config("WASM_CXXFLAGS", wasm_cxxflags)
2501 @depends("--with-wasm-sandboxed-libraries")
2502 def wasm_sandboxing(libraries):
2503     if not libraries:
2504         return
2506     return namespace(**{name: True for name in libraries})
2509 @template
2510 def wasm_sandboxing_config_defines():
2511     for lib in wasm_sandboxing_libraries():
2512         set_config(
2513             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2514         )
2515         set_define(
2516             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2517         )
2520 wasm_sandboxing_config_defines()
2523 # new XULStore implementation
2524 # ==============================================================
2527 @depends(milestone)
2528 def new_xulstore(milestone):
2529     if milestone.is_nightly:
2530         return True
2533 set_config("MOZ_NEW_XULSTORE", True, when=new_xulstore)
2534 set_define("MOZ_NEW_XULSTORE", True, when=new_xulstore)
2537 # new Notification Store implementation
2538 # ==============================================================
2541 @depends(milestone)
2542 def new_notification_store(milestone):
2543     if milestone.is_nightly:
2544         return True
2547 set_config("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2548 set_define("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2551 # Glean SDK Integration Crate
2552 # ==============================================================
2555 @depends(target)
2556 def glean_android(target):
2557     return target.os == "Android"
2560 set_config("MOZ_GLEAN_ANDROID", True, when=glean_android)
2561 set_define("MOZ_GLEAN_ANDROID", True, when=glean_android)
2564 # dump_syms
2565 # ==============================================================
2567 check_prog(
2568     "DUMP_SYMS",
2569     ["dump_syms"],
2570     allow_missing=True,
2571     bootstrap="dump_syms",
2572     when=compile_environment,
2576 check_prog(
2577     "PDBSTR",
2578     ["pdbstr.exe"],
2579     allow_missing=True,
2580     bootstrap="pdbstr",
2581     when=compile_environment & target_is_windows,
2585 @depends("MOZ_AUTOMATION", c_compiler)
2586 def allow_missing_winchecksec(automation, c_compiler):
2587     if not automation:
2588         return True
2589     if c_compiler and c_compiler.type != "clang-cl":
2590         return True
2593 check_prog(
2594     "WINCHECKSEC",
2595     ["winchecksec.exe", "winchecksec"],
2596     bootstrap="winchecksec",
2597     allow_missing=allow_missing_winchecksec,
2598     when=compile_environment & target_is_windows,
2601 # Fork server
2602 @depends(target, build_project)
2603 def forkserver_default(target, build_project):
2604     return build_project == "browser" and (
2605         (target.os == "GNU" and target.kernel == "Linux")
2606         or target.os == "FreeBSD"
2607         or target.os == "OpenBSD"
2608     )
2611 option(
2612     "--enable-forkserver",
2613     default=forkserver_default,
2614     env="MOZ_ENABLE_FORKSERVER",
2615     help="{Enable|Disable} fork server",
2619 @depends("--enable-forkserver", target)
2620 def forkserver_flag(value, target):
2621     if (
2622         target.os == "Android"
2623         or (target.os == "GNU" and target.kernel == "Linux")
2624         or target.os == "FreeBSD"
2625         or target.os == "OpenBSD"
2626     ):
2627         return bool(value)
2628     pass
2631 set_config("MOZ_ENABLE_FORKSERVER", forkserver_flag)
2632 set_define("MOZ_ENABLE_FORKSERVER", forkserver_flag, forkserver_flag)
2634 # Crash Reporter
2635 # ==============================================================
2637 with only_when(compile_environment & target_is_linux):
2638     # Check if we need to use the breakpad_getcontext fallback.
2639     getcontext = check_symbol("getcontext")
2640     set_config("HAVE_GETCONTEXT", getcontext)
2641     set_define("HAVE_GETCONTEXT", getcontext)
2643 # NSS
2644 # ==============================================================
2645 include("../build/moz.configure/nss.configure")
2648 # Enable or disable running in background task mode: headless for
2649 # periodic, short-lived, maintenance tasks.
2650 # ==============================================================================
2653 option(
2654     "--disable-backgroundtasks",
2655     help="Disable running in background task mode",
2659 set_config(
2660     "MOZ_BACKGROUNDTASKS", depends_if("--enable-backgroundtasks")(lambda _: True)
2664 # Update-related programs: updater, maintenance service, update agent,
2665 # default browser agent.
2666 # ==============================================================
2667 include("../build/moz.configure/update-programs.configure")
2670 # Mobile optimizations
2671 # ==============================================================
2672 option(
2673     "--enable-mobile-optimize",
2674     default=target_is_android,
2675     help="{Enable|Disable} mobile optimizations",
2678 set_define("MOZ_GFX_OPTIMIZE_MOBILE", True, when="--enable-mobile-optimize")
2679 # We ignore "paint will resample" on mobile for performance.
2680 # We may want to revisit this later.
2681 set_define("MOZ_IGNORE_PAINT_WILL_RESAMPLE", True, when="--enable-mobile-optimize")
2683 # Pref extensions
2684 # ==============================================================
2685 option("--disable-pref-extensions", help="Disable pref extensions such as autoconfig")
2686 set_config("MOZ_PREF_EXTENSIONS", True, when="--enable-pref-extensions")
2688 # Offer a way to disable the startup cache
2689 # ==============================================================
2690 option("--disable-startupcache", help="Disable startup cache")
2693 @depends("--enable-startupcache")
2694 def enable_startupcache(value):
2695     if value:
2696         return True
2699 set_define(
2700     "MOZ_DISABLE_STARTUPCACHE", True, when=depends(enable_startupcache)(lambda x: not x)
2704 # Branding
2705 # ==============================================================
2706 option(
2707     env="MOZ_APP_REMOTINGNAME",
2708     nargs=1,
2709     help="Used for the internal program name, which affects profile name "
2710     "and remoting. If not set, defaults to MOZ_APP_NAME if the update channel "
2711     "is release, and MOZ_APP_NAME-MOZ_UPDATE_CHANNEL otherwise.",
2715 @depends("MOZ_APP_REMOTINGNAME", moz_app_name, update_channel)
2716 def moz_app_remotingname(value, moz_app_name, update_channel):
2717     if value:
2718         return value[0]
2719     if update_channel == "release":
2720         return moz_app_name
2721     return moz_app_name + "-" + update_channel
2724 set_config("MOZ_APP_REMOTINGNAME", moz_app_remotingname)
2726 option(
2727     env="ANDROID_PACKAGE_NAME",
2728     nargs=1,
2729     help="Name of the Android package (default org.mozilla.$MOZ_APP_NAME)",
2733 @depends("ANDROID_PACKAGE_NAME", moz_app_name)
2734 def android_package_name(value, moz_app_name):
2735     if value:
2736         return value[0]
2737     if moz_app_name == "fennec":
2738         return "org.mozilla.fennec_aurora"
2739     return "org.mozilla.%s" % moz_app_name
2742 set_config("ANDROID_PACKAGE_NAME", android_package_name)
2745 # Miscellaneous options
2746 # ==============================================================
2747 option(env="MOZ_WINCONSOLE", nargs="?", help="Whether we can create a console window.")
2748 set_define("MOZ_WINCONSOLE", True, when=depends("MOZ_WINCONSOLE")(lambda x: x))
2751 # Alternative Crashreporter setting
2752 option(
2753     "--with-crashreporter-url",
2754     env="MOZ_CRASHREPORTER_URL",
2755     default="https://crash-reports.mozilla.com/",
2756     nargs=1,
2757     help="Set an alternative crashreporter url",
2760 set_config(
2761     "MOZ_CRASHREPORTER_URL",
2762     depends("--with-crashreporter-url")(lambda x: x[0].rstrip("/")),
2766 # Crash reporter options
2767 # ==============================================================
2768 @depends(target)
2769 def oxidized_breakpad(target):
2770     if target.kernel == "Linux" and target.os != "Android":
2771         return target.cpu in ("x86", "x86_64")
2772     return False
2775 set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2776 set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2779 # Wine
2780 # ==============================================================
2781 @depends(target, host)
2782 def want_wine(target, host):
2783     return target.kernel == "WINNT" and host.kernel != "WINNT"
2786 wine = check_prog(
2787     "WINE",
2788     ["wine64", "wine"],
2789     when=want_wine,
2790     bootstrap="wine/bin",
2793 # DOM Streams
2794 # ==============================================================
2795 # Set this to true so the JS engine knows we're doing a browser build.
2796 set_config("MOZ_DOM_STREAMS", True)
2797 set_define("MOZ_DOM_STREAMS", True)
2799 # libevent
2800 # ==============================================================
2801 with only_when(compile_environment):
2802     system_lib_option(
2803         "--with-system-libevent",
2804         nargs="?",
2805         help="Use system libevent",
2806     )
2808     @depends("--with-system-libevent")
2809     def deprecated_system_libevent_path(value):
2810         if len(value) == 1:
2811             die(
2812                 "--with-system-libevent=PATH is not supported anymore. Please use "
2813                 "--with-system-libevent and set any necessary pkg-config environment variable."
2814             )
2816     pkg_check_modules("MOZ_LIBEVENT", "libevent", when="--with-system-libevent")
2818     set_config("MOZ_SYSTEM_LIBEVENT", True, when="--with-system-libevent")
2821 # Crash reporting
2822 # ==============================================================
2823 @depends(target, developer_options, artifact_builds)
2824 def crashreporter_default(target, developer_options, artifacts):
2825     if target.kernel in ("WINNT", "Darwin"):
2826         return True
2827     if target.kernel == "Linux" and target.cpu in ("x86", "x86_64", "arm", "aarch64"):
2828         # The crash reporter prevents crash stacktraces to be logged in the
2829         # logs on Android, so we leave it out by default in developer builds.
2830         return target.os != "Android" or not developer_options or artifacts
2833 option(
2834     "--enable-crashreporter",
2835     default=crashreporter_default,
2836     help="{Enable|Disable} crash reporting",
2840 set_config("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2841 set_define("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2842 add_old_configure_assignment("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2844 with only_when(compile_environment):
2845     with only_when("--enable-crashreporter"):
2846         pkg_check_modules(
2847             "MOZ_GTHREAD",
2848             "gthread-2.0",
2849             when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2850         )
2852         set_config(
2853             "MOZ_CRASHREPORTER_INJECTOR",
2854             True,
2855             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2856         )
2857         set_define(
2858             "MOZ_CRASHREPORTER_INJECTOR",
2859             True,
2860             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2861         )
2864 # Gtk+
2865 # ==============================================================
2866 with only_when(toolkit_gtk):
2867     pkg_check_modules(
2868         "MOZ_GTK3",
2869         "gtk+-3.0 >= 3.14.0 gtk+-unix-print-3.0 glib-2.0 gobject-2.0 gio-unix-2.0",
2870     )
2872     set_define("GDK_VERSION_MIN_REQUIRED", "GDK_VERSION_3_14")
2873     set_define("GDK_VERSION_MAX_ALLOWED", "GDK_VERSION_3_14")
2875     pkg_check_modules("GLIB", "glib-2.0 >= 2.42 gobject-2.0")
2877     set_define("GLIB_VERSION_MIN_REQUIRED", "GLIB_VERSION_2_42")
2878     set_define("GLIB_VERSION_MAX_ALLOWED", "GLIB_VERSION_2_42")
2880     set_define("MOZ_ACCESSIBILITY_ATK", True, when=accessibility)
2882 # DBus
2883 # ==============================================================
2884 with only_when(toolkit_gtk):
2885     option("--disable-dbus", help="Disable dbus support")
2887     with only_when("--enable-dbus"):
2888         pkg_check_modules("MOZ_DBUS", "dbus-1 >= 0.60")
2889         pkg_check_modules("MOZ_DBUS_GLIB", "dbus-glib-1 >= 0.60")
2891         set_config("MOZ_ENABLE_DBUS", True)
2892         set_define("MOZ_ENABLE_DBUS", True)
2895 # Necko's wifi scanner
2896 # ==============================================================
2897 @depends(target)
2898 def necko_wifi_when(target):
2899     return target.os in ("WINNT", "OSX", "DragonFly", "FreeBSD") or (
2900         target.kernel == "Linux" and target.os == "GNU"
2901     )
2904 option("--disable-necko-wifi", help="Disable necko wifi scanner", when=necko_wifi_when)
2906 set_config("NECKO_WIFI", True, when="--enable-necko-wifi")
2907 set_define("NECKO_WIFI", True, when="--enable-necko-wifi")
2910 @depends(
2911     depends("--enable-necko-wifi", when=necko_wifi_when)(lambda x: x),
2912     depends("--enable-dbus", when=toolkit_gtk)(lambda x: x),
2913     when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2915 def necko_wifi_dbus(necko_wifi, dbus):
2916     if necko_wifi and not dbus:
2917         die(
2918             "Necko WiFi scanning needs DBus on your platform, remove --disable-dbus"
2919             " or use --disable-necko-wifi"
2920         )
2921     return necko_wifi and dbus
2924 set_config("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
2927 # Frontend JS debug mode
2928 # ==============================================================
2929 option("--enable-debug-js-modules", help="Enable debug mode for frontend JS libraries")
2931 set_config("DEBUG_JS_MODULES", True, when="--enable-debug-js-modules")
2934 # moz_dump_painting
2935 # ==============================================================
2936 option("--enable-dump-painting", help="Enable paint debugging")
2938 set_define(
2939     "MOZ_DUMP_PAINTING",
2940     True,
2941     when=depends("--enable-dump-painting", "--enable-debug")(
2942         lambda painting, debug: painting or debug
2943     ),
2945 set_define("MOZ_LAYERS_HAVE_LOG", True, when="--enable-dump-painting")
2948 # libproxy support
2949 # ==============================================================
2950 with only_when(toolkit_gtk):
2951     system_lib_option("--enable-libproxy", help="Enable libproxy support")
2953     with only_when("--enable-libproxy"):
2954         pkg_check_modules("MOZ_LIBPROXY", "libproxy-1.0")
2956         set_config("MOZ_ENABLE_LIBPROXY", True)
2957         set_define("MOZ_ENABLE_LIBPROXY", True)
2960 # Enable runtime logging
2961 # ==============================================================
2962 set_define("MOZ_LOGGING", True)
2963 set_define("FORCE_PR_LOG", True)
2965 # This will enable logging of addref, release, ctor, dtor.
2966 # ==============================================================
2967 option(
2968     "--enable-logrefcnt",
2969     default=moz_debug,
2970     help="{Enable|Disable} logging of refcounts",
2973 set_define("NS_BUILD_REFCNT_LOGGING", True, when="--enable-logrefcnt")
2976 # NegotiateAuth
2977 # ==============================================================
2978 option("--disable-negotiateauth", help="Disable GSS-API negotiation")
2980 set_config("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
2981 set_define("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
2984 # Parental control
2985 # ==============================================================
2986 option("--disable-parental-controls", help="Do not build parental controls")
2988 set_config(
2989     "MOZ_DISABLE_PARENTAL_CONTROLS",
2990     True,
2991     when=depends("--enable-parental-controls")(lambda x: not x),
2993 set_define(
2994     "MOZ_DISABLE_PARENTAL_CONTROLS",
2995     True,
2996     when=depends("--enable-parental-controls")(lambda x: not x),
3000 # Sandboxing support
3001 # ==============================================================
3002 @depends(target, tsan, asan)
3003 def sandbox_default(target, tsan, asan):
3004     # Only enable the sandbox by default on Linux, OpenBSD, macOS, and Windows
3005     if target.kernel == "Linux" and target.os == "GNU":
3006         # Bug 1182565: TSan conflicts with sandboxing on Linux.
3007         # Bug 1287971: LSan also conflicts with sandboxing on Linux.
3008         if tsan or asan:
3009             return False
3010         # Linux sandbox is only available on x86{,_64} and arm{,64}.
3011         return target.cpu in ("x86", "x86_64", "arm", "aarch64")
3012     return target.kernel in ("WINNT", "Darwin", "OpenBSD")
3015 option(
3016     "--enable-sandbox",
3017     default=sandbox_default,
3018     help="{Enable|Disable} sandboxing support",
3021 set_config("MOZ_SANDBOX", True, when="--enable-sandbox")
3022 set_define("MOZ_SANDBOX", True, when="--enable-sandbox")
3025 # Searching of system directories for extensions.
3026 # ==============================================================
3027 # Note: this switch is meant to be used for test builds whose behavior should
3028 # not depend on what happens to be installed on the local machine.
3029 option(
3030     "--disable-system-extension-dirs",
3031     help="Disable searching system- and account-global directories for extensions"
3032     " of any kind; use only profile-specific extension directories",
3035 set_define("ENABLE_SYSTEM_EXTENSION_DIRS", True, when="--enable-system-extension-dirs")
3038 # Pixman
3039 # ==============================================================
3040 with only_when(compile_environment):
3041     system_lib_option(
3042         "--enable-system-pixman", help="Use system pixman (located with pkgconfig)"
3043     )
3045     @depends("--enable-system-pixman")
3046     def in_tree_pixman(pixman):
3047         return not pixman
3049     set_config("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3050     set_define("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3052     pkg_check_modules("MOZ_PIXMAN", "pixman-1 >= 0.36.0", when="--enable-system-pixman")
3053     # Set MOZ_PIXMAN_CFLAGS to an explicit empty value when --enable-system-pixman is *not* used,
3054     # for layout/style/extra-bindgen-flags
3055     set_config("MOZ_PIXMAN_CFLAGS", [], when=in_tree_pixman)
3058 # Universalchardet
3059 # ==============================================================
3060 with only_when(compile_environment):
3061     option("--disable-universalchardet", help="Disable universal encoding detection")
3063     set_config("MOZ_UNIVERSALCHARDET", True, when="--enable-universalchardet")
3066 # Disable zipwriter
3067 # ==============================================================
3068 with only_when(compile_environment):
3069     option("--disable-zipwriter", help="Disable zipwriter component")
3071     set_config("MOZ_ZIPWRITER", True, when="--enable-zipwriter")
3074 # Location of the mozilla user directory
3075 # ==============================================================
3076 with only_when(compile_environment):
3078     @depends(target)
3079     def default_user_appdir(target):
3080         if target.kernel in ("WINNT", "Darwin"):
3081             return "Mozilla"
3082         return ".mozilla"
3084     option(
3085         "--with-user-appdir",
3086         nargs=1,
3087         default=default_user_appdir,
3088         help="Set user-specific appdir",
3089     )
3091     @depends("--with-user-appdir")
3092     def user_appdir(appdir):
3093         if not appdir:
3094             die("--without-user-appdir is not a valid option.")
3095         if "/" in appdir[0]:
3096             die("--with-user-appdir must be a single relative path.")
3097         return '"{}"'.format(appdir[0])
3099     set_define("MOZ_USER_DIR", user_appdir)
3102 # Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
3103 # ==============================================================
3104 with only_when(compile_environment):
3105     have_sin_len = c_compiler.try_compile(
3106         includes=["netinet/in.h"],
3107         body="struct sockaddr_in x; void *foo = (void*) &x.sin_len;",
3108         check_msg="for sin_len in struct sockaddr_in",
3109     )
3110     have_sin6_len = c_compiler.try_compile(
3111         includes=["netinet/in.h"],
3112         body="struct sockaddr_in6 x; void *foo = (void*) &x.sin6_len;",
3113         check_msg="for sin_len6 in struct sockaddr_in6",
3114     )
3115     set_define("HAVE_SIN_LEN", have_sin_len)
3116     set_define("HAVE_SIN6_LEN", have_sin6_len)
3117     # HAVE_CONN_LEN must be the same as HAVE_SIN_LEN and HAVE_SIN6_LEN
3118     set_define("HAVE_SCONN_LEN", have_sin_len & have_sin6_len)
3119     set_define(
3120         "HAVE_SA_LEN",
3121         c_compiler.try_compile(
3122             includes=["netinet/in.h"],
3123             body="struct sockaddr x; void *foo = (void*) &x.sa_len;",
3124             check_msg="for sa_len in struct sockaddr",
3125         ),
3126     )
3129 # Check for pthread_cond_timedwait_monotonic_np
3130 # ==============================================================
3131 with only_when(compile_environment):
3132     set_define(
3133         "HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC",
3134         c_compiler.try_compile(
3135             includes=["pthread.h"],
3136             body="pthread_cond_timedwait_monotonic_np(0, 0, 0);",
3137             # -Werror to catch any "implicit declaration" warning that means the function
3138             # is not supported.
3139             flags=["-Werror=implicit-function-declaration"],
3140             check_msg="for pthread_cond_timedwait_monotonic_np",
3141         ),
3142     )
3145 # Custom dynamic linker for Android
3146 # ==============================================================
3147 with only_when(target_is_linux & compile_environment):
3148     option(
3149         env="MOZ_LINKER",
3150         default=depends(target.os, when="--enable-jemalloc")(
3151             lambda os: os == "Android"
3152         ),
3153         help="{Enable|Disable} custom dynamic linker",
3154     )
3156     set_config("MOZ_LINKER", True, when="MOZ_LINKER")
3157     set_define("MOZ_LINKER", True, when="MOZ_LINKER")
3158     add_old_configure_assignment("MOZ_LINKER", True, when="MOZ_LINKER")
3160     moz_linker = depends(when="MOZ_LINKER")(lambda: True)
3163 # 32-bits ethtool_cmd.speed
3164 # ==============================================================
3165 with only_when(target_is_linux & compile_environment):
3166     set_config(
3167         "MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI",
3168         c_compiler.try_compile(
3169             includes=["linux/ethtool.h"],
3170             body="struct ethtool_cmd cmd; cmd.speed_hi = 0;",
3171             check_msg="for 32-bits ethtool_cmd.speed",
3172         ),
3173     )
3175 # Gamepad support
3176 # ==============================================================
3177 check_header(
3178     "linux/joystick.h",
3179     onerror=lambda: die(
3180         "Can't find header linux/joystick.h, needed for gamepad support."
3181         " Please install Linux kernel headers."
3182     ),
3183     when=target_is_linux & compile_environment,
3186 # Smart card support
3187 # ==============================================================
3188 @depends(build_project)
3189 def disable_smart_cards(build_project):
3190     return build_project == "mobile/android"
3193 set_config("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3194 set_define("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3196 # Checks for library functions
3197 # ==============================================================
3198 with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
3199     set_define("HAVE_STAT64", check_symbol("stat64"))
3200     set_define("HAVE_LSTAT64", check_symbol("lstat64"))
3201     set_define("HAVE_TRUNCATE64", check_symbol("truncate64"))
3202     set_define("HAVE_STATVFS64", check_symbol("statvfs64"))
3203     set_define("HAVE_STATVFS", check_symbol("statvfs"))
3204     set_define("HAVE_STATFS64", check_symbol("statfs64"))
3205     set_define("HAVE_STATFS", check_symbol("statfs"))
3206     set_define("HAVE_LUTIMES", check_symbol("lutimes"))
3207     set_define("HAVE_POSIX_FADVISE", check_symbol("posix_fadvise"))
3208     set_define("HAVE_POSIX_FALLOCATE", check_symbol("posix_fallocate"))
3210     set_define("HAVE_ARC4RANDOM", check_symbol("arc4random"))
3211     set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf"))
3212     set_define("HAVE_MALLINFO", check_symbol("mallinfo"))