Backed out changeset af2c13b9fdb7 (bug 1801244) per developer request.
[gecko.git] / toolkit / moz.configure
blobe51e97678cbf6a40de7080bd8c7d1dbf8fee30b5
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 (
176         target.kernel == "Linux" and target.os != "Android" and target.cpu != "riscv64"
177     )
180 @depends(target, midir_linux_support)
181 def midir_support(target, midir_linux_support):
182     if target.os in ("WINNT", "OSX") or midir_linux_support:
183         return True
186 set_config("MOZ_WEBMIDI_MIDIR_IMPL", midir_support)
188 # Enable various cubeb backends
189 # ==============================================================
190 @depends(target)
191 def audio_backends_default(target):
192     if target.os == "Android":
193         return (
194             "aaudio",
195             "opensl",
196         )
197     elif target.os in ("DragonFly", "FreeBSD", "SunOS"):
198         return ("oss",)
199     elif target.os == "OpenBSD":
200         return ("sndio",)
201     elif target.os == "OSX":
202         return ("audiounit",)
203     elif target.os == "WINNT":
204         return ("wasapi",)
205     else:
206         return ("pulseaudio",)
209 option(
210     "--enable-audio-backends",
211     nargs="+",
212     choices=(
213         "aaudio",
214         "alsa",
215         "audiounit",
216         "jack",
217         "opensl",
218         "oss",
219         "pulseaudio",
220         "sndio",
221         "wasapi",
222     ),
223     default=audio_backends_default,
224     help="{Enable|Disable} various cubeb backends",
228 @depends("--enable-audio-backends", target)
229 def imply_aaudio(values, target):
230     if any("aaudio" in value for value in values) and target.os != "Android":
231         die("Cannot enable AAudio on %s", target.os)
232     return any("aaudio" in value for value in values) or None
235 @depends("--enable-audio-backends", target)
236 def imply_alsa(values, target):
237     if (
238         any("alsa" in value for value in values)
239         and target.kernel != "Linux"
240         and target.os != "FreeBSD"
241     ):
242         die("Cannot enable ALSA on %s", target.os)
243     return any("alsa" in value for value in values) or None
246 @depends("--enable-audio-backends", target)
247 def imply_audiounit(values, target):
248     if (
249         any("audiounit" in value for value in values)
250         and target.os != "OSX"
251         and target.kernel != "Darwin"
252     ):
253         die("Cannot enable AudioUnit on %s", target.os)
254     return any("audiounit" in value for value in values) or None
257 @depends("--enable-audio-backends")
258 def imply_jack(values):
259     return any("jack" in value for value in values) or None
262 @depends("--enable-audio-backends", target)
263 def imply_opensl(values, target):
264     if any("opensl" in value for value in values) and target.os != "Android":
265         die("Cannot enable OpenSL on %s", target.os)
266     return any("opensl" in value for value in values) or None
269 @depends("--enable-audio-backends", target)
270 def imply_oss(values, target):
271     if any("oss" in value for value in values) and (
272         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
273     ):
274         die("Cannot enable OSS on %s", target.os)
275     return any("oss" in value for value in values) or None
278 @depends("--enable-audio-backends", target)
279 def imply_pulseaudio(values, target):
280     if any("pulseaudio" in value for value in values) and (
281         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
282     ):
283         die("Cannot enable PulseAudio on %s", target.os)
284     return any("pulseaudio" in value for value in values) or None
287 @depends("--enable-audio-backends", target)
288 def imply_sndio(values, target):
289     if any("sndio" in value for value in values) and (
290         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
291     ):
292         die("Cannot enable sndio on %s", target.os)
293     return any("sndio" in value for value in values) or None
296 @depends("--enable-audio-backends", target)
297 def imply_wasapi(values, target):
298     if any("wasapi" in value for value in values) and target.os != "WINNT":
299         die("Cannot enable WASAPI on %s", target.os)
300     return any("wasapi" in value for value in values) or None
303 set_config("MOZ_AAUDIO", imply_aaudio, when="--enable-audio-backends")
305 imply_option("--enable-alsa", imply_alsa, reason="--enable-audio-backends")
307 set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")
309 imply_option("--enable-jack", imply_jack, reason="--enable-audio-backends")
311 set_config("MOZ_OPENSL", imply_opensl, when="--enable-audio-backends")
313 set_config("MOZ_OSS", imply_oss, when="--enable-audio-backends")
315 imply_option("--enable-pulseaudio", imply_pulseaudio, reason="--enable-audio-backends")
317 imply_option("--enable-sndio", imply_sndio, reason="--enable-audio-backends")
319 set_config("MOZ_WASAPI", imply_wasapi, when="--enable-audio-backends")
321 # ALSA cubeb backend
322 # ==============================================================
323 option("--enable-alsa", env="MOZ_ALSA", help="Enable ALSA audio backend.")
326 @depends("--enable-alsa", midir_linux_support)
327 def enable_alsa_or_midir_linux_support(alsa_enabled, midir_linux_support):
328     return alsa_enabled or midir_linux_support
331 pkg_check_modules("MOZ_ALSA", "alsa", when=enable_alsa_or_midir_linux_support)
333 set_config("MOZ_ALSA", True, when="--enable-alsa")
335 # JACK cubeb backend
336 # ==============================================================
337 system_lib_option("--enable-jack", env="MOZ_JACK", help="Enable JACK audio backend.")
339 jack = pkg_check_modules("MOZ_JACK", "jack", when="--enable-jack")
341 set_config("MOZ_JACK", depends_if(jack)(lambda _: True))
343 # PulseAudio cubeb backend
344 # ==============================================================
345 option(
346     "--enable-pulseaudio",
347     env="MOZ_PULSEAUDIO",
348     help="{Enable|Disable} PulseAudio audio backend.",
351 pulseaudio = pkg_check_modules("MOZ_PULSEAUDIO", "libpulse", when="--enable-pulseaudio")
353 set_config("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
355 # sndio cubeb backend
356 # ==============================================================
357 system_lib_option("--enable-sndio", env="MOZ_SNDIO", help="Enable sndio audio backend.")
359 sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
361 set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
363 # Javascript engine
364 # ==============================================================
365 include("../js/moz.configure")
368 # NodeJS
369 # ==============================================================
370 include("../build/moz.configure/node.configure")
372 # JsonCpp
373 # ==============================================================
374 set_define("JSON_USE_EXCEPTION", 0)
376 # L10N
377 # ==============================================================
378 option("--with-l10n-base", nargs=1, env="L10NBASEDIR", help="Path to l10n repositories")
381 @depends("--with-l10n-base", "MOZ_AUTOMATION", build_environment)
382 @imports(_from="os.path", _import="isdir")
383 @imports(_from="os.path", _import="expanduser")
384 @imports(_from="os", _import="environ")
385 def l10n_base(value, automation, build_env):
386     if value:
387         path = value[0]
388         if not isdir(path):
389             die("Invalid value --with-l10n-base, %s doesn't exist", path)
390     elif automation:
391         path = os.path.join(build_env.topsrcdir, "../l10n-central")
392     else:
393         path = os.path.join(
394             environ.get(
395                 "MOZBUILD_STATE_PATH", expanduser(os.path.join("~", ".mozbuild"))
396             ),
397             "l10n-central",
398         )
399     return os.path.realpath(os.path.abspath(path))
402 set_config("L10NBASEDIR", l10n_base)
405 # Default toolkit
406 # ==============================================================
407 @depends(target)
408 def toolkit_choices(target):
409     if target.os == "WINNT":
410         return ("cairo-windows",)
411     elif target.os == "OSX":
412         return ("cairo-cocoa",)
413     elif target.os == "Android":
414         return ("cairo-android",)
415     else:
416         return (
417             "cairo-gtk3",
418             "cairo-gtk3-wayland",
419             "cairo-gtk3-wayland-only",
420             "cairo-gtk3-x11-wayland",
421         )
424 @depends(toolkit_choices)
425 def toolkit_default(choices):
426     return choices[0]
429 option(
430     "--enable-default-toolkit",
431     nargs=1,
432     choices=toolkit_choices,
433     default=toolkit_default,
434     help="Select default toolkit",
438 @depends("--enable-default-toolkit")
439 def full_toolkit(value):
440     if value:
441         return value[0]
444 @depends(full_toolkit)
445 def toolkit(toolkit):
446     if toolkit.startswith("cairo-gtk3"):
447         widget_toolkit = "gtk"
448     else:
449         widget_toolkit = toolkit.replace("cairo-", "")
450     return widget_toolkit
453 set_config("MOZ_WIDGET_TOOLKIT", toolkit)
454 add_old_configure_assignment("MOZ_WIDGET_TOOLKIT", toolkit)
457 @depends(toolkit)
458 def toolkit_define(toolkit):
459     if toolkit != "windows":
460         return "MOZ_WIDGET_%s" % toolkit.upper()
463 set_define(toolkit_define, True)
466 @depends(toolkit)
467 def toolkit_gtk(toolkit):
468     return toolkit == "gtk"
471 # Wayland support
472 # ==============================================================
473 wayland_headers = pkg_check_modules(
474     "MOZ_WAYLAND",
475     "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1 libdrm >= 2.4",
476     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3"),
477     when=toolkit_gtk,
481 @depends(wayland_headers, toolkit_gtk, artifact_builds)
482 def wayland_headers(wayland, toolkit_gtk, artifacts):
483     if toolkit_gtk and artifacts:
484         return True
485     return wayland
488 set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
489 set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
491 # GL Provider
492 # ==============================================================
493 option("--with-gl-provider", nargs=1, help="Set GL provider backend type")
496 @depends("--with-gl-provider")
497 def gl_provider(value):
498     if value:
499         return value[0]
502 @depends(gl_provider)
503 def gl_provider_define(provider):
504     if provider:
505         return "GLContextProvider%s" % provider
508 set_define("MOZ_GL_PROVIDER", gl_provider_define)
511 @depends(gl_provider, wayland_headers, toolkit_gtk)
512 def gl_default_provider(value, wayland, toolkit_gtk):
513     if value:
514         return value
515     elif wayland:
516         return "EGL"
517     elif toolkit_gtk:
518         return "GLX"
521 set_config("MOZ_GL_PROVIDER", gl_provider)
522 set_config("MOZ_GL_DEFAULT_PROVIDER", gl_default_provider)
525 @depends(gl_default_provider)
526 def gl_provider_define(provider):
527     if provider:
528         return "GL_PROVIDER_%s" % provider
531 set_define(gl_provider_define, True)
534 # PDF printing
535 # ==============================================================
536 @depends(toolkit)
537 def pdf_printing(toolkit):
538     if toolkit in ("windows", "gtk", "android"):
539         return True
542 set_config("MOZ_PDF_PRINTING", pdf_printing)
543 set_define("MOZ_PDF_PRINTING", pdf_printing)
546 # Event loop instrumentation
547 # ==============================================================
548 option(env="MOZ_INSTRUMENT_EVENT_LOOP", help="Force-enable event loop instrumentation")
551 @depends("MOZ_INSTRUMENT_EVENT_LOOP", toolkit)
552 def instrument_event_loop(value, toolkit):
553     if value or (
554         toolkit in ("windows", "gtk", "cocoa", "android") and value.origin == "default"
555     ):
556         return True
559 set_config("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
560 set_define("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
563 # Fontconfig Freetype
564 # ==============================================================
565 option(env="USE_FC_FREETYPE", help="Force-enable the use of fontconfig freetype")
568 @depends("USE_FC_FREETYPE", toolkit)
569 def fc_freetype(value, toolkit):
570     if value or (toolkit == "gtk" and value.origin == "default"):
571         return True
574 add_old_configure_assignment("USE_FC_FREETYPE", fc_freetype)
575 set_define("USE_FC_FREETYPE", fc_freetype)
577 # Pango
578 # ==============================================================
579 pkg_check_modules("MOZ_PANGO", "pango >= 1.22.0", when=toolkit_gtk)
581 # Fontconfig
582 # ==============================================================
583 fontconfig_info = pkg_check_modules(
584     "_FONTCONFIG", "fontconfig >= 2.7.0", when=fc_freetype
588 @depends(fc_freetype)
589 def check_for_freetype2(fc_freetype):
590     if fc_freetype:
591         return True
594 # Check for freetype2. Flags are combined with fontconfig flags.
595 freetype2_info = pkg_check_modules(
596     "_FT2", "freetype2 >= 9.10.3", when=check_for_freetype2
600 @depends(fontconfig_info, freetype2_info)
601 def freetype2_combined_info(fontconfig_info, freetype2_info):
602     if not freetype2_info:
603         return
604     if not fontconfig_info:
605         return freetype2_info
606     return namespace(
607         cflags=freetype2_info.cflags + fontconfig_info.cflags,
608         libs=freetype2_info.libs + fontconfig_info.libs,
609     )
612 set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
614 # Apple platform decoder support
615 # ==============================================================
616 @depends(toolkit)
617 def applemedia(toolkit):
618     if toolkit in ("cocoa", "uikit"):
619         return True
622 set_config("MOZ_APPLEMEDIA", applemedia)
623 set_define("MOZ_APPLEMEDIA", applemedia)
625 # Windows Media Foundation support
626 # ==============================================================
627 option("--disable-wmf", help="Disable support for Windows Media Foundation")
630 @depends("--disable-wmf", target)
631 def wmf(value, target):
632     enabled = bool(value)
633     if value.origin == "default":
634         # Enable Windows Media Foundation support by default.
635         # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
636         # guaranteed to have a recent-enough SDK to build WMF.
637         enabled = target.os == "WINNT"
638     if enabled and target.os != "WINNT":
639         die("Cannot enable Windows Media Foundation support on %s", target.os)
640     if enabled:
641         return True
644 @depends(c_compiler, when=wmf)
645 def wmfmediaengine(c_compiler):
646     return c_compiler and c_compiler.type == "clang-cl"
649 set_config("MOZ_WMF", wmf)
650 set_define("MOZ_WMF", wmf)
652 set_config("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
653 set_define("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
655 # FFmpeg H264/AAC Decoding Support
656 # ==============================================================
657 option("--disable-ffmpeg", help="Disable FFmpeg for fragmented H264/AAC decoding")
660 @depends("--disable-ffmpeg", target)
661 def ffmpeg(value, target):
662     enabled = bool(value)
663     if value.origin == "default":
664         enabled = target.os not in ("Android", "WINNT")
665     if enabled:
666         return True
669 set_config("MOZ_FFMPEG", ffmpeg)
670 set_define("MOZ_FFMPEG", ffmpeg)
671 imply_option("--enable-fmp4", ffmpeg, "--enable-ffmpeg")
673 # AV1 Video Codec Support
674 # ==============================================================
675 option("--disable-av1", help="Disable av1 video support")
678 @depends("--enable-av1")
679 def av1(value):
680     if value:
681         return True
684 @depends(target, when=av1 & compile_environment)
685 def dav1d_asm(target):
686     if target.cpu in ("aarch64", "x86", "x86_64"):
687         return True
690 @depends(target, when=av1 & compile_environment)
691 def dav1d_nasm(target):
692     if target.cpu in ("x86", "x86_64"):
693         return namespace(version="2.14", what="AV1")
696 set_config("MOZ_DAV1D_ASM", dav1d_asm)
697 set_define("MOZ_DAV1D_ASM", dav1d_asm)
698 set_config("MOZ_AV1", av1)
699 set_define("MOZ_AV1", av1)
701 # JXL Image Codec Support
702 # ==============================================================
703 option("--disable-jxl", help="Disable jxl image support")
706 @depends("--disable-jxl", milestone.is_nightly)
707 def jxl(value, is_nightly):
708     if is_nightly and value:
709         return True
712 set_config("MOZ_JXL", jxl)
713 set_define("MOZ_JXL", jxl)
715 # Built-in fragmented MP4 support.
716 # ==============================================================
717 option(
718     "--disable-fmp4",
719     env="MOZ_FMP4",
720     help="Disable support for in built Fragmented MP4 parsing",
724 @depends("--disable-fmp4", target, wmf, applemedia)
725 def fmp4(value, target, wmf, applemedia):
726     enabled = bool(value)
727     if value.origin == "default":
728         # target.os == 'Android' includes all B2G versions
729         enabled = wmf or applemedia or target.os == "Android"
730     if enabled:
731         return True
734 set_config("MOZ_FMP4", fmp4)
735 set_define("MOZ_FMP4", fmp4)
736 add_old_configure_assignment("MOZ_FMP4", fmp4)
739 @depends(target)
740 def sample_type_is_s16(target):
741     # Use integers over floats for audio on Android regardless of the CPU
742     # architecture, because audio backends for Android don't support floats.
743     # We also use integers on ARM because it's more efficient.
744     if target.os == "Android" or target.cpu == "arm":
745         return True
748 @depends(sample_type_is_s16)
749 def sample_type_is_float(t):
750     if not t:
751         return True
754 set_config("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
755 set_define("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
756 set_config("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
757 set_define("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
759 set_define("MOZ_VORBIS", sample_type_is_float)
760 set_config("MOZ_VORBIS", sample_type_is_float)
761 set_define("MOZ_TREMOR", sample_type_is_s16)
762 set_config("MOZ_TREMOR", sample_type_is_s16)
764 option(
765     "--disable-real-time-tracing",
766     help="Disable tracing of real-time audio callbacks",
769 set_config("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
770 set_define("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
772 # OpenMAX IL Decoding Support
773 # ==============================================================
774 option("--enable-openmax", help="Enable OpenMAX IL for video/audio decoding")
777 @depends("--enable-openmax")
778 def openmax(value):
779     enabled = bool(value)
780     if enabled:
781         return True
784 set_config("MOZ_OMX", openmax)
785 set_define("MOZ_OMX", openmax)
787 # EME Support
788 # ==============================================================
789 @depends(target)
790 def eme_choices(target):
791     if (
792         target.kernel in ("WINNT", "Linux")
793         and target.os != "Android"
794         and target.cpu in ("x86", "x86_64")
795     ):
796         return ("widevine",)
797     if target.kernel == "WINNT" and target.cpu == "aarch64":
798         return ("widevine",)
799     if target.os in ("OSX"):
800         return ("widevine",)
803 # Widevine is enabled by default in desktop browser builds, except
804 # on aarch64 Windows.
805 @depends(build_project, eme_choices, target)
806 def eme_default(build_project, choices, target):
807     if build_project == "browser":
808         if target.kernel != "WINNT" or target.cpu != "aarch64":
809             return choices
812 option(
813     "--enable-eme",
814     nargs="+",
815     choices=eme_choices,
816     default=eme_default,
817     when=eme_choices,
818     help="{Enable|Disable} support for Encrypted Media Extensions",
822 @depends("--enable-eme", fmp4, when=eme_choices)
823 def eme(enabled, fmp4):
824     if enabled and enabled.origin != "default" and not fmp4:
825         die("Encrypted Media Extension support requires " "Fragmented MP4 support")
828 @depends("--enable-eme", when=eme_choices)
829 def eme_modules(value):
830     return value
833 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
834 # None.
835 set_config("MOZ_EME_MODULES", eme_modules | dependable([]))
838 @depends(eme_modules, target, when=eme_modules)
839 def eme_win32_artifact(modules, target):
840     if "widevine" in modules and target.kernel == "WINNT" and target.cpu == "aarch64":
841         return True
844 set_config("MOZ_EME_WIN32_ARTIFACT", eme_win32_artifact)
846 option(
847     name="--enable-chrome-format",
848     help="Select FORMAT of chrome files during packaging.",
849     nargs=1,
850     choices=("omni", "jar", "flat"),
851     default="omni",
855 @depends("--enable-chrome-format")
856 def packager_format(value):
857     return value[0]
860 set_config("MOZ_PACKAGER_FORMAT", packager_format)
862 # The packager minifies two different types of files: non-JS (mostly property
863 # files for l10n), and JS.  Setting MOZ_PACKAGER_MINIFY only minifies the
864 # former.  Firefox doesn't yet minify JS, due to concerns about debuggability.
866 # Also, the JS minification setup really only works correctly on Android:
867 # we need extra setup to use the newly-built shell for Linux and Windows,
868 # and cross-compilation for macOS requires some extra care.
871 @depends(target_is_android, "--enable-debug", milestone.is_nightly)
872 def enable_minify_default(is_android, debug, is_nightly):
873     if is_android and not debug and not is_nightly:
874         return ("properties", "js")
875     return ("properties",)
878 option(
879     name="--enable-minify",
880     help="Select types of files to minify during packaging.",
881     nargs="*",
882     choices=("properties", "js"),
883     default=enable_minify_default,
887 @depends("--enable-minify")
888 def enable_minify(value):
889     if "js" in value and "properties" not in value:
890         die("--enable-minify=js requires --enable-minify=properties.")
891     return namespace(
892         properties="properties" in value,
893         js="js" in value,
894     )
897 set_config("MOZ_PACKAGER_MINIFY", True, when=enable_minify.properties)
898 set_config("MOZ_PACKAGER_MINIFY_JS", True, when=enable_minify.js)
901 @depends(host, build_project)
902 def jar_maker_format(host, build_project):
903     # Multilocales for mobile/android use the same mergedirs for all locales,
904     # so we can't use symlinks for those builds.
905     if host.os == "WINNT" or build_project == "mobile/android":
906         return "flat"
907     return "symlink"
910 set_config("MOZ_JAR_MAKER_FILE_FORMAT", jar_maker_format)
913 @depends(toolkit)
914 def omnijar_name(toolkit):
915     # Fennec's static resources live in the assets/ folder of the
916     # APK.  Adding a path to the name here works because we only
917     # have one omnijar file in the final package (which is not the
918     # case on desktop).
919     return "assets/omni.ja" if toolkit == "android" else "omni.ja"
922 set_config("OMNIJAR_NAME", omnijar_name)
924 project_flag("MOZ_PLACES", help="Build Places if required", set_as_define=True)
926 project_flag(
927     "MOZ_SERVICES_HEALTHREPORT",
928     help="Build Firefox Health Reporter Service",
929     set_for_old_configure=True,
930     set_as_define=True,
933 project_flag(
934     "MOZ_NORMANDY",
935     help="Enable Normandy recipe runner",
936     set_for_old_configure=True,
937     set_as_define=True,
940 project_flag("MOZ_SERVICES_SYNC", help="Build Sync Services if required")
942 project_flag(
943     "MOZ_ANDROID_HISTORY",
944     help="Enable Android History instead of Places",
945     set_as_define=True,
948 project_flag(
949     "MOZ_DEDICATED_PROFILES",
950     help="Enable dedicated profiles per install",
951     set_as_define=True,
954 project_flag(
955     "MOZ_BLOCK_PROFILE_DOWNGRADE",
956     help="Block users from starting profiles last used by a newer build",
957     set_as_define=True,
961 @depends("MOZ_PLACES", "MOZ_ANDROID_HISTORY")
962 def check_places_and_android_history(places, android_history):
963     if places and android_history:
964         die("Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.")
967 option(
968     env="MOZ_TELEMETRY_REPORTING",
969     default=mozilla_official,
970     help="Enable telemetry reporting",
973 set_define("MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING")
974 add_old_configure_assignment(
975     "MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING"
979 @depends("MOZ_TELEMETRY_REPORTING", milestone.is_nightly)
980 def telemetry_on_by_default(reporting, is_nightly):
981     return reporting and is_nightly
984 set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
987 # gpsd support
988 # ==============================================================
989 system_lib_option("--enable-gpsd", env="MOZ_GPSD", help="Enable gpsd support")
992 @depends("--enable-gpsd")
993 def gpsd(value):
994     return bool(value)
997 system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
999 set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
1001 # Miscellaneous programs
1002 # ==============================================================
1004 check_prog("TAR", ("gnutar", "gtar", "tar"))
1005 check_prog("UNZIP", ("unzip",))
1007 # Key files
1008 # ==============================================================
1009 include("../build/moz.configure/keyfiles.configure")
1011 simple_keyfile("Mozilla API")
1013 simple_keyfile("Google Location Service API")
1015 simple_keyfile("Google Safebrowsing API")
1017 id_and_secret_keyfile("Bing API")
1019 simple_keyfile("Adjust SDK")
1021 id_and_secret_keyfile("Leanplum SDK")
1023 simple_keyfile("Pocket API")
1026 # WebRender Debugger integration
1027 # ==============================================================
1029 option(
1030     "--enable-webrender-debugger", help="Build the websocket debug server in WebRender"
1033 set_config(
1034     "MOZ_WEBRENDER_DEBUGGER", depends_if("--enable-webrender-debugger")(lambda _: True)
1037 # Additional system headers defined at the application level
1038 # ==============================================================
1040 option(
1041     "--enable-app-system-headers",
1042     env="MOZ_APP_SYSTEM_HEADERS",
1043     help="Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild",
1047 @depends("--enable-app-system-headers")
1048 def app_system_headers(value):
1049     if value:
1050         return True
1053 set_config("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1054 set_define("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1056 # Printing
1057 # ==============================================================
1058 option("--disable-printing", help="Disable printing support")
1061 @depends("--disable-printing")
1062 def printing(value):
1063     if value:
1064         return True
1067 set_config("NS_PRINTING", printing)
1068 set_define("NS_PRINTING", printing)
1069 set_define("NS_PRINT_PREVIEW", printing)
1071 # Speech-dispatcher support
1072 # ==============================================================
1073 @depends(toolkit)
1074 def no_speechd_on_non_gtk(toolkit):
1075     if toolkit != "gtk":
1076         return False
1079 imply_option(
1080     "--enable-synth-speechd", no_speechd_on_non_gtk, reason="--enable-default-toolkit"
1083 option("--disable-synth-speechd", help="Disable speech-dispatcher support")
1085 set_config("MOZ_SYNTH_SPEECHD", depends_if("--disable-synth-speechd")(lambda _: True))
1087 # Speech API
1088 # ==============================================================
1089 option("--disable-webspeech", help="Disable support for HTML Speech API")
1092 @depends("--disable-webspeech")
1093 def webspeech(value):
1094     if value:
1095         return True
1098 set_config("MOZ_WEBSPEECH", webspeech)
1099 set_define("MOZ_WEBSPEECH", webspeech)
1100 add_old_configure_assignment("MOZ_WEBSPEECH", webspeech)
1102 # Speech API test backend
1103 # ==============================================================
1104 option(
1105     "--enable-webspeechtestbackend",
1106     default=webspeech,
1107     help="{Enable|Disable} support for HTML Speech API Test Backend",
1111 @depends_if("--enable-webspeechtestbackend")
1112 def webspeech_test_backend(value):
1113     return True
1116 set_config("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1117 set_define("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1119 # Graphics
1120 # ==============================================================
1121 @depends(target, milestone)
1122 def skia_pdf_default(target, milestone):
1123     return milestone.is_nightly and target.os != "WINNT"
1126 option("--enable-skia-pdf", default=skia_pdf_default, help="{Enable|Disable} Skia PDF")
1128 set_config("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1129 set_define("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1131 set_config(
1132     "SKIA_INCLUDES",
1133     [
1134         "/gfx/skia",
1135         "/gfx/skia/skia",
1136     ],
1139 system_lib_option(
1140     "--with-system-webp", help="Use system libwebp (located with pkgconfig)"
1143 system_webp = pkg_check_modules(
1144     "MOZ_WEBP", "libwebp >= 1.0.2 libwebpdemux >= 1.0.2", when="--with-system-webp"
1147 set_config("MOZ_SYSTEM_WEBP", depends(when=system_webp)(lambda: True))
1149 # Build Freetype in the tree
1150 # ==============================================================
1151 @depends(target, "--enable-skia-pdf")
1152 def tree_freetype(target, skia_pdf):
1153     if target.os == "Android" or (skia_pdf and target.os == "WINNT"):
1154         return True
1157 set_define("MOZ_TREE_FREETYPE", tree_freetype)
1158 set_config("MOZ_TREE_FREETYPE", tree_freetype)
1160 set_define("HAVE_FT_BITMAP_SIZE_Y_PPEM", tree_freetype)
1161 set_define("HAVE_FT_GLYPHSLOT_EMBOLDEN", tree_freetype)
1162 set_define("HAVE_FT_LOAD_SFNT_TABLE", tree_freetype)
1165 @depends(freetype2_combined_info, tree_freetype, build_environment)
1166 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
1167     if tree_freetype:
1168         return namespace(
1169             cflags=("-I%s/modules/freetype2/include" % build_env.topsrcdir,), libs=()
1170         )
1171     if freetype2_combined_info:
1172         return freetype2_combined_info
1175 set_config("FT2_LIBS", ft2_info.libs)
1178 @depends(target, tree_freetype, freetype2_info)
1179 def enable_cairo_ft(target, tree_freetype, freetype2_info):
1180     # Avoid defining MOZ_ENABLE_CAIRO_FT on Windows platforms because
1181     # "cairo-ft-font.c" includes <dlfcn.h>, which only exists on posix platforms
1182     return freetype2_info or (tree_freetype and target.os != "WINNT")
1185 set_config("MOZ_ENABLE_CAIRO_FT", True, when=enable_cairo_ft)
1186 set_config("CAIRO_FT_CFLAGS", ft2_info.cflags, when=enable_cairo_ft)
1189 # WebDriver (HTTP / BiDi)
1190 # ==============================================================
1192 # WebDriver is a remote control interface that enables introspection and
1193 # control of user agents. It provides a platform- and language-neutral wire
1194 # protocol as a way for out-of-process programs to remotely instruct the
1195 # behavior of web browsers.
1197 # The Gecko implementation is backed by Marionette and Remote Agent.
1198 # Both protocols are not really toolkit features, as much as Gecko engine
1199 # features. But they are enabled based on the toolkit, so here it lives.
1201 # Marionette remote protocol
1202 # -----------------------------------------------------------
1204 # Marionette is the Gecko remote protocol used for various remote control,
1205 # automation, and testing purposes throughout Gecko-based applications like
1206 # Firefox, Thunderbird, and any mobile browser built upon GeckoView.
1208 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
1209 # implementation.
1211 # The source of Marionette lives in ../remote/marionette.
1213 # For more information, see:
1214 # https://firefox-source-docs.mozilla.org/testing/marionette/index.html
1216 # Remote Agent (WebDriver BiDi / partial CDP)
1217 # -----------------------------------------------------------
1219 # The primary purpose is the implementation of the WebDriver BiDi specification.
1220 # But it also complements the existing Firefox Developer Tools Remote Debugging
1221 # Protocol (RDP) by implementing a subset of the Chrome DevTools Protocol (CDP).
1223 # The source of Remote Agent lives in ../remote.
1225 # For more information, see:
1226 # https://firefox-source-docs.mozilla.org/remote/index.html
1229 option(
1230     "--disable-webdriver",
1231     help="Disable support for WebDriver remote protocols",
1235 @depends("--disable-webdriver")
1236 def webdriver(enabled):
1237     if enabled:
1238         return True
1241 set_config("ENABLE_WEBDRIVER", webdriver)
1242 set_define("ENABLE_WEBDRIVER", webdriver)
1245 # geckodriver WebDriver implementation
1246 # ==============================================================
1248 # Turn off geckodriver for build configs we don't handle yet,
1249 # but allow --enable-geckodriver to override when compile environment is available.
1250 # --disable-tests implies disabling geckodriver.
1251 # Disable building in CI
1254 @depends(
1255     "--enable-tests", target, cross_compiling, hazard_analysis, asan, "MOZ_AUTOMATION"
1257 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
1258     if not enable_tests:
1259         return False
1260     if hazard or target.os == "Android" or (asan and cross_compile):
1261         return False
1262     if automation:
1263         return False
1264     return True
1267 option(
1268     "--enable-geckodriver",
1269     default=geckodriver_default,
1270     when="--enable-compile-environment",
1271     help="{Build|Do not build} geckodriver",
1275 @depends("--enable-geckodriver", when="--enable-compile-environment")
1276 def geckodriver(enabled):
1277     if enabled:
1278         return True
1281 set_config("MOZ_GECKODRIVER", geckodriver)
1284 # WebRTC
1285 # ========================================================
1286 @depends(target)
1287 def webrtc_default(target):
1288     # Turn off webrtc for OS's we don't handle yet, but allow
1289     # --enable-webrtc to override.
1290     os_match = False
1291     for os_fragment in (
1292         "linux",
1293         "mingw",
1294         "android",
1295         "linuxandroid",
1296         "dragonfly",
1297         "freebsd",
1298         "netbsd",
1299         "openbsd",
1300         "darwin",
1301     ):
1302         if target.raw_os.startswith(os_fragment):
1303             os_match = True
1305     cpu_match = False
1306     if (
1307         target.cpu
1308         in (
1309             "x86_64",
1310             "arm",
1311             "aarch64",
1312             "x86",
1313             "ia64",
1314             "mips32",
1315             "mips64",
1316         )
1317         or target.cpu.startswith("ppc")
1318     ):
1319         cpu_match = True
1321     if os_match and cpu_match:
1322         return True
1323     return False
1326 option(
1327     "--disable-webrtc",
1328     default=webrtc_default,
1329     help="{Enable|Disable} support for WebRTC",
1333 @depends("--disable-webrtc")
1334 def webrtc(enabled):
1335     if enabled:
1336         return True
1339 set_config("MOZ_WEBRTC", webrtc)
1340 set_define("MOZ_WEBRTC", webrtc)
1341 set_config("MOZ_SCTP", webrtc)
1342 set_define("MOZ_SCTP", webrtc)
1343 set_config("MOZ_SRTP", webrtc)
1344 set_define("MOZ_SRTP", webrtc)
1345 set_config("MOZ_WEBRTC_SIGNALING", webrtc)
1346 set_define("MOZ_WEBRTC_SIGNALING", webrtc)
1347 set_config("MOZ_PEERCONNECTION", webrtc)
1348 set_define("MOZ_PEERCONNECTION", webrtc)
1349 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1350 # opt/production builds (via MOZ_CRASH())
1351 set_config("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1352 set_define("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1354 # RAW media
1355 # ==============================================================
1358 @depends(target, webrtc)
1359 def raw_media_default(target, webrtc):
1360     if target.os == "Android":
1361         return True
1362     if webrtc:
1363         return True
1366 option(
1367     "--enable-raw",
1368     default=raw_media_default,
1369     help="{Enable|Disable} support for RAW media",
1372 set_config("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1373 set_define("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1376 # X11
1377 # ==============================================================
1378 @depends(webrtc, when=toolkit_gtk)
1379 def x11_libs(webrtc):
1380     libs = [
1381         "x11",
1382         "xcb",
1383         "xcb-shm",
1384         "x11-xcb",
1385         "xext",
1386         "xrandr >= 1.4.0",
1387     ]
1388     if webrtc:
1389         # third_party/libwebrtc/webrtc/webrtc_gn/moz.build adds those
1390         # manually, ensure they're available.
1391         libs += [
1392             "xcomposite",
1393             "xcursor",
1394             "xdamage",
1395             "xfixes",
1396             "xi",
1397             "xtst",
1398         ]
1399     return libs
1402 x11_headers = pkg_check_modules(
1403     "MOZ_X11",
1404     x11_libs,
1405     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1406     when=depends(full_toolkit)(
1407         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1408     ),
1412 set_config("MOZ_X11", True, when=x11_headers)
1413 set_define("MOZ_X11", True, when=x11_headers)
1415 pkg_check_modules(
1416     "MOZ_X11_SM",
1417     ["ice", "sm"],
1418     cflags_only=True,
1419     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1420     when=depends(full_toolkit)(
1421         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1422     ),
1426 # ASan Reporter Addon
1427 # ==============================================================
1428 option(
1429     "--enable-address-sanitizer-reporter",
1430     help="Enable Address Sanitizer Reporter Extension",
1434 @depends("--enable-address-sanitizer-reporter")
1435 def enable_asan_reporter(value):
1436     if value:
1437         return True
1440 set_config("MOZ_ASAN_REPORTER", enable_asan_reporter)
1441 set_define("MOZ_ASAN_REPORTER", enable_asan_reporter)
1442 add_old_configure_assignment("MOZ_ASAN_REPORTER", enable_asan_reporter)
1444 # Elfhack
1445 # ==============================================================
1446 with only_when("--enable-compile-environment"):
1448     @depends(host, target)
1449     def has_elfhack(host, target):
1450         return (
1451             target.kernel == "Linux"
1452             and host.kernel == "Linux"
1453             and target.cpu in ("arm", "aarch64", "x86", "x86_64")
1454         )
1456     @depends("--enable-release", enable_linker)
1457     def default_elfhack(release, linker):
1458         # Disable elfhack when explicitly building with --enable-linker=lld
1459         if linker and linker.origin != "default" and linker[0] in ("lld", "mold"):
1460             return False
1461         return bool(release)
1463     with only_when(has_elfhack):
1464         option(
1465             "--disable-elf-hack",
1466             default=default_elfhack,
1467             help="{Enable|Disable} elf hacks",
1468         )
1470         @depends(select_linker, when="--enable-elf-hack")
1471         def use_elf_hack(linker):
1472             if linker and linker.KIND == "lld":
1473                 die(
1474                     "Cannot enable elfhack with lld."
1475                     " Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
1476                 )
1477             return True
1479         set_config("USE_ELF_HACK", use_elf_hack)
1482 @depends(build_environment)
1483 def idl_roots(build_env):
1484     return namespace(
1485         ipdl_root=os.path.join(build_env.topobjdir, "ipc", "ipdl"),
1486         webidl_root=os.path.join(build_env.topobjdir, "dom", "bindings"),
1487         xpcom_root=os.path.join(build_env.topobjdir, "xpcom", "components"),
1488     )
1491 set_config("WEBIDL_ROOT", idl_roots.webidl_root)
1492 set_config("IPDL_ROOT", idl_roots.ipdl_root)
1493 set_config("XPCOM_ROOT", idl_roots.xpcom_root)
1495 # Proxy bypass protection
1496 # ==============================================================
1498 option(
1499     "--enable-proxy-bypass-protection",
1500     help="Prevent suspected or confirmed proxy bypasses",
1504 @depends_if("--enable-proxy-bypass-protection")
1505 def proxy_bypass_protection(_):
1506     return True
1509 set_config("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1510 set_define("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1512 # Proxy direct failover
1513 # ==============================================================
1515 option(
1516     "--disable-proxy-direct-failover",
1517     help="Disable direct failover for system requests",
1521 @depends_if("--disable-proxy-direct-failover")
1522 def proxy_direct_failover(value):
1523     if value:
1524         return True
1527 set_config("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1528 set_define("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1530 # MIDL
1531 # ==============================================================
1534 @depends(c_compiler, toolchain_prefix)
1535 def midl_names(c_compiler, toolchain_prefix):
1536     if c_compiler and c_compiler.type in ["gcc", "clang"]:
1537         # mingw
1538         widl = ("widl",)
1539         if toolchain_prefix:
1540             prefixed = tuple("%s%s" % (p, "widl") for p in toolchain_prefix)
1541             widl = prefixed + widl
1542         return widl
1544     return ("midl.exe",)
1547 @depends(target, "--enable-compile-environment")
1548 def check_for_midl(target, compile_environment):
1549     if target.os != "WINNT":
1550         return
1552     if compile_environment:
1553         return True
1556 midl = check_prog(
1557     "MIDL",
1558     midl_names,
1559     when=check_for_midl,
1560     allow_missing=True,
1561     paths=sdk_bin_path,
1562     # MIDL being used from a python wrapper script, we can live with it
1563     # having spaces.
1564     allow_spaces=True,
1567 option(env="MIDL_FLAGS", nargs=1, help="Extra flags to pass to MIDL")
1570 @depends(
1571     "MIDL_FLAGS",
1572     target,
1573     midl,
1574     when=depends(midl, target)(lambda m, t: m and t.kernel == "WINNT"),
1576 def midl_flags(flags, target, midl):
1577     if flags:
1578         flags = flags[0].split()
1579     else:
1580         flags = []
1582     if not midl.endswith("widl"):
1583         env = {
1584             "x86": "win32",
1585             "x86_64": "x64",
1586             "aarch64": "arm64",
1587         }[target.cpu]
1588         return flags + ["-nologo", "-no_cpp", "-env", env]
1590     # widl
1591     return flags + {
1592         "x86": ["--win32", "-m32"],
1593         "x86_64": ["--win64", "-m64"],
1594     }[target.cpu]
1597 set_config("MIDL_FLAGS", midl_flags)
1599 # Accessibility
1600 # ==============================================================
1602 option("--disable-accessibility", help="Disable accessibility support")
1605 @depends("--enable-accessibility", check_for_midl, midl, c_compiler)
1606 def accessibility(value, check_for_midl, midl, c_compiler):
1607     enabled = bool(value)
1609     if not enabled:
1610         return
1612     if check_for_midl and not midl:
1613         if c_compiler and c_compiler.type in ("gcc", "clang"):
1614             die(
1615                 "You have accessibility enabled, but widl could not be found. "
1616                 "Add --disable-accessibility to your mozconfig or install widl. "
1617                 "See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details."
1618             )
1619         else:
1620             die(
1621                 "MIDL could not be found. "
1622                 "Building accessibility without MIDL is not supported."
1623             )
1625     return enabled
1628 set_config("ACCESSIBILITY", accessibility)
1629 set_define("ACCESSIBILITY", accessibility)
1632 @depends(moz_debug, developer_options)
1633 def a11y_log(debug, developer_options):
1634     return debug or developer_options
1637 set_config("A11Y_LOG", True, when=a11y_log)
1638 set_define("A11Y_LOG", True, when=a11y_log)
1641 # Addon signing
1642 # ==============================================================
1643 @depends(milestone)
1644 def require_signing(milestone):
1645     return milestone.is_release_or_beta and not milestone.is_esr
1648 option(
1649     env="MOZ_REQUIRE_SIGNING",
1650     default=require_signing,
1651     help="Enforce that add-ons are signed by the trusted root",
1654 set_config("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1655 set_define("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1657 option(
1658     "--with-unsigned-addon-scopes",
1659     nargs="+",
1660     choices=("app", "system"),
1661     help="Addon scopes where signature is not required",
1665 @depends("--with-unsigned-addon-scopes")
1666 def unsigned_addon_scopes(scopes):
1667     return namespace(
1668         app="app" in scopes or None,
1669         system="system" in scopes or None,
1670     )
1673 set_config("MOZ_UNSIGNED_APP_SCOPE", unsigned_addon_scopes.app)
1674 set_config("MOZ_UNSIGNED_SYSTEM_SCOPE", unsigned_addon_scopes.system)
1677 # Addon sideloading
1678 # ==============================================================
1679 option(
1680     "--allow-addon-sideload",
1681     default=milestone.is_esr,
1682     help="Addon sideloading is allowed",
1686 set_config("MOZ_ALLOW_ADDON_SIDELOAD", True, when="--allow-addon-sideload")
1688 # WebExtensions API WebIDL bindings
1689 # ==============================================================
1692 @depends(milestone)
1693 def extensions_webidl_bindings_default(milestone):
1694     # Only enable the webidl bindings for the WebExtensions APIs
1695     # in Nightly.
1696     return milestone.is_nightly
1699 option(
1700     "--enable-extensions-webidl-bindings",
1701     default=extensions_webidl_bindings_default,
1702     help="{Enable|Disable} building experimental WebExtensions WebIDL bindings",
1706 @depends("--enable-extensions-webidl-bindings")
1707 def extensions_webidl_enabled(value):
1708     return bool(value)
1711 set_config("MOZ_WEBEXT_WEBIDL_ENABLED", extensions_webidl_enabled)
1713 # Launcher process (Windows only)
1714 # ==============================================================
1717 @depends(target)
1718 def launcher_process_default(target):
1719     return target.os == "WINNT"
1722 option(
1723     "--enable-launcher-process",
1724     default=launcher_process_default,
1725     help="{Enable|Disable} launcher process by default",
1729 @depends("--enable-launcher-process", target)
1730 def launcher(value, target):
1731     enabled = bool(value)
1732     if enabled and target.os != "WINNT":
1733         die("Cannot enable launcher process on %s", target.os)
1734     if enabled:
1735         return True
1738 set_config("MOZ_LAUNCHER_PROCESS", launcher)
1739 set_define("MOZ_LAUNCHER_PROCESS", launcher)
1741 # llvm-dlltool (Windows only)
1742 # ==============================================================
1745 @depends(build_project, target, "--enable-compile-environment")
1746 def check_for_llvm_dlltool(build_project, target, compile_environment):
1747     if build_project != "browser":
1748         return
1750     if target.os != "WINNT":
1751         return
1753     return compile_environment
1756 llvm_dlltool = check_prog(
1757     "LLVM_DLLTOOL",
1758     ("llvm-dlltool",),
1759     what="llvm-dlltool",
1760     when=check_for_llvm_dlltool,
1761     paths=clang_search_path,
1765 @depends(target, when=llvm_dlltool)
1766 def llvm_dlltool_flags(target):
1767     arch = {
1768         "x86": "i386",
1769         "x86_64": "i386:x86-64",
1770         "aarch64": "arm64",
1771     }[target.cpu]
1773     return ["-m", arch]
1776 set_config("LLVM_DLLTOOL_FLAGS", llvm_dlltool_flags)
1778 # BITS download (Windows only)
1779 # ==============================================================
1781 option(
1782     "--enable-bits-download",
1783     when=target_is_windows,
1784     default=target_is_windows,
1785     help="{Enable|Disable} building BITS download support",
1788 set_define(
1789     "MOZ_BITS_DOWNLOAD",
1790     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1792 set_config(
1793     "MOZ_BITS_DOWNLOAD",
1794     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1797 # Bundled fonts on desktop platform
1798 # ==============================================================
1801 @depends(target)
1802 def bundled_fonts_default(target):
1803     return target.os == "WINNT" or target.kernel == "Linux"
1806 @depends(build_project)
1807 def allow_bundled_fonts(project):
1808     return project == "browser" or project == "comm/mail"
1811 option(
1812     "--enable-bundled-fonts",
1813     default=bundled_fonts_default,
1814     when=allow_bundled_fonts,
1815     help="{Enable|Disable} support for bundled fonts on desktop platforms",
1818 set_define(
1819     "MOZ_BUNDLED_FONTS",
1820     depends_if("--enable-bundled-fonts", when=allow_bundled_fonts)(lambda _: True),
1823 # Reflow counting
1824 # ==============================================================
1827 @depends(moz_debug)
1828 def reflow_perf(debug):
1829     if debug:
1830         return True
1833 option(
1834     "--enable-reflow-perf",
1835     default=reflow_perf,
1836     help="{Enable|Disable} reflow performance tracing",
1839 # The difference in conditions here comes from the initial implementation
1840 # in old-configure, which was unexplained there as well.
1841 set_define("MOZ_REFLOW_PERF", depends_if("--enable-reflow-perf")(lambda _: True))
1842 set_define("MOZ_REFLOW_PERF_DSP", reflow_perf)
1844 # Layout debugger
1845 # ==============================================================
1848 @depends(moz_debug)
1849 def layout_debugger(debug):
1850     if debug:
1851         return True
1854 option(
1855     "--enable-layout-debugger",
1856     default=layout_debugger,
1857     help="{Enable|Disable} layout debugger",
1860 set_config("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1861 set_define("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1864 # Shader Compiler for Windows (and MinGW Cross Compile)
1865 # ==============================================================
1867 with only_when(compile_environment):
1868     fxc = check_prog(
1869         "FXC",
1870         ("fxc.exe", "fxc2.exe"),
1871         when=depends(target)(lambda t: t.kernel == "WINNT"),
1872         paths=sdk_bin_path,
1873         # FXC being used from a python wrapper script, we can live with it
1874         # having spaces.
1875         allow_spaces=True,
1876     )
1879 # VPX
1880 # ===
1882 with only_when(compile_environment):
1883     system_lib_option(
1884         "--with-system-libvpx", help="Use system libvpx (located with pkgconfig)"
1885     )
1887     with only_when("--with-system-libvpx"):
1888         vpx = pkg_check_modules("MOZ_LIBVPX", "vpx >= 1.10.0")
1890         check_header(
1891             "vpx/vpx_decoder.h",
1892             flags=vpx.cflags,
1893             onerror=lambda: die(
1894                 "Couldn't find vpx/vpx_decoder.h, which is required to build "
1895                 "with system libvpx. Use --without-system-libvpx to build "
1896                 "with in-tree libvpx."
1897             ),
1898         )
1900         check_symbol(
1901             "vpx_codec_dec_init_ver",
1902             flags=vpx.libs,
1903             onerror=lambda: die(
1904                 "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1905                 "not found"
1906             ),
1907         )
1909         set_config("MOZ_SYSTEM_LIBVPX", True)
1911     @depends("--with-system-libvpx", target)
1912     def in_tree_vpx(system_libvpx, target):
1913         if system_libvpx:
1914             return
1916         arm_asm = (target.cpu == "arm") or None
1917         return namespace(arm_asm=arm_asm)
1919     @depends(target, when=in_tree_vpx)
1920     def vpx_nasm(target):
1921         if target.cpu in ("x86", "x86_64"):
1922             if target.kernel == "WINNT":
1923                 # Version 2.03 is needed for automatic safeseh support.
1924                 return namespace(version="2.03", what="VPX")
1925             return namespace(what="VPX")
1927     @depends(in_tree_vpx, vpx_nasm, target, neon_flags)
1928     def vpx_as_flags(vpx, vpx_nasm, target, neon_flags):
1929         if vpx and vpx.arm_asm:
1930             # These flags are a lie; they're just used to enable the requisite
1931             # opcodes; actual arch detection is done at runtime.
1932             return neon_flags
1933         elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64":
1934             return ("-DPIC",)
1936     set_config("VPX_USE_NASM", True, when=vpx_nasm)
1937     set_config("VPX_ASFLAGS", vpx_as_flags)
1940 # JPEG
1941 # ====
1943 with only_when(compile_environment):
1944     system_lib_option(
1945         "--with-system-jpeg",
1946         nargs="?",
1947         help="Use system libjpeg (installed at given prefix)",
1948     )
1950     @depends_if("--with-system-jpeg")
1951     def jpeg_flags(value):
1952         if len(value):
1953             return namespace(
1954                 cflags=("-I%s/include" % value[0],),
1955                 ldflags=("-L%s/lib" % value[0], "-ljpeg"),
1956             )
1957         return namespace(
1958             ldflags=("-ljpeg",),
1959         )
1961     with only_when("--with-system-jpeg"):
1962         check_symbol(
1963             "jpeg_destroy_compress",
1964             flags=jpeg_flags.ldflags,
1965             onerror=lambda: die(
1966                 "--with-system-jpeg requested but symbol "
1967                 "jpeg_destroy_compress not found."
1968             ),
1969         )
1971         c_compiler.try_compile(
1972             includes=[
1973                 "stdio.h",
1974                 "sys/types.h",
1975                 "jpeglib.h",
1976             ],
1977             body="""
1978                 #if JPEG_LIB_VERSION < 62
1979                 #error Insufficient JPEG library version
1980                 #endif
1981             """,
1982             flags=jpeg_flags.cflags,
1983             check_msg="for sufficient jpeg library version",
1984             onerror=lambda: die(
1985                 "Insufficient JPEG library version for "
1986                 "--with-system-jpeg (62 required)"
1987             ),
1988         )
1990         c_compiler.try_compile(
1991             includes=[
1992                 "stdio.h",
1993                 "sys/types.h",
1994                 "jpeglib.h",
1995             ],
1996             body="""
1997                 #ifndef JCS_EXTENSIONS
1998                 #error libjpeg-turbo JCS_EXTENSIONS required
1999                 #endif
2000             """,
2001             flags=jpeg_flags.cflags,
2002             check_msg="for sufficient libjpeg-turbo JCS_EXTENSIONS",
2003             onerror=lambda: die(
2004                 "libjpeg-turbo JCS_EXTENSIONS required for " "--with-system-jpeg"
2005             ),
2006         )
2008         set_config("MOZ_JPEG_CFLAGS", jpeg_flags.cflags)
2009         set_config("MOZ_JPEG_LIBS", jpeg_flags.ldflags)
2011     @depends("--with-system-jpeg", target, neon_flags)
2012     def in_tree_jpeg_arm(system_jpeg, target, neon_flags):
2013         if system_jpeg:
2014             return
2016         if target.cpu == "arm":
2017             return neon_flags
2018         elif target.cpu == "aarch64":
2019             return ("-march=armv8-a",)
2021     @depends("--with-system-jpeg", target)
2022     def in_tree_jpeg_mips64(system_jpeg, target):
2023         if system_jpeg:
2024             return
2026         if target.cpu == "mips64":
2027             return ("-Wa,-mloongson-mmi", "-mloongson-ext")
2029     # Compiler check from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L419
2030     jpeg_mips64_mmi = c_compiler.try_compile(
2031         body='int c = 0, a = 0, b = 0; asm("paddb %0, %1, %2" : "=f" (c) : "f" (a), "f" (b));',
2032         check_msg="for loongson mmi support",
2033         flags=in_tree_jpeg_mips64,
2034         when=in_tree_jpeg_mips64,
2035     )
2037     @depends(
2038         "--with-system-jpeg",
2039         target,
2040         in_tree_jpeg_arm,
2041         in_tree_jpeg_mips64,
2042         jpeg_mips64_mmi,
2043     )
2044     def in_tree_jpeg(
2045         system_jpeg, target, in_tree_jpeg_arm, in_tree_jpeg_mips64, jpeg_mips64_mmi
2046     ):
2047         if system_jpeg:
2048             return
2050         if target.cpu in ("arm", "aarch64"):
2051             return in_tree_jpeg_arm
2052         elif target.kernel == "Darwin":
2053             if target.cpu == "x86":
2054                 return ("-DPIC", "-DMACHO")
2055             elif target.cpu == "x86_64":
2056                 return ("-D__x86_64__", "-DPIC", "-DMACHO")
2057         elif target.kernel == "WINNT":
2058             if target.cpu == "x86":
2059                 return ("-DPIC", "-DWIN32")
2060             elif target.cpu == "x86_64":
2061                 return ("-D__x86_64__", "-DPIC", "-DWIN64", "-DMSVC")
2062         elif target.cpu == "mips32":
2063             return ("-mdspr2",)
2064         elif target.cpu == "mips64" and jpeg_mips64_mmi:
2065             return in_tree_jpeg_mips64
2066         elif target.cpu == "x86":
2067             return ("-DPIC", "-DELF")
2068         elif target.cpu == "x86_64":
2069             return ("-D__x86_64__", "-DPIC", "-DELF")
2071     @depends(target, when=depends("--with-system-jpeg")(lambda x: not x))
2072     def jpeg_nasm(target):
2073         if target.cpu in ("x86", "x86_64"):
2074             # libjpeg-turbo 2.0.6 requires nasm 2.10.
2075             return namespace(version="2.10", what="JPEG")
2077     # Compiler checks from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L258
2078     jpeg_arm_neon_vld1_s16_x3 = c_compiler.try_compile(
2079         includes=["arm_neon.h"],
2080         body="int16_t input[12] = {}; int16x4x3_t output = vld1_s16_x3(input);",
2081         check_msg="for vld1_s16_x3 in arm_neon.h",
2082         flags=in_tree_jpeg_arm,
2083         when=in_tree_jpeg_arm,
2084     )
2086     jpeg_arm_neon_vld1_u16_x2 = c_compiler.try_compile(
2087         includes=["arm_neon.h"],
2088         body="uint16_t input[8] = {}; uint16x4x2_t output = vld1_u16_x2(input);",
2089         check_msg="for vld1_u16_x2 in arm_neon.h",
2090         flags=in_tree_jpeg_arm,
2091         when=in_tree_jpeg_arm,
2092     )
2094     jpeg_arm_neon_vld1q_u8_x4 = c_compiler.try_compile(
2095         includes=["arm_neon.h"],
2096         body="uint8_t input[64] = {}; uint8x16x4_t output = vld1q_u8_x4(input);",
2097         check_msg="for vld1q_u8_x4 in arm_neon.h",
2098         flags=in_tree_jpeg_arm,
2099         when=in_tree_jpeg_arm,
2100     )
2102     set_config("LIBJPEG_TURBO_USE_NASM", True, when=jpeg_nasm)
2103     set_config("LIBJPEG_TURBO_SIMD_FLAGS", in_tree_jpeg)
2104     set_config("LIBJPEG_TURBO_HAVE_VLD1_S16_X3", jpeg_arm_neon_vld1_s16_x3)
2105     set_config("LIBJPEG_TURBO_HAVE_VLD1_U16_X2", jpeg_arm_neon_vld1_u16_x2)
2106     set_config("LIBJPEG_TURBO_HAVE_VLD1Q_U8_X4", jpeg_arm_neon_vld1q_u8_x4)
2107     set_config(
2108         "LIBJPEG_TURBO_NEON_INTRINSICS",
2109         jpeg_arm_neon_vld1_s16_x3
2110         & jpeg_arm_neon_vld1_u16_x2
2111         & jpeg_arm_neon_vld1q_u8_x4,
2112     )
2115 # PNG
2116 # ===
2117 with only_when(compile_environment):
2118     system_lib_option(
2119         "--with-system-png",
2120         nargs="?",
2121         help="Use system libpng",
2122     )
2124     @depends("--with-system-png")
2125     def deprecated_system_png_path(value):
2126         if len(value) == 1:
2127             die(
2128                 "--with-system-png=PATH is not supported anymore. Please use "
2129                 "--with-system-png and set any necessary pkg-config environment variable."
2130             )
2132     png = pkg_check_modules("MOZ_PNG", "libpng >= 1.6.35", when="--with-system-png")
2134     check_symbol(
2135         "png_get_acTL",
2136         flags=png.libs,
2137         onerror=lambda: die(
2138             "--with-system-png won't work because the system's libpng doesn't have APNG support"
2139         ),
2140         when="--with-system-png",
2141     )
2143     set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
2146 # FFmpeg's ffvpx configuration
2147 # ==============================================================
2148 with only_when(compile_environment):
2150     @depends(target)
2151     def libav_fft(target):
2152         return target.kernel in ("WINNT", "Darwin") or target.cpu == "x86_64"
2154     set_config("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2155     set_define("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2158 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
2159 with only_when(compile_environment | artifact_builds):
2161     @depends(target)
2162     def ffvpx(target):
2163         enable = use_nasm = True
2164         flac_only = False
2165         flags = []
2167         if target.kernel == "WINNT":
2168             if target.cpu == "x86":
2169                 # 32-bit windows need to prefix symbols with an underscore.
2170                 flags = ["-DPIC", "-DWIN32", "-DPREFIX", "-Pconfig_win32.asm"]
2171             elif target.cpu == "x86_64":
2172                 flags = [
2173                     "-D__x86_64__",
2174                     "-DPIC",
2175                     "-DWIN64",
2176                     "-DMSVC",
2177                     "-Pconfig_win64.asm",
2178                 ]
2179             elif target.cpu == "aarch64":
2180                 flags = ["-DPIC", "-DWIN64"]
2181                 use_nasm = False
2182         elif target.kernel == "Darwin":
2183             # 32/64-bit macosx assemblers need to prefix symbols with an
2184             # underscore.
2185             flags = ["-DPIC", "-DMACHO", "-DPREFIX"]
2186             if target.cpu == "x86_64":
2187                 flags += [
2188                     "-D__x86_64__",
2189                     "-Pconfig_darwin64.asm",
2190                 ]
2191             elif target.cpu == "aarch64":
2192                 use_nasm = False
2193         elif target.cpu == "x86_64":
2194             flags = ["-D__x86_64__", "-DPIC", "-DELF", "-Pconfig_unix64.asm"]
2195         elif target.cpu in ("x86", "arm", "aarch64"):
2196             flac_only = True
2197         else:
2198             enable = False
2200         if flac_only or not enable:
2201             use_nasm = False
2203         return namespace(
2204             enable=enable,
2205             use_nasm=use_nasm,
2206             flac_only=flac_only,
2207             flags=flags,
2208         )
2210     @depends(when=ffvpx.use_nasm)
2211     def ffvpx_nasm():
2212         # nasm 2.10 for AVX-2 support.
2213         return namespace(version="2.10", what="FFVPX")
2215     # ffvpx_nasm can't indirectly depend on vpx_as_flags, because it depends
2216     # on a compiler test, so we have to do a little bit of dance here.
2217     @depends(ffvpx, vpx_as_flags, target)
2218     def ffvpx(ffvpx, vpx_as_flags, target):
2219         if ffvpx and vpx_as_flags and target.cpu in ("arm", "aarch64"):
2220             ffvpx.flags.extend(vpx_as_flags)
2221         return ffvpx
2223     set_config("MOZ_FFVPX", True, when=ffvpx.enable)
2224     set_define("MOZ_FFVPX", True, when=ffvpx.enable)
2225     set_config("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2226     set_define("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2227     set_config("FFVPX_ASFLAGS", ffvpx.flags)
2228     set_config("FFVPX_USE_NASM", True, when=ffvpx.use_nasm)
2231 # nasm detection
2232 # ==============================================================
2233 @depends(dav1d_nasm, vpx_nasm, jpeg_nasm, ffvpx_nasm, when=compile_environment)
2234 def need_nasm(*requirements):
2235     requires = {
2236         x.what: x.version if hasattr(x, "version") else True for x in requirements if x
2237     }
2238     if requires:
2239         items = sorted(requires.keys())
2240         if len(items) > 1:
2241             what = " and ".join((", ".join(items[:-1]), items[-1]))
2242         else:
2243             what = items[0]
2244         versioned = {k: v for (k, v) in requires.items() if v is not True}
2245         return namespace(what=what, versioned=versioned)
2248 nasm = check_prog(
2249     "NASM",
2250     ["nasm"],
2251     allow_missing=True,
2252     bootstrap="nasm",
2253     when=need_nasm,
2257 @depends(nasm, need_nasm.what)
2258 def check_nasm(nasm, what):
2259     if not nasm and what:
2260         die("Nasm is required to build with %s, but it was not found." % what)
2261     return nasm
2264 @depends_if(check_nasm)
2265 @checking("nasm version")
2266 def nasm_version(nasm):
2267     version = (
2268         check_cmd_output(nasm, "-v", onerror=lambda: die("Failed to get nasm version."))
2269         .splitlines()[0]
2270         .split()[2]
2271     )
2272     return Version(version)
2275 @depends(nasm_version, need_nasm.versioned, when=need_nasm.versioned)
2276 def check_nasm_version(nasm_version, versioned):
2277     by_version = sorted(versioned.items(), key=lambda x: x[1])
2278     what, version = by_version[-1]
2279     if nasm_version < version:
2280         die(
2281             "Nasm version %s or greater is required to build with %s." % (version, what)
2282         )
2283     return nasm_version
2286 @depends(target, when=check_nasm_version)
2287 def nasm_asflags(target):
2288     asflags = {
2289         ("OSX", "x86"): ["-f", "macho32"],
2290         ("OSX", "x86_64"): ["-f", "macho64"],
2291         ("WINNT", "x86"): ["-f", "win32"],
2292         ("WINNT", "x86_64"): ["-f", "win64"],
2293     }.get((target.os, target.cpu), None)
2294     if asflags is None:
2295         # We're assuming every x86 platform we support that's
2296         # not Windows or Mac is ELF.
2297         if target.cpu == "x86":
2298             asflags = ["-f", "elf32"]
2299         elif target.cpu == "x86_64":
2300             asflags = ["-f", "elf64"]
2301     return asflags
2304 set_config("NASM_ASFLAGS", nasm_asflags)
2307 # ANGLE OpenGL->D3D translator for WebGL
2308 # ==============================================================
2310 with only_when(compile_environment & target_is_windows):
2312     def d3d_compiler_dll_result(value):
2313         if not value.path:
2314             return "provided by the OS"
2315         return value.path
2317     @depends(target, valid_windows_sdk_dir, fxc)
2318     @checking("for D3D compiler DLL", d3d_compiler_dll_result)
2319     @imports("os.path")
2320     def d3d_compiler_dll(target, windows_sdk_dir, fxc):
2321         suffix = {
2322             "x86_64": "x64",
2323         }.get(target.cpu, target.cpu)
2325         name = "d3dcompiler_47.dll"
2327         if target.cpu == "aarch64":
2328             # AArch64 Windows comes with d3dcompiler_47.dll installed
2329             return namespace(name=name, path=None)
2331         if windows_sdk_dir:
2332             path = os.path.join(windows_sdk_dir.path, "Redist", "D3D", suffix, name)
2333             error_extra = "in Windows SDK at {}".format(windows_sdk_dir.path)
2334         else:
2335             path = os.path.join(os.path.dirname(fxc), name)
2336             error_extra = "alongside FXC at {}".format(fxc)
2338         if os.path.exists(path):
2339             return namespace(name=name, path=path)
2340         die("Could not find {} {}".format(name, error_extra))
2342     set_config("MOZ_ANGLE_RENDERER", True)
2343     set_config(
2344         "MOZ_D3DCOMPILER_VISTA_DLL", d3d_compiler_dll.name, when=d3d_compiler_dll.path
2345     )
2346     set_config("MOZ_D3DCOMPILER_VISTA_DLL_PATH", d3d_compiler_dll.path)
2348 # Remoting protocol support
2349 # ==============================================================
2352 @depends(toolkit)
2353 def has_remote(toolkit):
2354     if toolkit in ("gtk", "windows", "cocoa"):
2355         return True
2358 set_config("MOZ_HAS_REMOTE", has_remote)
2359 set_define("MOZ_HAS_REMOTE", has_remote)
2361 # RLBox Library Sandboxing wasm support
2362 # ==============================================================
2365 def wasm_sandboxing_libraries():
2366     return (
2367         "graphite",
2368         "ogg",
2369         "hunspell",
2370         "expat",
2371         "woff2",
2372     )
2375 @depends(dependable(wasm_sandboxing_libraries))
2376 def default_wasm_sandboxing_libraries(libraries):
2377     non_default_libs = set()
2379     return tuple(l for l in libraries if l not in non_default_libs)
2382 option(
2383     "--with-wasm-sandboxed-libraries",
2384     env="WASM_SANDBOXED_LIBRARIES",
2385     help="{Enable wasm sandboxing for the selected libraries|Disable wasm sandboxing}",
2386     nargs="+",
2387     choices=dependable(wasm_sandboxing_libraries),
2388     default=default_wasm_sandboxing_libraries,
2392 @depends("--with-wasm-sandboxed-libraries")
2393 def requires_wasm_sandboxing(libraries):
2394     if libraries:
2395         return True
2398 set_config("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2399 set_define("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2401 with only_when(requires_wasm_sandboxing & compile_environment):
2402     option(
2403         "--with-wasi-sysroot",
2404         env="WASI_SYSROOT",
2405         nargs=1,
2406         help="Path to wasi sysroot for wasm sandboxing",
2407     )
2409     @depends("--with-wasi-sysroot", requires_wasm_sandboxing)
2410     def bootstrap_wasi_sysroot(wasi_sysroot, requires_wasm_sandboxing):
2411         return requires_wasm_sandboxing and not wasi_sysroot
2413     @depends(
2414         "--with-wasi-sysroot",
2415         bootstrap_path("sysroot-wasm32-wasi", when=bootstrap_wasi_sysroot),
2416         "--with-wasm-sandboxed-libraries",
2417     )
2418     @imports("os")
2419     def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot, sandboxed_libs):
2420         if not wasi_sysroot:
2421             if not bootstrapped_sysroot:
2422                 suggest_disable = ""
2423                 if sandboxed_libs.origin == "default":
2424                     suggest_disable = (
2425                         " Or build with --without-wasm-sandboxed-libraries."
2426                     )
2427                 die(
2428                     "Cannot find a wasi sysroot. Please give its location with "
2429                     "--with-wasi-sysroot." + suggest_disable
2430                 )
2431             return bootstrapped_sysroot
2433         wasi_sysroot = wasi_sysroot[0]
2434         if not os.path.isdir(wasi_sysroot):
2435             die("Argument to --with-wasi-sysroot must be a directory")
2436         if not os.path.isabs(wasi_sysroot):
2437             die("Argument to --with-wasi-sysroot must be an absolute path")
2439         return wasi_sysroot
2441     set_config("WASI_SYSROOT", wasi_sysroot)
2443     def wasm_compiler_with_flags(compiler, sysroot):
2444         if not sysroot:
2445             return
2446         elif compiler:
2447             return (
2448                 compiler.wrapper
2449                 + [compiler.compiler]
2450                 + compiler.flags
2451                 + ["--sysroot=%s" % sysroot]
2452             )
2454     wasm_cc = compiler("C", wasm, other_compiler=c_compiler)
2456     @depends(wasm_cc, wasi_sysroot)
2457     def wasm_cc_with_flags(wasm_cc, wasi_sysroot):
2458         return wasm_compiler_with_flags(wasm_cc, wasi_sysroot)
2460     set_config("WASM_CC", wasm_cc_with_flags)
2462     wasm_cxx = compiler(
2463         "C++",
2464         wasm,
2465         c_compiler=wasm_cc,
2466         other_compiler=cxx_compiler,
2467         other_c_compiler=c_compiler,
2468     )
2470     @depends(wasm_cxx, wasi_sysroot)
2471     def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot):
2472         return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot)
2474     set_config("WASM_CXX", wasm_cxx_with_flags)
2476     wasm_compile_flags = dependable(["-fno-exceptions", "-fno-strict-aliasing"])
2477     option(env="WASM_CFLAGS", nargs=1, help="Options to pass to WASM_CC")
2479     @depends("WASM_CFLAGS", wasm_compile_flags)
2480     def wasm_cflags(value, wasm_compile_flags):
2481         if value:
2482             return wasm_compile_flags + value
2483         else:
2484             return wasm_compile_flags
2486     set_config("WASM_CFLAGS", wasm_cflags)
2488     option(env="WASM_CXXFLAGS", nargs=1, help="Options to pass to WASM_CXX")
2490     @depends("WASM_CXXFLAGS", wasm_compile_flags)
2491     def wasm_cxxflags(value, wasm_compile_flags):
2492         if value:
2493             return wasm_compile_flags + value
2494         else:
2495             return wasm_compile_flags
2497     set_config("WASM_CXXFLAGS", wasm_cxxflags)
2500 @depends("--with-wasm-sandboxed-libraries")
2501 def wasm_sandboxing(libraries):
2502     if not libraries:
2503         return
2505     return namespace(**{name: True for name in libraries})
2508 @template
2509 def wasm_sandboxing_config_defines():
2510     for lib in wasm_sandboxing_libraries():
2511         set_config(
2512             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2513         )
2514         set_define(
2515             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2516         )
2519 wasm_sandboxing_config_defines()
2522 # new XULStore implementation
2523 # ==============================================================
2526 @depends(milestone)
2527 def new_xulstore(milestone):
2528     if milestone.is_nightly:
2529         return True
2532 set_config("MOZ_NEW_XULSTORE", True, when=new_xulstore)
2533 set_define("MOZ_NEW_XULSTORE", True, when=new_xulstore)
2536 # new Notification Store implementation
2537 # ==============================================================
2540 @depends(milestone)
2541 def new_notification_store(milestone):
2542     if milestone.is_nightly:
2543         return True
2546 set_config("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2547 set_define("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2550 # Glean SDK Integration Crate
2551 # ==============================================================
2554 @depends(target)
2555 def glean_android(target):
2556     return target.os == "Android"
2559 set_config("MOZ_GLEAN_ANDROID", True, when=glean_android)
2560 set_define("MOZ_GLEAN_ANDROID", True, when=glean_android)
2563 # dump_syms
2564 # ==============================================================
2566 check_prog(
2567     "DUMP_SYMS",
2568     ["dump_syms"],
2569     allow_missing=True,
2570     bootstrap="dump_syms",
2571     when=compile_environment,
2575 @depends(valid_windows_sdk_dir, host)
2576 @imports(_from="os", _import="environ")
2577 def pdbstr_paths(valid_windows_sdk_dir, host):
2578     if not valid_windows_sdk_dir:
2579         return
2581     vc_host = {
2582         "x86": "x86",
2583         "x86_64": "x64",
2584     }.get(host.cpu)
2586     return [
2587         environ["PATH"],
2588         os.path.join(valid_windows_sdk_dir.path, "Debuggers", vc_host, "srcsrv"),
2589     ]
2592 check_prog(
2593     "PDBSTR",
2594     ["pdbstr.exe"],
2595     allow_missing=True,
2596     when=compile_environment & target_is_windows,
2597     paths=pdbstr_paths,
2598     allow_spaces=True,
2602 @depends("MOZ_AUTOMATION", c_compiler)
2603 def allow_missing_winchecksec(automation, c_compiler):
2604     if not automation:
2605         return True
2606     if c_compiler and c_compiler.type != "clang-cl":
2607         return True
2610 check_prog(
2611     "WINCHECKSEC",
2612     ["winchecksec.exe", "winchecksec"],
2613     bootstrap="winchecksec",
2614     allow_missing=allow_missing_winchecksec,
2615     when=compile_environment & target_is_windows,
2618 # Fork server
2619 @depends(target, build_project)
2620 def forkserver_default(target, build_project):
2621     return build_project == "browser" and (
2622         (target.os == "GNU" and target.kernel == "Linux")
2623         or target.os == "FreeBSD"
2624         or target.os == "OpenBSD"
2625     )
2628 option(
2629     "--enable-forkserver",
2630     default=forkserver_default,
2631     env="MOZ_ENABLE_FORKSERVER",
2632     help="{Enable|Disable} fork server",
2636 @depends("--enable-forkserver", target)
2637 def forkserver_flag(value, target):
2638     if (
2639         target.os == "Android"
2640         or (target.os == "GNU" and target.kernel == "Linux")
2641         or target.os == "FreeBSD"
2642         or target.os == "OpenBSD"
2643     ):
2644         return bool(value)
2645     pass
2648 set_config("MOZ_ENABLE_FORKSERVER", forkserver_flag)
2649 set_define("MOZ_ENABLE_FORKSERVER", forkserver_flag, forkserver_flag)
2651 # Crash Reporter
2652 # ==============================================================
2654 with only_when(compile_environment & target_has_linux_kernel):
2655     # Check if we need to use the breakpad_getcontext fallback.
2656     getcontext = check_symbol("getcontext")
2657     set_config("HAVE_GETCONTEXT", getcontext)
2658     set_define("HAVE_GETCONTEXT", getcontext)
2660 # NSS
2661 # ==============================================================
2662 include("../build/moz.configure/nss.configure")
2665 # Enable or disable running in background task mode: headless for
2666 # periodic, short-lived, maintenance tasks.
2667 # ==============================================================================
2668 option(
2669     "--disable-backgroundtasks",
2670     help="Disable running in background task mode",
2672 set_config("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2673 set_define("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2676 # Update-related programs: updater, maintenance service, update agent,
2677 # default browser agent.
2678 # ==============================================================
2679 include("../build/moz.configure/update-programs.configure")
2682 # Mobile optimizations
2683 # ==============================================================
2684 option(
2685     "--enable-mobile-optimize",
2686     default=target_is_android,
2687     help="{Enable|Disable} mobile optimizations",
2690 set_define("MOZ_GFX_OPTIMIZE_MOBILE", True, when="--enable-mobile-optimize")
2691 # We ignore "paint will resample" on mobile for performance.
2692 # We may want to revisit this later.
2693 set_define("MOZ_IGNORE_PAINT_WILL_RESAMPLE", True, when="--enable-mobile-optimize")
2695 # Pref extensions
2696 # ==============================================================
2697 option("--disable-pref-extensions", help="Disable pref extensions such as autoconfig")
2698 set_config("MOZ_PREF_EXTENSIONS", True, when="--enable-pref-extensions")
2700 # Offer a way to disable the startup cache
2701 # ==============================================================
2702 option("--disable-startupcache", help="Disable startup cache")
2705 @depends("--enable-startupcache")
2706 def enable_startupcache(value):
2707     if value:
2708         return True
2711 set_define(
2712     "MOZ_DISABLE_STARTUPCACHE", True, when=depends(enable_startupcache)(lambda x: not x)
2716 # Branding
2717 # ==============================================================
2718 option(
2719     env="MOZ_APP_REMOTINGNAME",
2720     nargs=1,
2721     help="Used for the internal program name, which affects profile name "
2722     "and remoting. If not set, defaults to MOZ_APP_NAME if the update channel "
2723     "is release, and MOZ_APP_NAME-MOZ_UPDATE_CHANNEL otherwise.",
2727 @depends("MOZ_APP_REMOTINGNAME", moz_app_name, update_channel)
2728 def moz_app_remotingname(value, moz_app_name, update_channel):
2729     if value:
2730         return value[0]
2731     if update_channel == "release":
2732         return moz_app_name
2733     return moz_app_name + "-" + update_channel
2736 set_config("MOZ_APP_REMOTINGNAME", moz_app_remotingname)
2738 option(
2739     env="ANDROID_PACKAGE_NAME",
2740     nargs=1,
2741     help="Name of the Android package (default org.mozilla.$MOZ_APP_NAME)",
2745 @depends("ANDROID_PACKAGE_NAME", moz_app_name)
2746 def android_package_name(value, moz_app_name):
2747     if value:
2748         return value[0]
2749     if moz_app_name == "fennec":
2750         return "org.mozilla.fennec_aurora"
2751     return "org.mozilla.%s" % moz_app_name
2754 set_config("ANDROID_PACKAGE_NAME", android_package_name)
2757 # Miscellaneous options
2758 # ==============================================================
2759 option(env="MOZ_WINCONSOLE", nargs="?", help="Whether we can create a console window.")
2760 set_define("MOZ_WINCONSOLE", True, when=depends("MOZ_WINCONSOLE")(lambda x: x))
2763 # Alternative Crashreporter setting
2764 option(
2765     "--with-crashreporter-url",
2766     env="MOZ_CRASHREPORTER_URL",
2767     default="https://crash-reports.mozilla.com/",
2768     nargs=1,
2769     help="Set an alternative crashreporter url",
2772 set_config(
2773     "MOZ_CRASHREPORTER_URL",
2774     depends("--with-crashreporter-url")(lambda x: x[0].rstrip("/")),
2778 # Crash reporter options
2779 # ==============================================================
2780 @depends(target)
2781 def oxidized_breakpad(target):
2782     if target.kernel == "Linux" and target.os != "Android":
2783         return target.cpu in ("x86", "x86_64")
2784     return False
2787 set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2788 set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2791 # Wine
2792 # ==============================================================
2793 @depends(target, host)
2794 def want_wine(target, host):
2795     return target.kernel == "WINNT" and host.kernel != "WINNT"
2798 wine = check_prog(
2799     "WINE",
2800     ["wine64", "wine"],
2801     when=want_wine,
2802     bootstrap="wine/bin",
2805 # DOM Streams
2806 # ==============================================================
2807 # Set this to true so the JS engine knows we're doing a browser build.
2808 set_config("MOZ_DOM_STREAMS", True)
2809 set_define("MOZ_DOM_STREAMS", True)
2811 # libevent
2812 # ==============================================================
2813 with only_when(compile_environment):
2814     system_lib_option(
2815         "--with-system-libevent",
2816         nargs="?",
2817         help="Use system libevent",
2818     )
2820     @depends("--with-system-libevent")
2821     def deprecated_system_libevent_path(value):
2822         if len(value) == 1:
2823             die(
2824                 "--with-system-libevent=PATH is not supported anymore. Please use "
2825                 "--with-system-libevent and set any necessary pkg-config environment variable."
2826             )
2828     pkg_check_modules("MOZ_LIBEVENT", "libevent", when="--with-system-libevent")
2830     set_config("MOZ_SYSTEM_LIBEVENT", True, when="--with-system-libevent")
2833 # Crash reporting
2834 # ==============================================================
2835 @depends(target, developer_options, artifact_builds)
2836 def crashreporter_default(target, developer_options, artifacts):
2837     if target.kernel in ("WINNT", "Darwin"):
2838         return True
2839     if target.kernel == "Linux" and target.cpu in ("x86", "x86_64", "arm", "aarch64"):
2840         # The crash reporter prevents crash stacktraces to be logged in the
2841         # logs on Android, so we leave it out by default in developer builds.
2842         return target.os != "Android" or not developer_options or artifacts
2845 option(
2846     "--enable-crashreporter",
2847     default=crashreporter_default,
2848     help="{Enable|Disable} crash reporting",
2852 set_config("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2853 set_define("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2854 add_old_configure_assignment("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2856 with only_when(compile_environment):
2857     with only_when("--enable-crashreporter"):
2858         pkg_check_modules(
2859             "MOZ_GTHREAD",
2860             "gthread-2.0",
2861             when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2862         )
2864         set_config(
2865             "MOZ_CRASHREPORTER_INJECTOR",
2866             True,
2867             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2868         )
2869         set_define(
2870             "MOZ_CRASHREPORTER_INJECTOR",
2871             True,
2872             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2873         )
2876 # Gtk+
2877 # ==============================================================
2878 with only_when(toolkit_gtk):
2879     pkg_check_modules(
2880         "MOZ_GTK3",
2881         "gtk+-3.0 >= 3.14.0 gtk+-unix-print-3.0 glib-2.0 gobject-2.0 gio-unix-2.0",
2882     )
2884     set_define("GDK_VERSION_MIN_REQUIRED", "GDK_VERSION_3_14")
2885     set_define("GDK_VERSION_MAX_ALLOWED", "GDK_VERSION_3_14")
2887     pkg_check_modules("GLIB", "glib-2.0 >= 2.42 gobject-2.0")
2889     set_define("GLIB_VERSION_MIN_REQUIRED", "GLIB_VERSION_2_42")
2890     set_define("GLIB_VERSION_MAX_ALLOWED", "GLIB_VERSION_2_42")
2892     set_define("MOZ_ACCESSIBILITY_ATK", True, when=accessibility)
2894 # DBus
2895 # ==============================================================
2896 with only_when(toolkit_gtk):
2897     option("--disable-dbus", help="Disable dbus support")
2899     with only_when("--enable-dbus"):
2900         pkg_check_modules("MOZ_DBUS", "dbus-1 >= 0.60")
2901         pkg_check_modules("MOZ_DBUS_GLIB", "dbus-glib-1 >= 0.60")
2903         set_config("MOZ_ENABLE_DBUS", True)
2904         set_define("MOZ_ENABLE_DBUS", True)
2907 # Necko's wifi scanner
2908 # ==============================================================
2909 @depends(target)
2910 def necko_wifi_when(target):
2911     return target.os in ("WINNT", "OSX", "DragonFly", "FreeBSD") or (
2912         target.kernel == "Linux" and target.os == "GNU"
2913     )
2916 option("--disable-necko-wifi", help="Disable necko wifi scanner", when=necko_wifi_when)
2918 set_config("NECKO_WIFI", True, when="--enable-necko-wifi")
2919 set_define("NECKO_WIFI", True, when="--enable-necko-wifi")
2922 @depends(
2923     depends("--enable-necko-wifi", when=necko_wifi_when)(lambda x: x),
2924     depends("--enable-dbus", when=toolkit_gtk)(lambda x: x),
2925     when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2927 def necko_wifi_dbus(necko_wifi, dbus):
2928     if necko_wifi and not dbus:
2929         die(
2930             "Necko WiFi scanning needs DBus on your platform, remove --disable-dbus"
2931             " or use --disable-necko-wifi"
2932         )
2933     return necko_wifi and dbus
2936 set_config("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
2939 # Frontend JS debug mode
2940 # ==============================================================
2941 option("--enable-debug-js-modules", help="Enable debug mode for frontend JS libraries")
2943 set_config("DEBUG_JS_MODULES", True, when="--enable-debug-js-modules")
2946 # moz_dump_painting
2947 # ==============================================================
2948 option("--enable-dump-painting", help="Enable paint debugging")
2950 set_define(
2951     "MOZ_DUMP_PAINTING",
2952     True,
2953     when=depends("--enable-dump-painting", "--enable-debug")(
2954         lambda painting, debug: painting or debug
2955     ),
2957 set_define("MOZ_LAYERS_HAVE_LOG", True, when="--enable-dump-painting")
2960 # libproxy support
2961 # ==============================================================
2962 with only_when(toolkit_gtk):
2963     system_lib_option("--enable-libproxy", help="Enable libproxy support")
2965     with only_when("--enable-libproxy"):
2966         pkg_check_modules("MOZ_LIBPROXY", "libproxy-1.0")
2968         set_config("MOZ_ENABLE_LIBPROXY", True)
2969         set_define("MOZ_ENABLE_LIBPROXY", True)
2972 # Enable runtime logging
2973 # ==============================================================
2974 set_define("MOZ_LOGGING", True)
2975 set_define("FORCE_PR_LOG", True)
2977 # This will enable logging of addref, release, ctor, dtor.
2978 # ==============================================================
2979 option(
2980     "--enable-logrefcnt",
2981     default=moz_debug,
2982     help="{Enable|Disable} logging of refcounts",
2985 set_define("NS_BUILD_REFCNT_LOGGING", True, when="--enable-logrefcnt")
2988 # NegotiateAuth
2989 # ==============================================================
2990 option("--disable-negotiateauth", help="Disable GSS-API negotiation")
2992 set_config("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
2993 set_define("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
2996 # Parental control
2997 # ==============================================================
2998 option("--disable-parental-controls", help="Do not build parental controls")
3000 set_config(
3001     "MOZ_DISABLE_PARENTAL_CONTROLS",
3002     True,
3003     when=depends("--enable-parental-controls")(lambda x: not x),
3005 set_define(
3006     "MOZ_DISABLE_PARENTAL_CONTROLS",
3007     True,
3008     when=depends("--enable-parental-controls")(lambda x: not x),
3012 # Sandboxing support
3013 # ==============================================================
3014 @depends(target, tsan, asan)
3015 def sandbox_default(target, tsan, asan):
3016     # Only enable the sandbox by default on Linux, OpenBSD, macOS, and Windows
3017     if target.kernel == "Linux" and target.os == "GNU":
3018         # Bug 1182565: TSan conflicts with sandboxing on Linux.
3019         # Bug 1287971: LSan also conflicts with sandboxing on Linux.
3020         if tsan or asan:
3021             return False
3022         # Linux sandbox is only available on x86{,_64} and arm{,64}.
3023         return target.cpu in ("x86", "x86_64", "arm", "aarch64")
3024     return target.kernel in ("WINNT", "Darwin", "OpenBSD")
3027 option(
3028     "--enable-sandbox",
3029     default=sandbox_default,
3030     help="{Enable|Disable} sandboxing support",
3033 set_config("MOZ_SANDBOX", True, when="--enable-sandbox")
3034 set_define("MOZ_SANDBOX", True, when="--enable-sandbox")
3037 # Searching of system directories for extensions.
3038 # ==============================================================
3039 # Note: this switch is meant to be used for test builds whose behavior should
3040 # not depend on what happens to be installed on the local machine.
3041 option(
3042     "--disable-system-extension-dirs",
3043     help="Disable searching system- and account-global directories for extensions"
3044     " of any kind; use only profile-specific extension directories",
3047 set_define("ENABLE_SYSTEM_EXTENSION_DIRS", True, when="--enable-system-extension-dirs")
3050 # Pixman
3051 # ==============================================================
3052 with only_when(compile_environment):
3053     system_lib_option(
3054         "--enable-system-pixman", help="Use system pixman (located with pkgconfig)"
3055     )
3057     @depends("--enable-system-pixman")
3058     def in_tree_pixman(pixman):
3059         return not pixman
3061     set_config("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3062     set_define("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3064     pkg_check_modules("MOZ_PIXMAN", "pixman-1 >= 0.36.0", when="--enable-system-pixman")
3065     # Set MOZ_PIXMAN_CFLAGS to an explicit empty value when --enable-system-pixman is *not* used,
3066     # for layout/style/extra-bindgen-flags
3067     set_config("MOZ_PIXMAN_CFLAGS", [], when=in_tree_pixman)
3070 # Universalchardet
3071 # ==============================================================
3072 with only_when(compile_environment):
3073     option("--disable-universalchardet", help="Disable universal encoding detection")
3075     set_config("MOZ_UNIVERSALCHARDET", True, when="--enable-universalchardet")
3078 # Disable zipwriter
3079 # ==============================================================
3080 with only_when(compile_environment):
3081     option("--disable-zipwriter", help="Disable zipwriter component")
3083     set_config("MOZ_ZIPWRITER", True, when="--enable-zipwriter")
3086 # Location of the mozilla user directory
3087 # ==============================================================
3088 with only_when(compile_environment):
3090     @depends(target)
3091     def default_user_appdir(target):
3092         if target.kernel in ("WINNT", "Darwin"):
3093             return "Mozilla"
3094         return ".mozilla"
3096     option(
3097         "--with-user-appdir",
3098         nargs=1,
3099         default=default_user_appdir,
3100         help="Set user-specific appdir",
3101     )
3103     @depends("--with-user-appdir")
3104     def user_appdir(appdir):
3105         if not appdir:
3106             die("--without-user-appdir is not a valid option.")
3107         if "/" in appdir[0]:
3108             die("--with-user-appdir must be a single relative path.")
3109         return '"{}"'.format(appdir[0])
3111     set_define("MOZ_USER_DIR", user_appdir)
3114 # Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
3115 # ==============================================================
3116 with only_when(compile_environment):
3117     have_sin_len = c_compiler.try_compile(
3118         includes=["netinet/in.h"],
3119         body="struct sockaddr_in x; void *foo = (void*) &x.sin_len;",
3120         check_msg="for sin_len in struct sockaddr_in",
3121     )
3122     have_sin6_len = c_compiler.try_compile(
3123         includes=["netinet/in.h"],
3124         body="struct sockaddr_in6 x; void *foo = (void*) &x.sin6_len;",
3125         check_msg="for sin_len6 in struct sockaddr_in6",
3126     )
3127     set_define("HAVE_SIN_LEN", have_sin_len)
3128     set_define("HAVE_SIN6_LEN", have_sin6_len)
3129     # HAVE_CONN_LEN must be the same as HAVE_SIN_LEN and HAVE_SIN6_LEN
3130     set_define("HAVE_SCONN_LEN", have_sin_len & have_sin6_len)
3131     set_define(
3132         "HAVE_SA_LEN",
3133         c_compiler.try_compile(
3134             includes=["netinet/in.h"],
3135             body="struct sockaddr x; void *foo = (void*) &x.sa_len;",
3136             check_msg="for sa_len in struct sockaddr",
3137         ),
3138     )
3141 # Check for pthread_cond_timedwait_monotonic_np
3142 # ==============================================================
3143 with only_when(compile_environment):
3144     set_define(
3145         "HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC",
3146         c_compiler.try_compile(
3147             includes=["pthread.h"],
3148             body="pthread_cond_timedwait_monotonic_np(0, 0, 0);",
3149             # -Werror to catch any "implicit declaration" warning that means the function
3150             # is not supported.
3151             flags=["-Werror=implicit-function-declaration"],
3152             check_msg="for pthread_cond_timedwait_monotonic_np",
3153         ),
3154     )
3157 # Custom dynamic linker for Android
3158 # ==============================================================
3159 with only_when(target_has_linux_kernel & compile_environment):
3160     option(
3161         env="MOZ_LINKER",
3162         default=depends(target.os, when="--enable-jemalloc")(
3163             lambda os: os == "Android"
3164         ),
3165         help="{Enable|Disable} custom dynamic linker",
3166     )
3168     set_config("MOZ_LINKER", True, when="MOZ_LINKER")
3169     set_define("MOZ_LINKER", True, when="MOZ_LINKER")
3170     add_old_configure_assignment("MOZ_LINKER", True, when="MOZ_LINKER")
3172     moz_linker = depends(when="MOZ_LINKER")(lambda: True)
3175 # 32-bits ethtool_cmd.speed
3176 # ==============================================================
3177 with only_when(target_has_linux_kernel & compile_environment):
3178     set_config(
3179         "MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI",
3180         c_compiler.try_compile(
3181             includes=["linux/ethtool.h"],
3182             body="struct ethtool_cmd cmd; cmd.speed_hi = 0;",
3183             check_msg="for 32-bits ethtool_cmd.speed",
3184         ),
3185     )
3187 # Gamepad support
3188 # ==============================================================
3189 check_header(
3190     "linux/joystick.h",
3191     onerror=lambda: die(
3192         "Can't find header linux/joystick.h, needed for gamepad support."
3193         " Please install Linux kernel headers."
3194     ),
3195     when=target_has_linux_kernel & compile_environment,
3198 # Smart card support
3199 # ==============================================================
3200 @depends(build_project)
3201 def disable_smart_cards(build_project):
3202     return build_project == "mobile/android"
3205 set_config("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3206 set_define("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3208 # Enable UniFFI fixtures
3209 # ==============================================================
3210 # These are used to test the uniffi-bindgen-gecko-js code generation.  They
3211 # should not be enabled in release builds.
3213 option(
3214     "--enable-uniffi-fixtures",
3215     help="Enable UniFFI Fixtures/Examples",
3218 set_config("MOZ_UNIFFI_FIXTURES", True, when="--enable-uniffi-fixtures")
3220 # Checks for library functions
3221 # ==============================================================
3222 with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
3223     set_define("HAVE_STAT64", check_symbol("stat64"))
3224     set_define("HAVE_LSTAT64", check_symbol("lstat64"))
3225     set_define("HAVE_TRUNCATE64", check_symbol("truncate64"))
3226     set_define("HAVE_STATVFS64", check_symbol("statvfs64"))
3227     set_define("HAVE_STATVFS", check_symbol("statvfs"))
3228     set_define("HAVE_STATFS64", check_symbol("statfs64"))
3229     set_define("HAVE_STATFS", check_symbol("statfs"))
3230     set_define("HAVE_LUTIMES", check_symbol("lutimes"))
3231     set_define("HAVE_POSIX_FADVISE", check_symbol("posix_fadvise"))
3232     set_define("HAVE_POSIX_FALLOCATE", check_symbol("posix_fallocate"))
3234     set_define("HAVE_ARC4RANDOM", check_symbol("arc4random"))
3235     set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf"))
3236     set_define("HAVE_MALLINFO", check_symbol("mallinfo"))
3238 # System policies
3239 # ==============================================================
3241 option(
3242     "--disable-system-policies",
3243     help="Disable reading policies from Windows registry, macOS's file system attributes, and /etc/firefox",
3246 set_config("MOZ_SYSTEM_POLICIES", True, when="--enable-system-policies")