Bug 1799258 - span_iterator::difference_type s/index_type/ptrdiff/. r=bradwerth
[gecko.git] / toolkit / moz.configure
blobce97db43fd3df70ba0e03e1528221290b74e912e
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 == "NetBSD":
204         return ("sunaudio",)
205     elif target.os == "SunOS":
206         return ("sunaudio",)
207     elif target.os == "WINNT":
208         return ("wasapi",)
209     else:
210         return ("pulseaudio",)
213 option(
214     "--enable-audio-backends",
215     nargs="+",
216     choices=(
217         "aaudio",
218         "alsa",
219         "audiounit",
220         "jack",
221         "opensl",
222         "oss",
223         "pulseaudio",
224         "sndio",
225         "sunaudio",
226         "wasapi",
227     ),
228     default=audio_backends_default,
229     help="{Enable|Disable} various cubeb backends",
233 @depends("--enable-audio-backends", target)
234 def imply_aaudio(values, target):
235     if any("aaudio" in value for value in values) and target.os != "Android":
236         die("Cannot enable AAudio on %s", target.os)
237     return any("aaudio" in value for value in values) or None
240 @depends("--enable-audio-backends", target)
241 def imply_alsa(values, target):
242     if (
243         any("alsa" in value for value in values)
244         and target.kernel != "Linux"
245         and target.os != "FreeBSD"
246     ):
247         die("Cannot enable ALSA on %s", target.os)
248     return any("alsa" in value for value in values) or None
251 @depends("--enable-audio-backends", target)
252 def imply_audiounit(values, target):
253     if (
254         any("audiounit" in value for value in values)
255         and target.os != "OSX"
256         and target.kernel != "Darwin"
257     ):
258         die("Cannot enable AudioUnit on %s", target.os)
259     return any("audiounit" in value for value in values) or None
262 @depends("--enable-audio-backends")
263 def imply_jack(values):
264     return any("jack" in value for value in values) or None
267 @depends("--enable-audio-backends", target)
268 def imply_opensl(values, target):
269     if any("opensl" in value for value in values) and target.os != "Android":
270         die("Cannot enable OpenSL on %s", target.os)
271     return any("opensl" in value for value in values) or None
274 @depends("--enable-audio-backends", target)
275 def imply_oss(values, target):
276     if any("oss" in value for value in values) and (
277         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
278     ):
279         die("Cannot enable OSS on %s", target.os)
280     return any("oss" in value for value in values) or None
283 @depends("--enable-audio-backends", target)
284 def imply_pulseaudio(values, target):
285     if any("pulseaudio" in value for value in values) and (
286         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
287     ):
288         die("Cannot enable PulseAudio on %s", target.os)
289     return any("pulseaudio" in value for value in values) or None
292 @depends("--enable-audio-backends", target)
293 def imply_sndio(values, target):
294     if any("sndio" in value for value in values) and (
295         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
296     ):
297         die("Cannot enable sndio on %s", target.os)
298     return any("sndio" in value for value in values) or None
301 @depends("--enable-audio-backends", target)
302 def imply_sunaudio(values, target):
303     if any("sunaudio" in value for value in values) and (
304         target.os != "NetBSD" and target.os != "SunOS"
305     ):
306         die("Cannot enable sunaudio on %s", target.os)
307     return any("sunaudio" in value for value in values) or None
310 @depends("--enable-audio-backends", target)
311 def imply_wasapi(values, target):
312     if any("wasapi" in value for value in values) and target.os != "WINNT":
313         die("Cannot enable WASAPI on %s", target.os)
314     return any("wasapi" in value for value in values) or None
317 set_config("MOZ_AAUDIO", imply_aaudio, when="--enable-audio-backends")
319 imply_option("--enable-alsa", imply_alsa, reason="--enable-audio-backends")
321 set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")
323 imply_option("--enable-jack", imply_jack, reason="--enable-audio-backends")
325 set_config("MOZ_OPENSL", imply_opensl, when="--enable-audio-backends")
327 set_config("MOZ_OSS", imply_oss, when="--enable-audio-backends")
329 imply_option("--enable-pulseaudio", imply_pulseaudio, reason="--enable-audio-backends")
331 imply_option("--enable-sndio", imply_sndio, reason="--enable-audio-backends")
333 set_config("MOZ_SUNAUDIO", imply_sunaudio, when="--enable-audio-backends")
335 set_config("MOZ_WASAPI", imply_wasapi, when="--enable-audio-backends")
337 # ALSA cubeb backend
338 # ==============================================================
339 option("--enable-alsa", env="MOZ_ALSA", help="Enable ALSA audio backend.")
342 @depends("--enable-alsa", midir_linux_support)
343 def enable_alsa_or_midir_linux_support(alsa_enabled, midir_linux_support):
344     return alsa_enabled or midir_linux_support
347 pkg_check_modules("MOZ_ALSA", "alsa", when=enable_alsa_or_midir_linux_support)
349 set_config("MOZ_ALSA", True, when="--enable-alsa")
350 set_define("MOZ_ALSA", True, when="--enable-alsa")
352 # JACK cubeb backend
353 # ==============================================================
354 system_lib_option("--enable-jack", env="MOZ_JACK", help="Enable JACK audio backend.")
356 jack = pkg_check_modules("MOZ_JACK", "jack", when="--enable-jack")
358 set_config("MOZ_JACK", depends_if(jack)(lambda _: True))
360 # PulseAudio cubeb backend
361 # ==============================================================
362 option(
363     "--enable-pulseaudio",
364     env="MOZ_PULSEAUDIO",
365     help="{Enable|Disable} PulseAudio audio backend.",
368 pulseaudio = pkg_check_modules("MOZ_PULSEAUDIO", "libpulse", when="--enable-pulseaudio")
370 set_config("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
371 set_define("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
373 # sndio cubeb backend
374 # ==============================================================
375 system_lib_option("--enable-sndio", env="MOZ_SNDIO", help="Enable sndio audio backend.")
377 sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
379 set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
381 # Javascript engine
382 # ==============================================================
383 include("../js/moz.configure")
386 # NodeJS
387 # ==============================================================
388 include("../build/moz.configure/node.configure")
390 # JsonCpp
391 # ==============================================================
392 set_define("JSON_USE_EXCEPTION", 0)
394 # L10N
395 # ==============================================================
396 option("--with-l10n-base", nargs=1, env="L10NBASEDIR", help="Path to l10n repositories")
399 @depends("--with-l10n-base", "MOZ_AUTOMATION", build_environment)
400 @imports(_from="os.path", _import="isdir")
401 @imports(_from="os.path", _import="expanduser")
402 @imports(_from="os", _import="environ")
403 def l10n_base(value, automation, build_env):
404     if value:
405         path = value[0]
406         if not isdir(path):
407             die("Invalid value --with-l10n-base, %s doesn't exist", path)
408     elif automation:
409         path = os.path.join(build_env.topsrcdir, "../l10n-central")
410     else:
411         path = os.path.join(
412             environ.get(
413                 "MOZBUILD_STATE_PATH", expanduser(os.path.join("~", ".mozbuild"))
414             ),
415             "l10n-central",
416         )
417     return os.path.realpath(os.path.abspath(path))
420 set_config("L10NBASEDIR", l10n_base)
423 # Default toolkit
424 # ==============================================================
425 @depends(target)
426 def toolkit_choices(target):
427     if target.os == "WINNT":
428         return ("cairo-windows",)
429     elif target.os == "OSX":
430         return ("cairo-cocoa",)
431     elif target.os == "Android":
432         return ("cairo-android",)
433     else:
434         return (
435             "cairo-gtk3",
436             "cairo-gtk3-wayland",
437             "cairo-gtk3-wayland-only",
438             "cairo-gtk3-x11-wayland",
439         )
442 @depends(toolkit_choices)
443 def toolkit_default(choices):
444     return choices[0]
447 option(
448     "--enable-default-toolkit",
449     nargs=1,
450     choices=toolkit_choices,
451     default=toolkit_default,
452     help="Select default toolkit",
456 @depends("--enable-default-toolkit")
457 def full_toolkit(value):
458     if value:
459         return value[0]
462 @depends(full_toolkit)
463 def toolkit(toolkit):
464     if toolkit.startswith("cairo-gtk3"):
465         widget_toolkit = "gtk"
466     else:
467         widget_toolkit = toolkit.replace("cairo-", "")
468     return widget_toolkit
471 set_config("MOZ_WIDGET_TOOLKIT", toolkit)
472 add_old_configure_assignment("MOZ_WIDGET_TOOLKIT", toolkit)
475 @depends(toolkit)
476 def toolkit_define(toolkit):
477     if toolkit != "windows":
478         return "MOZ_WIDGET_%s" % toolkit.upper()
481 set_define(toolkit_define, True)
484 @depends(toolkit)
485 def toolkit_gtk(toolkit):
486     return toolkit == "gtk"
489 # Wayland support
490 # ==============================================================
491 wayland_headers = pkg_check_modules(
492     "MOZ_WAYLAND",
493     "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1 libdrm >= 2.4",
494     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3"),
495     when=toolkit_gtk,
499 @depends(wayland_headers, toolkit_gtk, artifact_builds)
500 def wayland_headers(wayland, toolkit_gtk, artifacts):
501     if toolkit_gtk and artifacts:
502         return True
503     return wayland
506 set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
507 set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
509 # GL Provider
510 # ==============================================================
511 option("--with-gl-provider", nargs=1, help="Set GL provider backend type")
514 @depends("--with-gl-provider")
515 def gl_provider(value):
516     if value:
517         return value[0]
520 @depends(gl_provider)
521 def gl_provider_define(provider):
522     if provider:
523         return "GLContextProvider%s" % provider
526 set_define("MOZ_GL_PROVIDER", gl_provider_define)
529 @depends(gl_provider, wayland_headers, toolkit_gtk)
530 def gl_default_provider(value, wayland, toolkit_gtk):
531     if value:
532         return value
533     elif wayland:
534         return "EGL"
535     elif toolkit_gtk:
536         return "GLX"
539 set_config("MOZ_GL_PROVIDER", gl_provider)
540 set_config("MOZ_GL_DEFAULT_PROVIDER", gl_default_provider)
543 @depends(gl_default_provider)
544 def gl_provider_define(provider):
545     if provider:
546         return "GL_PROVIDER_%s" % provider
549 set_define(gl_provider_define, True)
552 # PDF printing
553 # ==============================================================
554 @depends(toolkit)
555 def pdf_printing(toolkit):
556     if toolkit in ("windows", "gtk", "android"):
557         return True
560 set_config("MOZ_PDF_PRINTING", pdf_printing)
561 set_define("MOZ_PDF_PRINTING", pdf_printing)
564 # Event loop instrumentation
565 # ==============================================================
566 option(env="MOZ_INSTRUMENT_EVENT_LOOP", help="Force-enable event loop instrumentation")
569 @depends("MOZ_INSTRUMENT_EVENT_LOOP", toolkit)
570 def instrument_event_loop(value, toolkit):
571     if value or (
572         toolkit in ("windows", "gtk", "cocoa", "android") and value.origin == "default"
573     ):
574         return True
577 set_config("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
578 set_define("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
581 # Fontconfig Freetype
582 # ==============================================================
583 option(env="USE_FC_FREETYPE", help="Force-enable the use of fontconfig freetype")
586 @depends("USE_FC_FREETYPE", toolkit)
587 def fc_freetype(value, toolkit):
588     if value or (toolkit == "gtk" and value.origin == "default"):
589         return True
592 add_old_configure_assignment("USE_FC_FREETYPE", fc_freetype)
593 set_define("USE_FC_FREETYPE", fc_freetype)
595 # Pango
596 # ==============================================================
597 pkg_check_modules("MOZ_PANGO", "pango >= 1.22.0", when=toolkit_gtk)
599 # Fontconfig
600 # ==============================================================
601 fontconfig_info = pkg_check_modules(
602     "_FONTCONFIG", "fontconfig >= 2.7.0", when=fc_freetype
606 @depends(fc_freetype)
607 def check_for_freetype2(fc_freetype):
608     if fc_freetype:
609         return True
612 # Check for freetype2. Flags are combined with fontconfig flags.
613 freetype2_info = pkg_check_modules(
614     "_FT2", "freetype2 >= 9.10.3", when=check_for_freetype2
618 @depends(fontconfig_info, freetype2_info)
619 def freetype2_combined_info(fontconfig_info, freetype2_info):
620     if not freetype2_info:
621         return
622     if not fontconfig_info:
623         return freetype2_info
624     return namespace(
625         cflags=freetype2_info.cflags + fontconfig_info.cflags,
626         libs=freetype2_info.libs + fontconfig_info.libs,
627     )
630 set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
632 # Apple platform decoder support
633 # ==============================================================
634 @depends(toolkit)
635 def applemedia(toolkit):
636     if toolkit in ("cocoa", "uikit"):
637         return True
640 set_config("MOZ_APPLEMEDIA", applemedia)
641 set_define("MOZ_APPLEMEDIA", applemedia)
643 # Windows Media Foundation support
644 # ==============================================================
645 option("--disable-wmf", help="Disable support for Windows Media Foundation")
648 @depends("--disable-wmf", target, "--help")
649 def wmf(value, target, _):
650     enabled = bool(value)
651     if value.origin == "default":
652         # Enable Windows Media Foundation support by default.
653         # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
654         # guaranteed to have a recent-enough SDK to build WMF.
655         enabled = target.os == "WINNT"
656     if enabled and target.os != "WINNT":
657         die("Cannot enable Windows Media Foundation support on %s", target.os)
658     if enabled:
659         return True
662 @depends(c_compiler, when=wmf)
663 def wmfmediaengine(c_compiler):
664     return c_compiler and c_compiler.type == "clang-cl"
667 set_config("MOZ_WMF", wmf)
668 set_define("MOZ_WMF", wmf)
670 set_config("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
671 set_define("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
673 # FFmpeg H264/AAC Decoding Support
674 # ==============================================================
675 option("--disable-ffmpeg", help="Disable FFmpeg for fragmented H264/AAC decoding")
678 @depends("--disable-ffmpeg", target)
679 def ffmpeg(value, target):
680     enabled = bool(value)
681     if value.origin == "default":
682         enabled = target.os not in ("Android", "WINNT")
683     if enabled:
684         return True
687 set_config("MOZ_FFMPEG", ffmpeg)
688 set_define("MOZ_FFMPEG", ffmpeg)
689 imply_option("--enable-fmp4", ffmpeg, "--enable-ffmpeg")
691 # AV1 Video Codec Support
692 # ==============================================================
693 option("--disable-av1", help="Disable av1 video support")
696 @depends("--enable-av1")
697 def av1(value):
698     if value:
699         return True
702 @depends(target, when=av1 & compile_environment)
703 def dav1d_asm(target):
704     if target.cpu in ("aarch64", "x86", "x86_64"):
705         return True
708 @depends(target, when=av1 & compile_environment)
709 def dav1d_nasm(target):
710     if target.cpu in ("x86", "x86_64"):
711         return namespace(version="2.14", what="AV1")
714 set_config("MOZ_DAV1D_ASM", dav1d_asm)
715 set_define("MOZ_DAV1D_ASM", dav1d_asm)
716 set_config("MOZ_AV1", av1)
717 set_define("MOZ_AV1", av1)
719 # JXL Image Codec Support
720 # ==============================================================
721 option("--disable-jxl", help="Disable jxl image support")
724 @depends("--disable-jxl", milestone.is_nightly)
725 def jxl(value, is_nightly):
726     if is_nightly and value:
727         return True
730 set_config("MOZ_JXL", jxl)
731 set_define("MOZ_JXL", jxl)
733 # Built-in fragmented MP4 support.
734 # ==============================================================
735 option(
736     "--disable-fmp4",
737     env="MOZ_FMP4",
738     help="Disable support for in built Fragmented MP4 parsing",
742 @depends("--disable-fmp4", target, wmf, applemedia)
743 def fmp4(value, target, wmf, applemedia):
744     enabled = bool(value)
745     if value.origin == "default":
746         # target.os == 'Android' includes all B2G versions
747         enabled = wmf or applemedia or target.os == "Android"
748     if enabled:
749         return True
752 set_config("MOZ_FMP4", fmp4)
753 set_define("MOZ_FMP4", fmp4)
754 add_old_configure_assignment("MOZ_FMP4", fmp4)
757 @depends(target)
758 def sample_type_is_s16(target):
759     # Use integers over floats for audio on Android regardless of the CPU
760     # architecture, because audio backends for Android don't support floats.
761     # We also use integers on ARM because it's more efficient.
762     if target.os == "Android" or target.cpu == "arm":
763         return True
766 @depends(sample_type_is_s16)
767 def sample_type_is_float(t):
768     if not t:
769         return True
772 set_config("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
773 set_define("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
774 set_config("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
775 set_define("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
777 set_define("MOZ_VORBIS", sample_type_is_float)
778 set_config("MOZ_VORBIS", sample_type_is_float)
779 set_define("MOZ_TREMOR", sample_type_is_s16)
780 set_config("MOZ_TREMOR", sample_type_is_s16)
782 option(
783     "--disable-real-time-tracing",
784     help="Disable tracing of real-time audio callbacks",
787 set_config("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
788 set_define("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
790 # OpenMAX IL Decoding Support
791 # ==============================================================
792 option("--enable-openmax", help="Enable OpenMAX IL for video/audio decoding")
795 @depends("--enable-openmax")
796 def openmax(value):
797     enabled = bool(value)
798     if enabled:
799         return True
802 set_config("MOZ_OMX", openmax)
803 set_define("MOZ_OMX", openmax)
805 # EME Support
806 # ==============================================================
807 @depends(target, wmf)
808 def eme_choices(target, wmf):
809     if (
810         target.kernel in ("WINNT", "Linux")
811         and target.os != "Android"
812         and target.cpu in ("x86", "x86_64")
813     ):
814         if wmf:
815             return ("widevine", "wmfcdm")
816         return ("widevine",)
817     if target.kernel == "WINNT" and target.cpu == "aarch64":
818         return ("widevine",)
819     if target.os in ("OSX"):
820         return ("widevine",)
823 # Widevine is enabled by default in desktop browser builds, except
824 # on aarch64 Windows.
825 @depends(build_project, eme_choices, target)
826 def eme_default(build_project, choices, target):
827     if build_project == "browser":
828         if target.kernel != "WINNT" or target.cpu != "aarch64":
829             return choices
832 option(
833     "--enable-eme",
834     nargs="+",
835     choices=eme_choices,
836     default=eme_default,
837     when=eme_choices,
838     help="{Enable|Disable} support for Encrypted Media Extensions",
842 @depends("--enable-eme", fmp4, when=eme_choices)
843 def eme(enabled, fmp4):
844     if enabled and enabled.origin != "default" and not fmp4:
845         die("Encrypted Media Extension support requires " "Fragmented MP4 support")
848 @depends("--enable-eme", when=eme_choices)
849 def eme_modules(value):
850     return value
853 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
854 # None.
855 set_config("MOZ_EME_MODULES", eme_modules | dependable([]))
858 @depends(eme_modules, target, when=eme_modules)
859 def eme_win32_artifact(modules, target):
860     if "widevine" in modules and target.kernel == "WINNT" and target.cpu == "aarch64":
861         return True
864 set_config("MOZ_EME_WIN32_ARTIFACT", eme_win32_artifact)
867 # Media Foundation CDM support
868 # ==============================================================
869 @depends(eme_modules, when=wmfmediaengine)
870 def wmfcdm(modules):
871     if "wmfcdm" in modules:
872         return True
875 set_config("MOZ_WMF_CDM", True, when=wmfcdm)
876 set_define("MOZ_WMF_CDM", True, when=wmfcdm)
879 option(
880     name="--enable-chrome-format",
881     help="Select FORMAT of chrome files during packaging.",
882     nargs=1,
883     choices=("omni", "jar", "flat"),
884     default="omni",
888 @depends("--enable-chrome-format")
889 def packager_format(value):
890     return value[0]
893 set_config("MOZ_PACKAGER_FORMAT", packager_format)
895 # The packager minifies two different types of files: non-JS (mostly property
896 # files for l10n), and JS.  Setting MOZ_PACKAGER_MINIFY only minifies the
897 # former.  Firefox doesn't yet minify JS, due to concerns about debuggability.
899 # Also, the JS minification setup really only works correctly on Android:
900 # we need extra setup to use the newly-built shell for Linux and Windows,
901 # and cross-compilation for macOS requires some extra care.
904 @depends(target_is_android, "--enable-debug", milestone.is_nightly)
905 def enable_minify_default(is_android, debug, is_nightly):
906     if is_android and not debug and not is_nightly:
907         return ("properties", "js")
908     return ("properties",)
911 option(
912     name="--enable-minify",
913     help="Select types of files to minify during packaging.",
914     nargs="*",
915     choices=("properties", "js"),
916     default=enable_minify_default,
920 @depends("--enable-minify")
921 def enable_minify(value):
922     if "js" in value and "properties" not in value:
923         die("--enable-minify=js requires --enable-minify=properties.")
924     return namespace(
925         properties="properties" in value,
926         js="js" in value,
927     )
930 set_config("MOZ_PACKAGER_MINIFY", True, when=enable_minify.properties)
931 set_config("MOZ_PACKAGER_MINIFY_JS", True, when=enable_minify.js)
934 @depends(host, build_project)
935 def jar_maker_format(host, build_project):
936     # Multilocales for mobile/android use the same mergedirs for all locales,
937     # so we can't use symlinks for those builds.
938     if host.os == "WINNT" or build_project == "mobile/android":
939         return "flat"
940     return "symlink"
943 set_config("MOZ_JAR_MAKER_FILE_FORMAT", jar_maker_format)
946 @depends(toolkit)
947 def omnijar_name(toolkit):
948     # Fennec's static resources live in the assets/ folder of the
949     # APK.  Adding a path to the name here works because we only
950     # have one omnijar file in the final package (which is not the
951     # case on desktop).
952     return "assets/omni.ja" if toolkit == "android" else "omni.ja"
955 set_config("OMNIJAR_NAME", omnijar_name)
957 project_flag("MOZ_PLACES", help="Build Places if required", set_as_define=True)
959 project_flag(
960     "MOZ_SERVICES_HEALTHREPORT",
961     help="Build Firefox Health Reporter Service",
962     set_as_define=True,
965 project_flag(
966     "MOZ_NORMANDY",
967     help="Enable Normandy recipe runner",
968     set_as_define=True,
971 project_flag("MOZ_SERVICES_SYNC", help="Build Sync Services if required")
973 project_flag(
974     "MOZ_ANDROID_HISTORY",
975     help="Enable Android History instead of Places",
976     set_as_define=True,
979 project_flag(
980     "MOZ_DEDICATED_PROFILES",
981     help="Enable dedicated profiles per install",
982     set_as_define=True,
985 project_flag(
986     "MOZ_BLOCK_PROFILE_DOWNGRADE",
987     help="Block users from starting profiles last used by a newer build",
988     set_as_define=True,
992 @depends("MOZ_PLACES", "MOZ_ANDROID_HISTORY")
993 def check_places_and_android_history(places, android_history):
994     if places and android_history:
995         die("Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.")
998 option(
999     env="MOZ_TELEMETRY_REPORTING",
1000     default=mozilla_official,
1001     help="Enable telemetry reporting",
1004 set_define("MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING")
1007 @depends("MOZ_TELEMETRY_REPORTING", milestone.is_nightly)
1008 def telemetry_on_by_default(reporting, is_nightly):
1009     return reporting and is_nightly
1012 set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
1015 # gpsd support
1016 # ==============================================================
1017 system_lib_option("--enable-gpsd", env="MOZ_GPSD", help="Enable gpsd support")
1020 @depends("--enable-gpsd")
1021 def gpsd(value):
1022     return bool(value)
1025 system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
1027 set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
1029 # Miscellaneous programs
1030 # ==============================================================
1032 check_prog("TAR", ("gnutar", "gtar", "tar"))
1033 check_prog("UNZIP", ("unzip",))
1035 # Key files
1036 # ==============================================================
1037 include("../build/moz.configure/keyfiles.configure")
1039 simple_keyfile("Mozilla API")
1041 simple_keyfile("Google Location Service API")
1043 simple_keyfile("Google Safebrowsing API")
1045 id_and_secret_keyfile("Bing API")
1047 simple_keyfile("Adjust SDK")
1049 id_and_secret_keyfile("Leanplum SDK")
1051 simple_keyfile("Pocket API")
1054 # WebRender Debugger integration
1055 # ==============================================================
1057 option(
1058     "--enable-webrender-debugger", help="Build the websocket debug server in WebRender"
1061 set_config(
1062     "MOZ_WEBRENDER_DEBUGGER", depends_if("--enable-webrender-debugger")(lambda _: True)
1065 # Additional system headers defined at the application level
1066 # ==============================================================
1068 option(
1069     "--enable-app-system-headers",
1070     env="MOZ_APP_SYSTEM_HEADERS",
1071     help="Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild",
1075 @depends("--enable-app-system-headers")
1076 def app_system_headers(value):
1077     if value:
1078         return True
1081 set_config("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1082 set_define("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1084 # Printing
1085 # ==============================================================
1086 option("--disable-printing", help="Disable printing support")
1089 @depends("--disable-printing")
1090 def printing(value):
1091     if value:
1092         return True
1095 set_config("NS_PRINTING", printing)
1096 set_define("NS_PRINTING", printing)
1097 set_define("NS_PRINT_PREVIEW", printing)
1099 # Speech-dispatcher support
1100 # ==============================================================
1101 @depends(toolkit)
1102 def no_speechd_on_non_gtk(toolkit):
1103     if toolkit != "gtk":
1104         return False
1107 imply_option(
1108     "--enable-synth-speechd", no_speechd_on_non_gtk, reason="--enable-default-toolkit"
1111 option("--disable-synth-speechd", help="Disable speech-dispatcher support")
1113 set_config("MOZ_SYNTH_SPEECHD", depends_if("--disable-synth-speechd")(lambda _: True))
1115 # Speech API
1116 # ==============================================================
1117 option("--disable-webspeech", help="Disable support for HTML Speech API")
1120 @depends("--disable-webspeech")
1121 def webspeech(value):
1122     if value:
1123         return True
1126 set_config("MOZ_WEBSPEECH", webspeech)
1127 set_define("MOZ_WEBSPEECH", webspeech)
1128 add_old_configure_assignment("MOZ_WEBSPEECH", webspeech)
1130 # Speech API test backend
1131 # ==============================================================
1132 option(
1133     "--enable-webspeechtestbackend",
1134     default=webspeech,
1135     help="{Enable|Disable} support for HTML Speech API Test Backend",
1139 @depends_if("--enable-webspeechtestbackend")
1140 def webspeech_test_backend(value):
1141     return True
1144 set_config("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1145 set_define("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1147 # Graphics
1148 # ==============================================================
1149 @depends(target, milestone)
1150 def skia_pdf_default(target, milestone):
1151     return milestone.is_nightly and target.os != "WINNT"
1154 option("--enable-skia-pdf", default=skia_pdf_default, help="{Enable|Disable} Skia PDF")
1156 set_config("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1157 set_define("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1159 set_config(
1160     "SKIA_INCLUDES",
1161     [
1162         "/gfx/skia",
1163         "/gfx/skia/skia",
1164     ],
1167 system_lib_option(
1168     "--with-system-webp", help="Use system libwebp (located with pkgconfig)"
1171 system_webp = pkg_check_modules(
1172     "MOZ_WEBP", "libwebp >= 1.0.2 libwebpdemux >= 1.0.2", when="--with-system-webp"
1175 set_config("MOZ_SYSTEM_WEBP", depends(when=system_webp)(lambda: True))
1177 # Build Freetype in the tree
1178 # ==============================================================
1179 @depends(target, "--enable-skia-pdf")
1180 def tree_freetype(target, skia_pdf):
1181     if target.os == "Android" or (skia_pdf and target.os == "WINNT"):
1182         return True
1185 set_define("MOZ_TREE_FREETYPE", tree_freetype)
1186 set_config("MOZ_TREE_FREETYPE", tree_freetype)
1188 set_define("HAVE_FT_BITMAP_SIZE_Y_PPEM", tree_freetype)
1189 set_define("HAVE_FT_GLYPHSLOT_EMBOLDEN", tree_freetype)
1190 set_define("HAVE_FT_LOAD_SFNT_TABLE", tree_freetype)
1193 @depends(freetype2_combined_info, tree_freetype, build_environment)
1194 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
1195     if tree_freetype:
1196         return namespace(
1197             cflags=("-I%s/modules/freetype2/include" % build_env.topsrcdir,), libs=()
1198         )
1199     if freetype2_combined_info:
1200         return freetype2_combined_info
1203 set_config("FT2_LIBS", ft2_info.libs)
1206 @depends(target, tree_freetype, freetype2_info)
1207 def enable_cairo_ft(target, tree_freetype, freetype2_info):
1208     # Avoid defining MOZ_ENABLE_CAIRO_FT on Windows platforms because
1209     # "cairo-ft-font.c" includes <dlfcn.h>, which only exists on posix platforms
1210     return freetype2_info or (tree_freetype and target.os != "WINNT")
1213 set_config("MOZ_ENABLE_CAIRO_FT", True, when=enable_cairo_ft)
1214 set_config("CAIRO_FT_CFLAGS", ft2_info.cflags, when=enable_cairo_ft)
1217 # WebDriver (HTTP / BiDi)
1218 # ==============================================================
1220 # WebDriver is a remote control interface that enables introspection and
1221 # control of user agents. It provides a platform- and language-neutral wire
1222 # protocol as a way for out-of-process programs to remotely instruct the
1223 # behavior of web browsers.
1225 # The Gecko implementation is backed by Marionette and Remote Agent.
1226 # Both protocols are not really toolkit features, as much as Gecko engine
1227 # features. But they are enabled based on the toolkit, so here it lives.
1229 # Marionette remote protocol
1230 # -----------------------------------------------------------
1232 # Marionette is the Gecko remote protocol used for various remote control,
1233 # automation, and testing purposes throughout Gecko-based applications like
1234 # Firefox, Thunderbird, and any mobile browser built upon GeckoView.
1236 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
1237 # implementation.
1239 # The source of Marionette lives in ../remote/marionette.
1241 # For more information, see:
1242 # https://firefox-source-docs.mozilla.org/testing/marionette/index.html
1244 # Remote Agent (WebDriver BiDi / partial CDP)
1245 # -----------------------------------------------------------
1247 # The primary purpose is the implementation of the WebDriver BiDi specification.
1248 # But it also complements the existing Firefox Developer Tools Remote Debugging
1249 # Protocol (RDP) by implementing a subset of the Chrome DevTools Protocol (CDP).
1251 # The source of Remote Agent lives in ../remote.
1253 # For more information, see:
1254 # https://firefox-source-docs.mozilla.org/remote/index.html
1257 option(
1258     "--disable-webdriver",
1259     help="Disable support for WebDriver remote protocols",
1263 @depends("--disable-webdriver")
1264 def webdriver(enabled):
1265     if enabled:
1266         return True
1269 set_config("ENABLE_WEBDRIVER", webdriver)
1270 set_define("ENABLE_WEBDRIVER", webdriver)
1273 # geckodriver WebDriver implementation
1274 # ==============================================================
1276 # Turn off geckodriver for build configs we don't handle yet,
1277 # but allow --enable-geckodriver to override when compile environment is available.
1278 # --disable-tests implies disabling geckodriver.
1279 # Disable building in CI
1282 @depends(
1283     "--enable-tests", target, cross_compiling, hazard_analysis, asan, "MOZ_AUTOMATION"
1285 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
1286     if not enable_tests:
1287         return False
1288     if hazard or target.os == "Android" or (asan and cross_compile):
1289         return False
1290     if automation:
1291         return False
1292     return True
1295 option(
1296     "--enable-geckodriver",
1297     default=geckodriver_default,
1298     when="--enable-compile-environment",
1299     help="{Build|Do not build} geckodriver",
1303 @depends("--enable-geckodriver", when="--enable-compile-environment")
1304 def geckodriver(enabled):
1305     if enabled:
1306         return True
1309 set_config("MOZ_GECKODRIVER", geckodriver)
1312 # WebRTC
1313 # ========================================================
1314 @depends(target)
1315 def webrtc_default(target):
1316     # Turn off webrtc for OS's we don't handle yet, but allow
1317     # --enable-webrtc to override.
1318     os_match = False
1319     for os_fragment in (
1320         "linux",
1321         "mingw",
1322         "android",
1323         "linuxandroid",
1324         "dragonfly",
1325         "freebsd",
1326         "netbsd",
1327         "openbsd",
1328         "darwin",
1329     ):
1330         if target.raw_os.startswith(os_fragment):
1331             os_match = True
1333     cpu_match = False
1334     if (
1335         target.cpu
1336         in (
1337             "x86_64",
1338             "arm",
1339             "aarch64",
1340             "x86",
1341             "ia64",
1342             "mips32",
1343             "mips64",
1344         )
1345         or target.cpu.startswith("ppc")
1346     ):
1347         cpu_match = True
1349     if os_match and cpu_match:
1350         return True
1351     return False
1354 option(
1355     "--disable-webrtc",
1356     default=webrtc_default,
1357     help="{Enable|Disable} support for WebRTC",
1361 @depends("--disable-webrtc")
1362 def webrtc(enabled):
1363     if enabled:
1364         return True
1367 set_config("MOZ_WEBRTC", webrtc)
1368 set_define("MOZ_WEBRTC", webrtc)
1369 set_config("MOZ_SCTP", webrtc)
1370 set_define("MOZ_SCTP", webrtc)
1371 set_config("MOZ_SRTP", webrtc)
1372 set_define("MOZ_SRTP", webrtc)
1373 set_config("MOZ_WEBRTC_SIGNALING", webrtc)
1374 set_define("MOZ_WEBRTC_SIGNALING", webrtc)
1375 set_config("MOZ_PEERCONNECTION", webrtc)
1376 set_define("MOZ_PEERCONNECTION", webrtc)
1377 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1378 # opt/production builds (via MOZ_CRASH())
1379 set_config("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1380 set_define("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1382 # RAW media
1383 # ==============================================================
1386 @depends(target, webrtc)
1387 def raw_media_default(target, webrtc):
1388     if target.os == "Android":
1389         return True
1390     if webrtc:
1391         return True
1394 option(
1395     "--enable-raw",
1396     default=raw_media_default,
1397     help="{Enable|Disable} support for RAW media",
1400 set_config("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1401 set_define("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1404 # X11
1405 # ==============================================================
1406 @depends(webrtc, when=toolkit_gtk)
1407 def x11_libs(webrtc):
1408     libs = [
1409         "x11",
1410         "xcb",
1411         "xcb-shm",
1412         "x11-xcb",
1413         "xext",
1414         "xrandr >= 1.4.0",
1415     ]
1416     if webrtc:
1417         # third_party/libwebrtc/webrtc/webrtc_gn/moz.build adds those
1418         # manually, ensure they're available.
1419         libs += [
1420             "xcomposite",
1421             "xcursor",
1422             "xdamage",
1423             "xfixes",
1424             "xi",
1425             "xtst",
1426         ]
1427     return libs
1430 x11_headers = pkg_check_modules(
1431     "MOZ_X11",
1432     x11_libs,
1433     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1434     when=depends(full_toolkit)(
1435         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1436     ),
1440 set_config("MOZ_X11", True, when=x11_headers)
1441 set_define("MOZ_X11", True, when=x11_headers)
1443 pkg_check_modules(
1444     "MOZ_X11_SM",
1445     ["ice", "sm"],
1446     cflags_only=True,
1447     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1448     when=depends(full_toolkit)(
1449         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1450     ),
1454 # ASan Reporter Addon
1455 # ==============================================================
1456 option(
1457     "--enable-address-sanitizer-reporter",
1458     help="Enable Address Sanitizer Reporter Extension",
1462 @depends("--enable-address-sanitizer-reporter")
1463 def enable_asan_reporter(value):
1464     if value:
1465         return True
1468 set_config("MOZ_ASAN_REPORTER", enable_asan_reporter)
1469 set_define("MOZ_ASAN_REPORTER", enable_asan_reporter)
1470 add_old_configure_assignment("MOZ_ASAN_REPORTER", enable_asan_reporter)
1472 # Elfhack
1473 # ==============================================================
1474 with only_when("--enable-compile-environment"):
1476     @depends(host, target)
1477     def has_elfhack(host, target):
1478         return (
1479             target.kernel == "Linux"
1480             and host.kernel == "Linux"
1481             and target.cpu in ("arm", "aarch64", "x86", "x86_64")
1482         )
1484     @depends("--enable-release", enable_linker)
1485     def default_elfhack(release, linker):
1486         # Disable elfhack when explicitly building with --enable-linker=lld
1487         if linker and linker.origin != "default" and linker[0] in ("lld", "mold"):
1488             return False
1489         return bool(release)
1491     with only_when(has_elfhack):
1492         option(
1493             "--disable-elf-hack",
1494             default=default_elfhack,
1495             help="{Enable|Disable} elf hacks",
1496         )
1498         @depends(select_linker, when="--enable-elf-hack")
1499         def use_elf_hack(linker):
1500             if linker and linker.KIND == "lld":
1501                 die(
1502                     "Cannot enable elfhack with lld."
1503                     " Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
1504                 )
1505             return True
1507         set_config("USE_ELF_HACK", use_elf_hack)
1510 @depends(build_environment)
1511 def idl_roots(build_env):
1512     return namespace(
1513         ipdl_root=os.path.join(build_env.topobjdir, "ipc", "ipdl"),
1514         webidl_root=os.path.join(build_env.topobjdir, "dom", "bindings"),
1515         xpcom_root=os.path.join(build_env.topobjdir, "xpcom", "components"),
1516     )
1519 set_config("WEBIDL_ROOT", idl_roots.webidl_root)
1520 set_config("IPDL_ROOT", idl_roots.ipdl_root)
1521 set_config("XPCOM_ROOT", idl_roots.xpcom_root)
1523 # Proxy bypass protection
1524 # ==============================================================
1526 option(
1527     "--enable-proxy-bypass-protection",
1528     help="Prevent suspected or confirmed proxy bypasses",
1532 @depends_if("--enable-proxy-bypass-protection")
1533 def proxy_bypass_protection(_):
1534     return True
1537 set_config("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1538 set_define("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1540 # Proxy direct failover
1541 # ==============================================================
1543 option(
1544     "--disable-proxy-direct-failover",
1545     help="Disable direct failover for system requests",
1549 @depends_if("--disable-proxy-direct-failover")
1550 def proxy_direct_failover(value):
1551     if value:
1552         return True
1555 set_config("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1556 set_define("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1558 # MIDL
1559 # ==============================================================
1562 @depends(c_compiler, toolchain_prefix)
1563 def midl_names(c_compiler, toolchain_prefix):
1564     if c_compiler and c_compiler.type in ["gcc", "clang"]:
1565         # mingw
1566         widl = ("widl",)
1567         if toolchain_prefix:
1568             prefixed = tuple("%s%s" % (p, "widl") for p in toolchain_prefix)
1569             widl = prefixed + widl
1570         return widl
1572     return ("midl.exe",)
1575 @depends(target, "--enable-compile-environment")
1576 def check_for_midl(target, compile_environment):
1577     if target.os != "WINNT":
1578         return
1580     if compile_environment:
1581         return True
1584 midl = check_prog(
1585     "MIDL",
1586     midl_names,
1587     when=check_for_midl,
1588     allow_missing=True,
1589     paths=sdk_bin_path,
1590     # MIDL being used from a python wrapper script, we can live with it
1591     # having spaces.
1592     allow_spaces=True,
1595 option(env="MIDL_FLAGS", nargs=1, help="Extra flags to pass to MIDL")
1598 @depends(
1599     "MIDL_FLAGS",
1600     target,
1601     midl,
1602     when=depends(midl, target)(lambda m, t: m and t.kernel == "WINNT"),
1604 def midl_flags(flags, target, midl):
1605     if flags:
1606         flags = flags[0].split()
1607     else:
1608         flags = []
1610     if not midl.endswith("widl"):
1611         env = {
1612             "x86": "win32",
1613             "x86_64": "x64",
1614             "aarch64": "arm64",
1615         }[target.cpu]
1616         return flags + ["-nologo", "-no_cpp", "-env", env]
1618     # widl
1619     return flags + {
1620         "x86": ["--win32", "-m32"],
1621         "x86_64": ["--win64", "-m64"],
1622     }[target.cpu]
1625 set_config("MIDL_FLAGS", midl_flags)
1627 # Accessibility
1628 # ==============================================================
1630 option("--disable-accessibility", help="Disable accessibility support")
1633 @depends("--enable-accessibility", check_for_midl, midl, c_compiler)
1634 def accessibility(value, check_for_midl, midl, c_compiler):
1635     enabled = bool(value)
1637     if not enabled:
1638         return
1640     if check_for_midl and not midl:
1641         if c_compiler and c_compiler.type in ("gcc", "clang"):
1642             die(
1643                 "You have accessibility enabled, but widl could not be found. "
1644                 "Add --disable-accessibility to your mozconfig or install widl. "
1645                 "See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details."
1646             )
1647         else:
1648             die(
1649                 "MIDL could not be found. "
1650                 "Building accessibility without MIDL is not supported."
1651             )
1653     return enabled
1656 set_config("ACCESSIBILITY", accessibility)
1657 set_define("ACCESSIBILITY", accessibility)
1660 @depends(moz_debug, developer_options)
1661 def a11y_log(debug, developer_options):
1662     return debug or developer_options
1665 set_config("A11Y_LOG", True, when=a11y_log)
1666 set_define("A11Y_LOG", True, when=a11y_log)
1669 # Addon signing
1670 # ==============================================================
1671 @depends(milestone)
1672 def require_signing(milestone):
1673     return milestone.is_release_or_beta and not milestone.is_esr
1676 option(
1677     env="MOZ_REQUIRE_SIGNING",
1678     default=require_signing,
1679     help="Enforce that add-ons are signed by the trusted root",
1682 set_config("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1683 set_define("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1685 option(
1686     "--with-unsigned-addon-scopes",
1687     nargs="+",
1688     choices=("app", "system"),
1689     help="Addon scopes where signature is not required",
1693 @depends("--with-unsigned-addon-scopes")
1694 def unsigned_addon_scopes(scopes):
1695     return namespace(
1696         app="app" in scopes or None,
1697         system="system" in scopes or None,
1698     )
1701 set_config("MOZ_UNSIGNED_APP_SCOPE", unsigned_addon_scopes.app)
1702 set_config("MOZ_UNSIGNED_SYSTEM_SCOPE", unsigned_addon_scopes.system)
1705 # Addon sideloading
1706 # ==============================================================
1707 option(
1708     "--allow-addon-sideload",
1709     default=milestone.is_esr,
1710     help="Addon sideloading is allowed",
1714 set_config("MOZ_ALLOW_ADDON_SIDELOAD", True, when="--allow-addon-sideload")
1716 # WebExtensions API WebIDL bindings
1717 # ==============================================================
1720 @depends(milestone)
1721 def extensions_webidl_bindings_default(milestone):
1722     # Only enable the webidl bindings for the WebExtensions APIs
1723     # in Nightly.
1724     return milestone.is_nightly
1727 option(
1728     "--enable-extensions-webidl-bindings",
1729     default=extensions_webidl_bindings_default,
1730     help="{Enable|Disable} building experimental WebExtensions WebIDL bindings",
1734 @depends("--enable-extensions-webidl-bindings")
1735 def extensions_webidl_enabled(value):
1736     return bool(value)
1739 set_config("MOZ_WEBEXT_WEBIDL_ENABLED", extensions_webidl_enabled)
1741 # Launcher process (Windows only)
1742 # ==============================================================
1745 @depends(target)
1746 def launcher_process_default(target):
1747     return target.os == "WINNT"
1750 option(
1751     "--enable-launcher-process",
1752     default=launcher_process_default,
1753     help="{Enable|Disable} launcher process by default",
1757 @depends("--enable-launcher-process", target)
1758 def launcher(value, target):
1759     enabled = bool(value)
1760     if enabled and target.os != "WINNT":
1761         die("Cannot enable launcher process on %s", target.os)
1762     if enabled:
1763         return True
1766 set_config("MOZ_LAUNCHER_PROCESS", launcher)
1767 set_define("MOZ_LAUNCHER_PROCESS", launcher)
1769 # llvm-dlltool (Windows only)
1770 # ==============================================================
1773 @depends(build_project, target, "--enable-compile-environment")
1774 def check_for_llvm_dlltool(build_project, target, compile_environment):
1775     if build_project != "browser":
1776         return
1778     if target.os != "WINNT":
1779         return
1781     return compile_environment
1784 llvm_dlltool = check_prog(
1785     "LLVM_DLLTOOL",
1786     ("llvm-dlltool",),
1787     what="llvm-dlltool",
1788     when=check_for_llvm_dlltool,
1789     paths=clang_search_path,
1793 @depends(target, when=llvm_dlltool)
1794 def llvm_dlltool_flags(target):
1795     arch = {
1796         "x86": "i386",
1797         "x86_64": "i386:x86-64",
1798         "aarch64": "arm64",
1799     }[target.cpu]
1801     return ["-m", arch]
1804 set_config("LLVM_DLLTOOL_FLAGS", llvm_dlltool_flags)
1806 # BITS download (Windows only)
1807 # ==============================================================
1809 option(
1810     "--enable-bits-download",
1811     when=target_is_windows,
1812     default=target_is_windows,
1813     help="{Enable|Disable} building BITS download support",
1816 set_define(
1817     "MOZ_BITS_DOWNLOAD",
1818     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1820 set_config(
1821     "MOZ_BITS_DOWNLOAD",
1822     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1825 # Bundled fonts on desktop platform
1826 # ==============================================================
1829 @depends(target)
1830 def bundled_fonts_default(target):
1831     return target.os == "WINNT" or target.kernel == "Linux"
1834 @depends(build_project)
1835 def allow_bundled_fonts(project):
1836     return project == "browser" or project == "comm/mail"
1839 option(
1840     "--enable-bundled-fonts",
1841     default=bundled_fonts_default,
1842     when=allow_bundled_fonts,
1843     help="{Enable|Disable} support for bundled fonts on desktop platforms",
1846 set_define(
1847     "MOZ_BUNDLED_FONTS",
1848     depends_if("--enable-bundled-fonts", when=allow_bundled_fonts)(lambda _: True),
1851 # Reflow counting
1852 # ==============================================================
1855 @depends(moz_debug)
1856 def reflow_perf(debug):
1857     if debug:
1858         return True
1861 option(
1862     "--enable-reflow-perf",
1863     default=reflow_perf,
1864     help="{Enable|Disable} reflow performance tracing",
1867 # The difference in conditions here comes from the initial implementation
1868 # in old-configure, which was unexplained there as well.
1869 set_define("MOZ_REFLOW_PERF", depends_if("--enable-reflow-perf")(lambda _: True))
1870 set_define("MOZ_REFLOW_PERF_DSP", reflow_perf)
1872 # Layout debugger
1873 # ==============================================================
1876 @depends(moz_debug)
1877 def layout_debugger(debug):
1878     if debug:
1879         return True
1882 option(
1883     "--enable-layout-debugger",
1884     default=layout_debugger,
1885     help="{Enable|Disable} layout debugger",
1888 set_config("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1889 set_define("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1892 # Shader Compiler for Windows (and MinGW Cross Compile)
1893 # ==============================================================
1895 with only_when(compile_environment):
1896     fxc = check_prog(
1897         "FXC",
1898         ("fxc.exe", "fxc2.exe"),
1899         when=depends(target)(lambda t: t.kernel == "WINNT"),
1900         paths=sdk_bin_path,
1901         # FXC being used from a python wrapper script, we can live with it
1902         # having spaces.
1903         allow_spaces=True,
1904     )
1907 # VPX
1908 # ===
1910 with only_when(compile_environment):
1911     system_lib_option(
1912         "--with-system-libvpx", help="Use system libvpx (located with pkgconfig)"
1913     )
1915     with only_when("--with-system-libvpx"):
1916         vpx = pkg_check_modules("MOZ_LIBVPX", "vpx >= 1.10.0")
1918         check_header(
1919             "vpx/vpx_decoder.h",
1920             flags=vpx.cflags,
1921             onerror=lambda: die(
1922                 "Couldn't find vpx/vpx_decoder.h, which is required to build "
1923                 "with system libvpx. Use --without-system-libvpx to build "
1924                 "with in-tree libvpx."
1925             ),
1926         )
1928         check_symbol(
1929             "vpx_codec_dec_init_ver",
1930             flags=vpx.libs,
1931             onerror=lambda: die(
1932                 "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1933                 "not found"
1934             ),
1935         )
1937         set_config("MOZ_SYSTEM_LIBVPX", True)
1939     @depends("--with-system-libvpx", target)
1940     def in_tree_vpx(system_libvpx, target):
1941         if system_libvpx:
1942             return
1944         arm_asm = (target.cpu == "arm") or None
1945         return namespace(arm_asm=arm_asm)
1947     @depends(target, when=in_tree_vpx)
1948     def vpx_nasm(target):
1949         if target.cpu in ("x86", "x86_64"):
1950             if target.kernel == "WINNT":
1951                 # Version 2.03 is needed for automatic safeseh support.
1952                 return namespace(version="2.03", what="VPX")
1953             return namespace(what="VPX")
1955     @depends(in_tree_vpx, vpx_nasm, target, neon_flags)
1956     def vpx_as_flags(vpx, vpx_nasm, target, neon_flags):
1957         if vpx and vpx.arm_asm:
1958             # These flags are a lie; they're just used to enable the requisite
1959             # opcodes; actual arch detection is done at runtime.
1960             return neon_flags
1961         elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64":
1962             return ("-DPIC",)
1964     set_config("VPX_USE_NASM", True, when=vpx_nasm)
1965     set_config("VPX_ASFLAGS", vpx_as_flags)
1968 # JPEG
1969 # ====
1971 with only_when(compile_environment):
1972     system_lib_option(
1973         "--with-system-jpeg",
1974         nargs="?",
1975         help="Use system libjpeg (installed at given prefix)",
1976     )
1978     @depends_if("--with-system-jpeg")
1979     def jpeg_flags(value):
1980         if len(value):
1981             return namespace(
1982                 cflags=("-I%s/include" % value[0],),
1983                 ldflags=("-L%s/lib" % value[0], "-ljpeg"),
1984             )
1985         return namespace(
1986             ldflags=("-ljpeg",),
1987         )
1989     with only_when("--with-system-jpeg"):
1990         check_symbol(
1991             "jpeg_destroy_compress",
1992             flags=jpeg_flags.ldflags,
1993             onerror=lambda: die(
1994                 "--with-system-jpeg requested but symbol "
1995                 "jpeg_destroy_compress not found."
1996             ),
1997         )
1999         c_compiler.try_compile(
2000             includes=[
2001                 "stdio.h",
2002                 "sys/types.h",
2003                 "jpeglib.h",
2004             ],
2005             body="""
2006                 #if JPEG_LIB_VERSION < 62
2007                 #error Insufficient JPEG library version
2008                 #endif
2009             """,
2010             flags=jpeg_flags.cflags,
2011             check_msg="for sufficient jpeg library version",
2012             onerror=lambda: die(
2013                 "Insufficient JPEG library version for "
2014                 "--with-system-jpeg (62 required)"
2015             ),
2016         )
2018         c_compiler.try_compile(
2019             includes=[
2020                 "stdio.h",
2021                 "sys/types.h",
2022                 "jpeglib.h",
2023             ],
2024             body="""
2025                 #ifndef JCS_EXTENSIONS
2026                 #error libjpeg-turbo JCS_EXTENSIONS required
2027                 #endif
2028             """,
2029             flags=jpeg_flags.cflags,
2030             check_msg="for sufficient libjpeg-turbo JCS_EXTENSIONS",
2031             onerror=lambda: die(
2032                 "libjpeg-turbo JCS_EXTENSIONS required for " "--with-system-jpeg"
2033             ),
2034         )
2036         set_config("MOZ_JPEG_CFLAGS", jpeg_flags.cflags)
2037         set_config("MOZ_JPEG_LIBS", jpeg_flags.ldflags)
2039     @depends("--with-system-jpeg", target, neon_flags)
2040     def in_tree_jpeg_arm(system_jpeg, target, neon_flags):
2041         if system_jpeg:
2042             return
2044         if target.cpu == "arm":
2045             return neon_flags
2046         elif target.cpu == "aarch64":
2047             return ("-march=armv8-a",)
2049     @depends("--with-system-jpeg", target)
2050     def in_tree_jpeg_mips64(system_jpeg, target):
2051         if system_jpeg:
2052             return
2054         if target.cpu == "mips64":
2055             return ("-Wa,-mloongson-mmi", "-mloongson-ext")
2057     # Compiler check from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L419
2058     jpeg_mips64_mmi = c_compiler.try_compile(
2059         body='int c = 0, a = 0, b = 0; asm("paddb %0, %1, %2" : "=f" (c) : "f" (a), "f" (b));',
2060         check_msg="for loongson mmi support",
2061         flags=in_tree_jpeg_mips64,
2062         when=in_tree_jpeg_mips64,
2063     )
2065     @depends(
2066         "--with-system-jpeg",
2067         target,
2068         in_tree_jpeg_arm,
2069         in_tree_jpeg_mips64,
2070         jpeg_mips64_mmi,
2071     )
2072     def in_tree_jpeg(
2073         system_jpeg, target, in_tree_jpeg_arm, in_tree_jpeg_mips64, jpeg_mips64_mmi
2074     ):
2075         if system_jpeg:
2076             return
2078         if target.cpu in ("arm", "aarch64"):
2079             return in_tree_jpeg_arm
2080         elif target.kernel == "Darwin":
2081             if target.cpu == "x86":
2082                 return ("-DPIC", "-DMACHO")
2083             elif target.cpu == "x86_64":
2084                 return ("-D__x86_64__", "-DPIC", "-DMACHO")
2085         elif target.kernel == "WINNT":
2086             if target.cpu == "x86":
2087                 return ("-DPIC", "-DWIN32")
2088             elif target.cpu == "x86_64":
2089                 return ("-D__x86_64__", "-DPIC", "-DWIN64", "-DMSVC")
2090         elif target.cpu == "mips32":
2091             return ("-mdspr2",)
2092         elif target.cpu == "mips64" and jpeg_mips64_mmi:
2093             return in_tree_jpeg_mips64
2094         elif target.cpu == "x86":
2095             return ("-DPIC", "-DELF")
2096         elif target.cpu == "x86_64":
2097             return ("-D__x86_64__", "-DPIC", "-DELF")
2099     @depends(target, when=depends("--with-system-jpeg")(lambda x: not x))
2100     def jpeg_nasm(target):
2101         if target.cpu in ("x86", "x86_64"):
2102             # libjpeg-turbo 2.0.6 requires nasm 2.10.
2103             return namespace(version="2.10", what="JPEG")
2105     # Compiler checks from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L258
2106     jpeg_arm_neon_vld1_s16_x3 = c_compiler.try_compile(
2107         includes=["arm_neon.h"],
2108         body="int16_t input[12] = {}; int16x4x3_t output = vld1_s16_x3(input);",
2109         check_msg="for vld1_s16_x3 in arm_neon.h",
2110         flags=in_tree_jpeg_arm,
2111         when=in_tree_jpeg_arm,
2112     )
2114     jpeg_arm_neon_vld1_u16_x2 = c_compiler.try_compile(
2115         includes=["arm_neon.h"],
2116         body="uint16_t input[8] = {}; uint16x4x2_t output = vld1_u16_x2(input);",
2117         check_msg="for vld1_u16_x2 in arm_neon.h",
2118         flags=in_tree_jpeg_arm,
2119         when=in_tree_jpeg_arm,
2120     )
2122     jpeg_arm_neon_vld1q_u8_x4 = c_compiler.try_compile(
2123         includes=["arm_neon.h"],
2124         body="uint8_t input[64] = {}; uint8x16x4_t output = vld1q_u8_x4(input);",
2125         check_msg="for vld1q_u8_x4 in arm_neon.h",
2126         flags=in_tree_jpeg_arm,
2127         when=in_tree_jpeg_arm,
2128     )
2130     set_config("LIBJPEG_TURBO_USE_NASM", True, when=jpeg_nasm)
2131     set_config("LIBJPEG_TURBO_SIMD_FLAGS", in_tree_jpeg)
2132     set_config("LIBJPEG_TURBO_HAVE_VLD1_S16_X3", jpeg_arm_neon_vld1_s16_x3)
2133     set_config("LIBJPEG_TURBO_HAVE_VLD1_U16_X2", jpeg_arm_neon_vld1_u16_x2)
2134     set_config("LIBJPEG_TURBO_HAVE_VLD1Q_U8_X4", jpeg_arm_neon_vld1q_u8_x4)
2135     set_config(
2136         "LIBJPEG_TURBO_NEON_INTRINSICS",
2137         jpeg_arm_neon_vld1_s16_x3
2138         & jpeg_arm_neon_vld1_u16_x2
2139         & jpeg_arm_neon_vld1q_u8_x4,
2140     )
2143 # PNG
2144 # ===
2145 with only_when(compile_environment):
2146     system_lib_option(
2147         "--with-system-png",
2148         nargs="?",
2149         help="Use system libpng",
2150     )
2152     @depends("--with-system-png")
2153     def deprecated_system_png_path(value):
2154         if len(value) == 1:
2155             die(
2156                 "--with-system-png=PATH is not supported anymore. Please use "
2157                 "--with-system-png and set any necessary pkg-config environment variable."
2158             )
2160     png = pkg_check_modules("MOZ_PNG", "libpng >= 1.6.35", when="--with-system-png")
2162     check_symbol(
2163         "png_get_acTL",
2164         flags=png.libs,
2165         onerror=lambda: die(
2166             "--with-system-png won't work because the system's libpng doesn't have APNG support"
2167         ),
2168         when="--with-system-png",
2169     )
2171     set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
2174 # FFmpeg's ffvpx configuration
2175 # ==============================================================
2176 with only_when(compile_environment):
2178     @depends(target)
2179     def libav_fft(target):
2180         return target.kernel in ("WINNT", "Darwin") or target.cpu == "x86_64"
2182     set_config("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2183     set_define("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2186 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
2187 with only_when(compile_environment | artifact_builds):
2189     @depends(target)
2190     def ffvpx(target):
2191         enable = use_nasm = True
2192         flac_only = False
2193         flags = []
2195         if target.kernel == "WINNT":
2196             if target.cpu == "x86":
2197                 # 32-bit windows need to prefix symbols with an underscore.
2198                 flags = ["-DPIC", "-DWIN32", "-DPREFIX", "-Pconfig_win32.asm"]
2199             elif target.cpu == "x86_64":
2200                 flags = [
2201                     "-D__x86_64__",
2202                     "-DPIC",
2203                     "-DWIN64",
2204                     "-DMSVC",
2205                     "-Pconfig_win64.asm",
2206                 ]
2207             elif target.cpu == "aarch64":
2208                 flags = ["-DPIC", "-DWIN64"]
2209                 use_nasm = False
2210         elif target.kernel == "Darwin":
2211             # 32/64-bit macosx assemblers need to prefix symbols with an
2212             # underscore.
2213             flags = ["-DPIC", "-DMACHO", "-DPREFIX"]
2214             if target.cpu == "x86_64":
2215                 flags += [
2216                     "-D__x86_64__",
2217                     "-Pconfig_darwin64.asm",
2218                 ]
2219             elif target.cpu == "aarch64":
2220                 use_nasm = False
2221         elif target.cpu == "x86_64":
2222             flags = ["-D__x86_64__", "-DPIC", "-DELF", "-Pconfig_unix64.asm"]
2223         elif target.cpu in ("x86", "arm", "aarch64"):
2224             flac_only = True
2225         else:
2226             enable = False
2228         if flac_only or not enable:
2229             use_nasm = False
2231         return namespace(
2232             enable=enable,
2233             use_nasm=use_nasm,
2234             flac_only=flac_only,
2235             flags=flags,
2236         )
2238     @depends(when=ffvpx.use_nasm)
2239     def ffvpx_nasm():
2240         # nasm 2.10 for AVX-2 support.
2241         return namespace(version="2.10", what="FFVPX")
2243     # ffvpx_nasm can't indirectly depend on vpx_as_flags, because it depends
2244     # on a compiler test, so we have to do a little bit of dance here.
2245     @depends(ffvpx, vpx_as_flags, target)
2246     def ffvpx(ffvpx, vpx_as_flags, target):
2247         if ffvpx and vpx_as_flags and target.cpu in ("arm", "aarch64"):
2248             ffvpx.flags.extend(vpx_as_flags)
2249         return ffvpx
2251     set_config("MOZ_FFVPX", True, when=ffvpx.enable)
2252     set_define("MOZ_FFVPX", True, when=ffvpx.enable)
2253     set_config("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2254     set_define("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2255     set_config("FFVPX_ASFLAGS", ffvpx.flags)
2256     set_config("FFVPX_USE_NASM", True, when=ffvpx.use_nasm)
2259 # nasm detection
2260 # ==============================================================
2261 @depends(dav1d_nasm, vpx_nasm, jpeg_nasm, ffvpx_nasm, when=compile_environment)
2262 def need_nasm(*requirements):
2263     requires = {
2264         x.what: x.version if hasattr(x, "version") else True for x in requirements if x
2265     }
2266     if requires:
2267         items = sorted(requires.keys())
2268         if len(items) > 1:
2269             what = " and ".join((", ".join(items[:-1]), items[-1]))
2270         else:
2271             what = items[0]
2272         versioned = {k: v for (k, v) in requires.items() if v is not True}
2273         return namespace(what=what, versioned=versioned)
2276 nasm = check_prog(
2277     "NASM",
2278     ["nasm"],
2279     allow_missing=True,
2280     bootstrap="nasm",
2281     when=need_nasm,
2285 @depends(nasm, need_nasm.what)
2286 def check_nasm(nasm, what):
2287     if not nasm and what:
2288         die("Nasm is required to build with %s, but it was not found." % what)
2289     return nasm
2292 @depends_if(check_nasm)
2293 @checking("nasm version")
2294 def nasm_version(nasm):
2295     version = (
2296         check_cmd_output(nasm, "-v", onerror=lambda: die("Failed to get nasm version."))
2297         .splitlines()[0]
2298         .split()[2]
2299     )
2300     return Version(version)
2303 @depends(nasm_version, need_nasm.versioned, when=need_nasm.versioned)
2304 def check_nasm_version(nasm_version, versioned):
2305     by_version = sorted(versioned.items(), key=lambda x: x[1])
2306     what, version = by_version[-1]
2307     if nasm_version < version:
2308         die(
2309             "Nasm version %s or greater is required to build with %s." % (version, what)
2310         )
2311     return nasm_version
2314 @depends(target, when=check_nasm_version)
2315 def nasm_asflags(target):
2316     asflags = {
2317         ("OSX", "x86"): ["-f", "macho32"],
2318         ("OSX", "x86_64"): ["-f", "macho64"],
2319         ("WINNT", "x86"): ["-f", "win32"],
2320         ("WINNT", "x86_64"): ["-f", "win64"],
2321     }.get((target.os, target.cpu), None)
2322     if asflags is None:
2323         # We're assuming every x86 platform we support that's
2324         # not Windows or Mac is ELF.
2325         if target.cpu == "x86":
2326             asflags = ["-f", "elf32"]
2327         elif target.cpu == "x86_64":
2328             asflags = ["-f", "elf64"]
2329     return asflags
2332 set_config("NASM_ASFLAGS", nasm_asflags)
2335 # ANGLE OpenGL->D3D translator for WebGL
2336 # ==============================================================
2338 with only_when(compile_environment & target_is_windows):
2340     def d3d_compiler_dll_result(value):
2341         if not value.path:
2342             return "provided by the OS"
2343         return value.path
2345     @depends(target, valid_windows_sdk_dir, fxc)
2346     @checking("for D3D compiler DLL", d3d_compiler_dll_result)
2347     @imports("os.path")
2348     def d3d_compiler_dll(target, windows_sdk_dir, fxc):
2349         suffix = {
2350             "x86_64": "x64",
2351         }.get(target.cpu, target.cpu)
2353         name = "d3dcompiler_47.dll"
2355         if target.cpu == "aarch64":
2356             # AArch64 Windows comes with d3dcompiler_47.dll installed
2357             return namespace(name=name, path=None)
2359         if windows_sdk_dir:
2360             path = os.path.join(windows_sdk_dir.path, "Redist", "D3D", suffix, name)
2361             error_extra = "in Windows SDK at {}".format(windows_sdk_dir.path)
2362         else:
2363             path = os.path.join(os.path.dirname(fxc), name)
2364             error_extra = "alongside FXC at {}".format(fxc)
2366         if os.path.exists(path):
2367             return namespace(name=name, path=path)
2368         die("Could not find {} {}".format(name, error_extra))
2370     set_config("MOZ_ANGLE_RENDERER", True)
2371     set_config(
2372         "MOZ_D3DCOMPILER_VISTA_DLL", d3d_compiler_dll.name, when=d3d_compiler_dll.path
2373     )
2374     set_config("MOZ_D3DCOMPILER_VISTA_DLL_PATH", d3d_compiler_dll.path)
2376 # Remoting protocol support
2377 # ==============================================================
2380 @depends(toolkit)
2381 def has_remote(toolkit):
2382     if toolkit in ("gtk", "windows", "cocoa"):
2383         return True
2386 set_config("MOZ_HAS_REMOTE", has_remote)
2387 set_define("MOZ_HAS_REMOTE", has_remote)
2389 # RLBox Library Sandboxing wasm support
2390 # ==============================================================
2393 def wasm_sandboxing_libraries():
2394     return (
2395         "graphite",
2396         "ogg",
2397         "hunspell",
2398         "expat",
2399         "woff2",
2400     )
2403 @depends(dependable(wasm_sandboxing_libraries), build_project)
2404 def default_wasm_sandboxing_libraries(libraries, build_project):
2405     if build_project != "tools/rusttests":
2406         non_default_libs = set()
2408         return tuple(l for l in libraries if l not in non_default_libs)
2411 option(
2412     "--with-wasm-sandboxed-libraries",
2413     env="WASM_SANDBOXED_LIBRARIES",
2414     help="{Enable wasm sandboxing for the selected libraries|Disable wasm sandboxing}",
2415     nargs="+",
2416     choices=dependable(wasm_sandboxing_libraries),
2417     default=default_wasm_sandboxing_libraries,
2421 @depends(target, host, when="--with-wasm-sandboxed-libraries")
2422 def check_wasm_sandboxing(target, host):
2423     if target.kernel == "WINNT" and host.kernel == "WINNT" and target.cpu != host.cpu:
2424         # Bug 1741233
2425         die(
2426             f"Wasm sandboxing is not supported yet when building for {target.cpu} on {host.cpu} Windows. "
2427             "Please use --without-wasm-sandboxed-libraries for now."
2428         )
2431 @depends("--with-wasm-sandboxed-libraries")
2432 def requires_wasm_sandboxing(libraries):
2433     if libraries:
2434         return True
2437 set_config("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2438 set_define("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2440 with only_when(requires_wasm_sandboxing & compile_environment):
2441     option(
2442         "--with-wasi-sysroot",
2443         env="WASI_SYSROOT",
2444         nargs=1,
2445         help="Path to wasi sysroot for wasm sandboxing",
2446     )
2448     @depends("--with-wasi-sysroot", requires_wasm_sandboxing)
2449     def bootstrap_wasi_sysroot(wasi_sysroot, requires_wasm_sandboxing):
2450         return requires_wasm_sandboxing and not wasi_sysroot
2452     @depends(
2453         "--with-wasi-sysroot",
2454         bootstrap_path("sysroot-wasm32-wasi", when=bootstrap_wasi_sysroot),
2455     )
2456     @imports("os")
2457     def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot):
2458         if not wasi_sysroot:
2459             return bootstrapped_sysroot
2461         wasi_sysroot = wasi_sysroot[0]
2462         if not os.path.isdir(wasi_sysroot):
2463             die("Argument to --with-wasi-sysroot must be a directory")
2464         if not os.path.isabs(wasi_sysroot):
2465             die("Argument to --with-wasi-sysroot must be an absolute path")
2467         return wasi_sysroot
2469     @depends(wasi_sysroot)
2470     def wasi_sysroot_flags(wasi_sysroot):
2471         if wasi_sysroot:
2472             log.info("Using wasi sysroot in %s", wasi_sysroot)
2473             return ["--sysroot=%s" % wasi_sysroot]
2474         return []
2476     set_config("WASI_SYSROOT", wasi_sysroot)
2478     def wasm_compiler_with_flags(compiler, sysroot_flags):
2479         if compiler:
2480             return (
2481                 compiler.wrapper + [compiler.compiler] + compiler.flags + sysroot_flags
2482             )
2484     @template
2485     def wasm_compiler_error(msg):
2486         @depends("--with-wasm-sandboxed-libraries")
2487         def wasm_compiler_error(sandboxed_libs):
2488             suggest_disable = ""
2489             if sandboxed_libs.origin == "default":
2490                 suggest_disable = " Or build with --without-wasm-sandboxed-libraries."
2491             return lambda: die(msg + suggest_disable)
2493         return wasm_compiler_error
2495     @template
2496     def check_wasm_compiler(compiler, language):
2497         compiler.try_compile(
2498             includes=["cstring" if language == "C++" else "string.h"],
2499             flags=wasi_sysroot_flags,
2500             check_msg="the wasm %s compiler can find wasi headers" % language,
2501             onerror=wasm_compiler_error(
2502                 "Cannot find wasi headers or problem with the wasm compiler. "
2503                 "Please fix the problem."
2504             ),
2505         )
2507         compiler.try_run(
2508             flags=wasi_sysroot_flags,
2509             check_msg="the wasm %s linker can find wasi libraries" % language,
2510             onerror=wasm_compiler_error(
2511                 "Cannot find wasi libraries or problem with the wasm linker. "
2512                 "Please fix the problem."
2513             ),
2514         )
2516     wasm_cc = compiler("C", wasm, other_compiler=c_compiler)
2517     check_wasm_compiler(wasm_cc, "C")
2519     @depends(wasm_cc, wasi_sysroot_flags)
2520     def wasm_cc_with_flags(wasm_cc, wasi_sysroot_flags):
2521         return wasm_compiler_with_flags(wasm_cc, wasi_sysroot_flags)
2523     set_config("WASM_CC", wasm_cc_with_flags)
2525     wasm_cxx = compiler(
2526         "C++",
2527         wasm,
2528         c_compiler=wasm_cc,
2529         other_compiler=cxx_compiler,
2530         other_c_compiler=c_compiler,
2531     )
2532     check_wasm_compiler(wasm_cxx, "C++")
2534     @depends(wasm_cxx, wasi_sysroot_flags)
2535     def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot_flags):
2536         return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot_flags)
2538     set_config("WASM_CXX", wasm_cxx_with_flags)
2540     wasm_compile_flags = dependable(["-fno-exceptions", "-fno-strict-aliasing"])
2541     option(env="WASM_CFLAGS", nargs=1, help="Options to pass to WASM_CC")
2543     @depends("WASM_CFLAGS", wasm_compile_flags)
2544     def wasm_cflags(value, wasm_compile_flags):
2545         if value:
2546             return wasm_compile_flags + value
2547         else:
2548             return wasm_compile_flags
2550     set_config("WASM_CFLAGS", wasm_cflags)
2552     option(env="WASM_CXXFLAGS", nargs=1, help="Options to pass to WASM_CXX")
2554     @depends("WASM_CXXFLAGS", wasm_compile_flags)
2555     def wasm_cxxflags(value, wasm_compile_flags):
2556         if value:
2557             return wasm_compile_flags + value
2558         else:
2559             return wasm_compile_flags
2561     set_config("WASM_CXXFLAGS", wasm_cxxflags)
2564 @depends("--with-wasm-sandboxed-libraries")
2565 def wasm_sandboxing(libraries):
2566     if not libraries:
2567         return
2569     return namespace(**{name: True for name in libraries})
2572 @template
2573 def wasm_sandboxing_config_defines():
2574     for lib in wasm_sandboxing_libraries():
2575         set_config(
2576             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2577         )
2578         set_define(
2579             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2580         )
2583 wasm_sandboxing_config_defines()
2586 # new Notification Store implementation
2587 # ==============================================================
2590 @depends(milestone)
2591 def new_notification_store(milestone):
2592     if milestone.is_nightly:
2593         return True
2596 set_config("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2597 set_define("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2600 # Glean SDK Integration Crate
2601 # ==============================================================
2604 @depends(target)
2605 def glean_android(target):
2606     return target.os == "Android"
2609 set_config("MOZ_GLEAN_ANDROID", True, when=glean_android)
2610 set_define("MOZ_GLEAN_ANDROID", True, when=glean_android)
2613 # dump_syms
2614 # ==============================================================
2616 check_prog(
2617     "DUMP_SYMS",
2618     ["dump_syms"],
2619     allow_missing=True,
2620     bootstrap="dump_syms",
2621     when=compile_environment,
2625 @depends(valid_windows_sdk_dir, host)
2626 @imports(_from="os", _import="environ")
2627 def pdbstr_paths(valid_windows_sdk_dir, host):
2628     if not valid_windows_sdk_dir:
2629         return
2631     vc_host = {
2632         "x86": "x86",
2633         "x86_64": "x64",
2634     }.get(host.cpu)
2636     return [
2637         environ["PATH"],
2638         os.path.join(valid_windows_sdk_dir.path, "Debuggers", vc_host, "srcsrv"),
2639     ]
2642 check_prog(
2643     "PDBSTR",
2644     ["pdbstr.exe"],
2645     allow_missing=True,
2646     when=compile_environment & target_is_windows,
2647     paths=pdbstr_paths,
2648     allow_spaces=True,
2652 @depends("MOZ_AUTOMATION", c_compiler)
2653 def allow_missing_winchecksec(automation, c_compiler):
2654     if not automation:
2655         return True
2656     if c_compiler and c_compiler.type != "clang-cl":
2657         return True
2660 check_prog(
2661     "WINCHECKSEC",
2662     ["winchecksec.exe", "winchecksec"],
2663     bootstrap="winchecksec",
2664     allow_missing=allow_missing_winchecksec,
2665     when=compile_environment & target_is_windows,
2668 # Fork server
2669 @depends(target, build_project)
2670 def forkserver_default(target, build_project):
2671     return build_project == "browser" and (
2672         (target.os == "GNU" and target.kernel == "Linux")
2673         or target.os == "FreeBSD"
2674         or target.os == "OpenBSD"
2675     )
2678 option(
2679     "--enable-forkserver",
2680     default=forkserver_default,
2681     env="MOZ_ENABLE_FORKSERVER",
2682     help="{Enable|Disable} fork server",
2686 @depends("--enable-forkserver", target)
2687 def forkserver_flag(value, target):
2688     if (
2689         target.os == "Android"
2690         or (target.os == "GNU" and target.kernel == "Linux")
2691         or target.os == "FreeBSD"
2692         or target.os == "OpenBSD"
2693     ):
2694         return bool(value)
2695     pass
2698 set_config("MOZ_ENABLE_FORKSERVER", forkserver_flag)
2699 set_define("MOZ_ENABLE_FORKSERVER", forkserver_flag, forkserver_flag)
2701 # Crash Reporter
2702 # ==============================================================
2704 with only_when(compile_environment & target_has_linux_kernel):
2705     # Check if we need to use the breakpad_getcontext fallback.
2706     getcontext = check_symbol("getcontext")
2707     set_config("HAVE_GETCONTEXT", getcontext)
2708     set_define("HAVE_GETCONTEXT", getcontext)
2710 # NSS
2711 # ==============================================================
2712 include("../build/moz.configure/nss.configure")
2715 # Enable or disable running in background task mode: headless for
2716 # periodic, short-lived, maintenance tasks.
2717 # ==============================================================================
2718 option(
2719     "--disable-backgroundtasks",
2720     help="Disable running in background task mode",
2722 set_config("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2723 set_define("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2726 # Update-related programs: updater, maintenance service, update agent,
2727 # default browser agent.
2728 # ==============================================================
2729 include("../build/moz.configure/update-programs.configure")
2732 # Mobile optimizations
2733 # ==============================================================
2734 option(
2735     "--enable-mobile-optimize",
2736     default=target_is_android,
2737     help="{Enable|Disable} mobile optimizations",
2740 set_define("MOZ_GFX_OPTIMIZE_MOBILE", True, when="--enable-mobile-optimize")
2741 # We ignore "paint will resample" on mobile for performance.
2742 # We may want to revisit this later.
2743 set_define("MOZ_IGNORE_PAINT_WILL_RESAMPLE", True, when="--enable-mobile-optimize")
2745 # Pref extensions
2746 # ==============================================================
2747 option("--disable-pref-extensions", help="Disable pref extensions such as autoconfig")
2748 set_config("MOZ_PREF_EXTENSIONS", True, when="--enable-pref-extensions")
2750 # Offer a way to disable the startup cache
2751 # ==============================================================
2752 option("--disable-startupcache", help="Disable startup cache")
2755 @depends("--enable-startupcache")
2756 def enable_startupcache(value):
2757     if value:
2758         return True
2761 set_define(
2762     "MOZ_DISABLE_STARTUPCACHE", True, when=depends(enable_startupcache)(lambda x: not x)
2766 # Branding
2767 # ==============================================================
2768 option(
2769     env="MOZ_APP_REMOTINGNAME",
2770     nargs=1,
2771     help="Used for the internal program name, which affects profile name "
2772     "and remoting. If not set, defaults to MOZ_APP_NAME if the update channel "
2773     "is release, and MOZ_APP_NAME-MOZ_UPDATE_CHANNEL otherwise.",
2777 @depends("MOZ_APP_REMOTINGNAME", moz_app_name, update_channel)
2778 def moz_app_remotingname(value, moz_app_name, update_channel):
2779     if value:
2780         return value[0]
2781     if update_channel == "release":
2782         return moz_app_name
2783     return moz_app_name + "-" + update_channel
2786 set_config("MOZ_APP_REMOTINGNAME", moz_app_remotingname)
2788 option(
2789     env="ANDROID_PACKAGE_NAME",
2790     nargs=1,
2791     help="Name of the Android package (default org.mozilla.$MOZ_APP_NAME)",
2795 @depends("ANDROID_PACKAGE_NAME", moz_app_name)
2796 def android_package_name(value, moz_app_name):
2797     if value:
2798         return value[0]
2799     if moz_app_name == "fennec":
2800         return "org.mozilla.fennec_aurora"
2801     return "org.mozilla.%s" % moz_app_name
2804 set_config("ANDROID_PACKAGE_NAME", android_package_name)
2807 # Miscellaneous options
2808 # ==============================================================
2809 option(env="MOZ_WINCONSOLE", nargs="?", help="Whether we can create a console window.")
2810 set_define("MOZ_WINCONSOLE", True, when=depends("MOZ_WINCONSOLE")(lambda x: x))
2813 # Alternative Crashreporter setting
2814 option(
2815     "--with-crashreporter-url",
2816     env="MOZ_CRASHREPORTER_URL",
2817     default="https://crash-reports.mozilla.com/",
2818     nargs=1,
2819     help="Set an alternative crashreporter url",
2822 set_config(
2823     "MOZ_CRASHREPORTER_URL",
2824     depends("--with-crashreporter-url")(lambda x: x[0].rstrip("/")),
2828 # Crash reporter options
2829 # ==============================================================
2830 @depends(target)
2831 def oxidized_breakpad(target):
2832     if target.kernel == "Linux" and target.os != "Android":
2833         return target.cpu in ("x86", "x86_64")
2834     return False
2837 set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2838 set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2841 # Wine
2842 # ==============================================================
2843 @depends(target, host)
2844 def want_wine(target, host):
2845     return target.kernel == "WINNT" and host.kernel != "WINNT"
2848 wine = check_prog(
2849     "WINE",
2850     ["wine64", "wine"],
2851     when=want_wine,
2852     bootstrap="wine/bin",
2855 # DOM Streams
2856 # ==============================================================
2857 # Set this to true so the JS engine knows we're doing a browser build.
2858 set_config("MOZ_DOM_STREAMS", True)
2859 set_define("MOZ_DOM_STREAMS", True)
2861 # libevent
2862 # ==============================================================
2863 with only_when(compile_environment):
2864     system_lib_option(
2865         "--with-system-libevent",
2866         nargs="?",
2867         help="Use system libevent",
2868     )
2870     @depends("--with-system-libevent")
2871     def deprecated_system_libevent_path(value):
2872         if len(value) == 1:
2873             die(
2874                 "--with-system-libevent=PATH is not supported anymore. Please use "
2875                 "--with-system-libevent and set any necessary pkg-config environment variable."
2876             )
2878     pkg_check_modules("MOZ_LIBEVENT", "libevent", when="--with-system-libevent")
2880     set_config("MOZ_SYSTEM_LIBEVENT", True, when="--with-system-libevent")
2883 # Crash reporting
2884 # ==============================================================
2885 @depends(target, developer_options, artifact_builds)
2886 def crashreporter_default(target, developer_options, artifacts):
2887     if target.kernel in ("WINNT", "Darwin"):
2888         return True
2889     if target.kernel == "Linux" and target.cpu in ("x86", "x86_64", "arm", "aarch64"):
2890         # The crash reporter prevents crash stacktraces to be logged in the
2891         # logs on Android, so we leave it out by default in developer builds.
2892         return target.os != "Android" or not developer_options or artifacts
2895 option(
2896     "--enable-crashreporter",
2897     default=crashreporter_default,
2898     help="{Enable|Disable} crash reporting",
2902 set_config("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2903 set_define("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2905 with only_when(compile_environment):
2906     with only_when("--enable-crashreporter"):
2907         pkg_check_modules(
2908             "MOZ_GTHREAD",
2909             "gthread-2.0",
2910             when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2911         )
2913         set_config(
2914             "MOZ_CRASHREPORTER_INJECTOR",
2915             True,
2916             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2917         )
2918         set_define(
2919             "MOZ_CRASHREPORTER_INJECTOR",
2920             True,
2921             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2922         )
2925 # If we have any service that uploads data (and requires data submission
2926 # policy alert), set MOZ_DATA_REPORTING.
2927 # ==============================================================
2928 @depends(
2929     "MOZ_TELEMETRY_REPORTING",
2930     "MOZ_SERVICES_HEALTHREPORT",
2931     "--enable-crashreporter",
2932     "MOZ_NORMANDY",
2934 def data_reporting(telemetry, healthreport, crashreporter, normandy):
2935     return telemetry or healthreport or crashreporter or normandy
2938 set_config("MOZ_DATA_REPORTING", True, when=data_reporting)
2939 set_define("MOZ_DATA_REPORTING", True, when=data_reporting)
2942 # Gtk+
2943 # ==============================================================
2944 with only_when(toolkit_gtk):
2945     pkg_check_modules(
2946         "MOZ_GTK3",
2947         "gtk+-3.0 >= 3.14.0 gtk+-unix-print-3.0 glib-2.0 gobject-2.0 gio-unix-2.0",
2948     )
2950     set_define("GDK_VERSION_MIN_REQUIRED", "GDK_VERSION_3_14")
2951     set_define("GDK_VERSION_MAX_ALLOWED", "GDK_VERSION_3_14")
2953     pkg_check_modules("GLIB", "glib-2.0 >= 2.42 gobject-2.0")
2955     set_define("GLIB_VERSION_MIN_REQUIRED", "GLIB_VERSION_2_42")
2956     set_define("GLIB_VERSION_MAX_ALLOWED", "GLIB_VERSION_2_42")
2958     set_define("MOZ_ACCESSIBILITY_ATK", True, when=accessibility)
2960 # DBus
2961 # ==============================================================
2962 with only_when(toolkit_gtk):
2963     option("--disable-dbus", help="Disable dbus support")
2965     with only_when("--enable-dbus"):
2966         pkg_check_modules("MOZ_DBUS", "dbus-1 >= 0.60")
2967         pkg_check_modules("MOZ_DBUS_GLIB", "dbus-glib-1 >= 0.60")
2969         set_config("MOZ_ENABLE_DBUS", True)
2970         set_define("MOZ_ENABLE_DBUS", True)
2973 # Necko's wifi scanner
2974 # ==============================================================
2975 @depends(target)
2976 def necko_wifi_when(target):
2977     return target.os in ("WINNT", "OSX", "DragonFly", "FreeBSD") or (
2978         target.kernel == "Linux" and target.os == "GNU"
2979     )
2982 option("--disable-necko-wifi", help="Disable necko wifi scanner", when=necko_wifi_when)
2984 set_config("NECKO_WIFI", True, when="--enable-necko-wifi")
2985 set_define("NECKO_WIFI", True, when="--enable-necko-wifi")
2988 @depends(
2989     depends("--enable-necko-wifi", when=necko_wifi_when)(lambda x: x),
2990     depends("--enable-dbus", when=toolkit_gtk)(lambda x: x),
2991     when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2993 def necko_wifi_dbus(necko_wifi, dbus):
2994     if necko_wifi and not dbus:
2995         die(
2996             "Necko WiFi scanning needs DBus on your platform, remove --disable-dbus"
2997             " or use --disable-necko-wifi"
2998         )
2999     return necko_wifi and dbus
3002 set_config("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
3005 # Frontend JS debug mode
3006 # ==============================================================
3007 option("--enable-debug-js-modules", help="Enable debug mode for frontend JS libraries")
3009 set_config("DEBUG_JS_MODULES", True, when="--enable-debug-js-modules")
3012 # moz_dump_painting
3013 # ==============================================================
3014 option("--enable-dump-painting", help="Enable paint debugging")
3016 set_define(
3017     "MOZ_DUMP_PAINTING",
3018     True,
3019     when=depends("--enable-dump-painting", "--enable-debug")(
3020         lambda painting, debug: painting or debug
3021     ),
3023 set_define("MOZ_LAYERS_HAVE_LOG", True, when="--enable-dump-painting")
3026 # libproxy support
3027 # ==============================================================
3028 with only_when(toolkit_gtk):
3029     system_lib_option("--enable-libproxy", help="Enable libproxy support")
3031     with only_when("--enable-libproxy"):
3032         pkg_check_modules("MOZ_LIBPROXY", "libproxy-1.0")
3034         set_config("MOZ_ENABLE_LIBPROXY", True)
3035         set_define("MOZ_ENABLE_LIBPROXY", True)
3038 # Enable runtime logging
3039 # ==============================================================
3040 set_define("MOZ_LOGGING", True)
3041 set_define("FORCE_PR_LOG", True)
3043 # This will enable logging of addref, release, ctor, dtor.
3044 # ==============================================================
3045 option(
3046     "--enable-logrefcnt",
3047     default=moz_debug,
3048     help="{Enable|Disable} logging of refcounts",
3051 set_define("NS_BUILD_REFCNT_LOGGING", True, when="--enable-logrefcnt")
3054 # NegotiateAuth
3055 # ==============================================================
3056 option("--disable-negotiateauth", help="Disable GSS-API negotiation")
3058 set_config("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
3059 set_define("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
3062 # Parental control
3063 # ==============================================================
3064 option("--disable-parental-controls", help="Do not build parental controls")
3066 set_config(
3067     "MOZ_DISABLE_PARENTAL_CONTROLS",
3068     True,
3069     when=depends("--enable-parental-controls")(lambda x: not x),
3071 set_define(
3072     "MOZ_DISABLE_PARENTAL_CONTROLS",
3073     True,
3074     when=depends("--enable-parental-controls")(lambda x: not x),
3078 # Sandboxing support
3079 # ==============================================================
3080 @depends(target, tsan, asan)
3081 def sandbox_default(target, tsan, asan):
3082     # Only enable the sandbox by default on Linux, OpenBSD, macOS, and Windows
3083     if target.kernel == "Linux" and target.os == "GNU":
3084         # Bug 1182565: TSan conflicts with sandboxing on Linux.
3085         # Bug 1287971: LSan also conflicts with sandboxing on Linux.
3086         if tsan or asan:
3087             return False
3088         # Linux sandbox is only available on x86{,_64} and arm{,64}.
3089         return target.cpu in ("x86", "x86_64", "arm", "aarch64")
3090     return target.kernel in ("WINNT", "Darwin", "OpenBSD")
3093 option(
3094     "--enable-sandbox",
3095     default=sandbox_default,
3096     help="{Enable|Disable} sandboxing support",
3099 set_config("MOZ_SANDBOX", True, when="--enable-sandbox")
3100 set_define("MOZ_SANDBOX", True, when="--enable-sandbox")
3102 with only_when(depends(target.kernel)(lambda k: k not in ("Darwin", "WINNT"))):
3103     set_define("MOZ_CONTENT_TEMP_DIR", True, when="--enable-sandbox")
3105 # Searching of system directories for extensions.
3106 # ==============================================================
3107 # Note: this switch is meant to be used for test builds whose behavior should
3108 # not depend on what happens to be installed on the local machine.
3109 option(
3110     "--disable-system-extension-dirs",
3111     help="Disable searching system- and account-global directories for extensions"
3112     " of any kind; use only profile-specific extension directories",
3115 set_define("ENABLE_SYSTEM_EXTENSION_DIRS", True, when="--enable-system-extension-dirs")
3118 # Pixman
3119 # ==============================================================
3120 with only_when(compile_environment):
3121     system_lib_option(
3122         "--enable-system-pixman", help="Use system pixman (located with pkgconfig)"
3123     )
3125     @depends("--enable-system-pixman")
3126     def in_tree_pixman(pixman):
3127         return not pixman
3129     set_config("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3130     set_define("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3132     pkg_check_modules("MOZ_PIXMAN", "pixman-1 >= 0.36.0", when="--enable-system-pixman")
3133     # Set MOZ_PIXMAN_CFLAGS to an explicit empty value when --enable-system-pixman is *not* used,
3134     # for layout/style/extra-bindgen-flags
3135     set_config("MOZ_PIXMAN_CFLAGS", [], when=in_tree_pixman)
3138 # Universalchardet
3139 # ==============================================================
3140 with only_when(compile_environment):
3141     option("--disable-universalchardet", help="Disable universal encoding detection")
3143     set_config("MOZ_UNIVERSALCHARDET", True, when="--enable-universalchardet")
3146 # Disable zipwriter
3147 # ==============================================================
3148 with only_when(compile_environment):
3149     option("--disable-zipwriter", help="Disable zipwriter component")
3151     set_config("MOZ_ZIPWRITER", True, when="--enable-zipwriter")
3154 # Location of the mozilla user directory
3155 # ==============================================================
3156 with only_when(compile_environment):
3158     @depends(target)
3159     def default_user_appdir(target):
3160         if target.kernel in ("WINNT", "Darwin"):
3161             return "Mozilla"
3162         return ".mozilla"
3164     option(
3165         "--with-user-appdir",
3166         nargs=1,
3167         default=default_user_appdir,
3168         help="Set user-specific appdir",
3169     )
3171     @depends("--with-user-appdir")
3172     def user_appdir(appdir):
3173         if not appdir:
3174             die("--without-user-appdir is not a valid option.")
3175         if "/" in appdir[0]:
3176             die("--with-user-appdir must be a single relative path.")
3177         return '"{}"'.format(appdir[0])
3179     set_define("MOZ_USER_DIR", user_appdir)
3182 # Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
3183 # ==============================================================
3184 with only_when(compile_environment):
3185     have_sin_len = c_compiler.try_compile(
3186         includes=["netinet/in.h"],
3187         body="struct sockaddr_in x; void *foo = (void*) &x.sin_len;",
3188         check_msg="for sin_len in struct sockaddr_in",
3189     )
3190     have_sin6_len = c_compiler.try_compile(
3191         includes=["netinet/in.h"],
3192         body="struct sockaddr_in6 x; void *foo = (void*) &x.sin6_len;",
3193         check_msg="for sin_len6 in struct sockaddr_in6",
3194     )
3195     set_define("HAVE_SIN_LEN", have_sin_len)
3196     set_define("HAVE_SIN6_LEN", have_sin6_len)
3197     # HAVE_CONN_LEN must be the same as HAVE_SIN_LEN and HAVE_SIN6_LEN
3198     set_define("HAVE_SCONN_LEN", have_sin_len & have_sin6_len)
3199     set_define(
3200         "HAVE_SA_LEN",
3201         c_compiler.try_compile(
3202             includes=["netinet/in.h"],
3203             body="struct sockaddr x; void *foo = (void*) &x.sa_len;",
3204             check_msg="for sa_len in struct sockaddr",
3205         ),
3206     )
3209 # Check for pthread_cond_timedwait_monotonic_np
3210 # ==============================================================
3211 with only_when(compile_environment):
3212     set_define(
3213         "HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC",
3214         c_compiler.try_compile(
3215             includes=["pthread.h"],
3216             body="pthread_cond_timedwait_monotonic_np(0, 0, 0);",
3217             # -Werror to catch any "implicit declaration" warning that means the function
3218             # is not supported.
3219             flags=["-Werror=implicit-function-declaration"],
3220             check_msg="for pthread_cond_timedwait_monotonic_np",
3221         ),
3222     )
3225 # Custom dynamic linker for Android
3226 # ==============================================================
3227 with only_when(target_has_linux_kernel & compile_environment):
3228     option(
3229         env="MOZ_LINKER",
3230         default=depends(target.os, when="--enable-jemalloc")(
3231             lambda os: os == "Android"
3232         ),
3233         help="{Enable|Disable} custom dynamic linker",
3234     )
3236     set_config("MOZ_LINKER", True, when="MOZ_LINKER")
3237     set_define("MOZ_LINKER", True, when="MOZ_LINKER")
3238     add_old_configure_assignment("MOZ_LINKER", True, when="MOZ_LINKER")
3240     moz_linker = depends(when="MOZ_LINKER")(lambda: True)
3243 # 32-bits ethtool_cmd.speed
3244 # ==============================================================
3245 with only_when(target_has_linux_kernel & compile_environment):
3246     set_config(
3247         "MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI",
3248         c_compiler.try_compile(
3249             includes=["linux/ethtool.h"],
3250             body="struct ethtool_cmd cmd; cmd.speed_hi = 0;",
3251             check_msg="for 32-bits ethtool_cmd.speed",
3252         ),
3253     )
3255 # Gamepad support
3256 # ==============================================================
3257 check_header(
3258     "linux/joystick.h",
3259     onerror=lambda: die(
3260         "Can't find header linux/joystick.h, needed for gamepad support."
3261         " Please install Linux kernel headers."
3262     ),
3263     when=target_has_linux_kernel & compile_environment,
3266 # Smart card support
3267 # ==============================================================
3268 @depends(build_project)
3269 def disable_smart_cards(build_project):
3270     return build_project == "mobile/android"
3273 set_config("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3274 set_define("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3276 # Enable UniFFI fixtures
3277 # ==============================================================
3278 # These are used to test the uniffi-bindgen-gecko-js code generation.  They
3279 # should not be enabled in release builds.
3281 option(
3282     "--enable-uniffi-fixtures",
3283     help="Enable UniFFI Fixtures/Examples",
3286 set_config("MOZ_UNIFFI_FIXTURES", True, when="--enable-uniffi-fixtures")
3288 # Checks for library functions
3289 # ==============================================================
3290 with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
3291     set_define("HAVE_STAT64", check_symbol("stat64"))
3292     set_define("HAVE_LSTAT64", check_symbol("lstat64"))
3293     set_define("HAVE_TRUNCATE64", check_symbol("truncate64"))
3294     set_define("HAVE_STATVFS64", check_symbol("statvfs64"))
3295     set_define("HAVE_STATVFS", check_symbol("statvfs"))
3296     set_define("HAVE_STATFS64", check_symbol("statfs64"))
3297     set_define("HAVE_STATFS", check_symbol("statfs"))
3298     set_define("HAVE_LUTIMES", check_symbol("lutimes"))
3299     set_define("HAVE_POSIX_FADVISE", check_symbol("posix_fadvise"))
3300     set_define("HAVE_POSIX_FALLOCATE", check_symbol("posix_fallocate"))
3302     set_define("HAVE_ARC4RANDOM", check_symbol("arc4random"))
3303     set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf"))
3304     set_define("HAVE_MALLINFO", check_symbol("mallinfo"))
3306 # System policies
3307 # ==============================================================
3309 option(
3310     "--disable-system-policies",
3311     help="Disable reading policies from Windows registry, macOS's file system attributes, and /etc/firefox",
3314 set_config("MOZ_SYSTEM_POLICIES", True, when="--enable-system-policies")