Bug 1837494 [wpt PR 40457] - Ignore urllib3's warnings when run on LibreSSL, a=testonly
[gecko.git] / toolkit / moz.configure
blobc518e02d00534379b24107c91ecfac25952df9d0
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 imply_option("--enable-profiling", dmd)
167 imply_option("--enable-jemalloc", dmd, when=compile_environment)
168 imply_option("--enable-replace-malloc", dmd, when=compile_environment)
170 # midir-based Web MIDI support
171 # ==============================================================
172 @depends(target)
173 def midir_linux_support(target):
174     return (
175         target.kernel == "Linux" and target.os != "Android" and target.cpu != "riscv64"
176     )
179 @depends(target, midir_linux_support)
180 def midir_support(target, midir_linux_support):
181     if target.os in ("WINNT", "OSX") or midir_linux_support:
182         return True
185 set_config("MOZ_WEBMIDI_MIDIR_IMPL", midir_support)
187 # Enable various cubeb backends
188 # ==============================================================
189 @depends(target)
190 def audio_backends_default(target):
191     if target.os == "Android":
192         return (
193             "aaudio",
194             "opensl",
195         )
196     elif target.os in ("DragonFly", "FreeBSD", "SunOS"):
197         return ("oss",)
198     elif target.os == "OpenBSD":
199         return ("sndio",)
200     elif target.os == "OSX":
201         return ("audiounit",)
202     elif target.os == "NetBSD":
203         return ("sunaudio",)
204     elif target.os == "SunOS":
205         return ("sunaudio",)
206     elif target.os == "WINNT":
207         return ("wasapi",)
208     else:
209         return ("pulseaudio",)
212 option(
213     "--enable-audio-backends",
214     nargs="+",
215     choices=(
216         "aaudio",
217         "alsa",
218         "audiounit",
219         "jack",
220         "opensl",
221         "oss",
222         "pulseaudio",
223         "sndio",
224         "sunaudio",
225         "wasapi",
226     ),
227     default=audio_backends_default,
228     help="{Enable|Disable} various cubeb backends",
232 @depends("--enable-audio-backends", target)
233 def imply_aaudio(values, target):
234     if any("aaudio" in value for value in values) and target.os != "Android":
235         die("Cannot enable AAudio on %s", target.os)
236     return any("aaudio" in value for value in values) or None
239 @depends("--enable-audio-backends", target)
240 def imply_alsa(values, target):
241     if (
242         any("alsa" in value for value in values)
243         and target.kernel != "Linux"
244         and target.os != "FreeBSD"
245     ):
246         die("Cannot enable ALSA on %s", target.os)
247     return any("alsa" in value for value in values) or None
250 @depends("--enable-audio-backends", target)
251 def imply_audiounit(values, target):
252     if (
253         any("audiounit" in value for value in values)
254         and target.os != "OSX"
255         and target.kernel != "Darwin"
256     ):
257         die("Cannot enable AudioUnit on %s", target.os)
258     return any("audiounit" in value for value in values) or None
261 @depends("--enable-audio-backends")
262 def imply_jack(values):
263     return any("jack" in value for value in values) or None
266 @depends("--enable-audio-backends", target)
267 def imply_opensl(values, target):
268     if any("opensl" in value for value in values) and target.os != "Android":
269         die("Cannot enable OpenSL on %s", target.os)
270     return any("opensl" in value for value in values) or None
273 @depends("--enable-audio-backends", target)
274 def imply_oss(values, target):
275     if any("oss" in value for value in values) and (
276         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
277     ):
278         die("Cannot enable OSS on %s", target.os)
279     return any("oss" in value for value in values) or None
282 @depends("--enable-audio-backends", target)
283 def imply_pulseaudio(values, target):
284     if any("pulseaudio" in value for value in values) and (
285         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
286     ):
287         die("Cannot enable PulseAudio on %s", target.os)
288     return any("pulseaudio" in value for value in values) or None
291 @depends("--enable-audio-backends", target)
292 def imply_sndio(values, target):
293     if any("sndio" in value for value in values) and (
294         target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
295     ):
296         die("Cannot enable sndio on %s", target.os)
297     return any("sndio" in value for value in values) or None
300 @depends("--enable-audio-backends", target)
301 def imply_sunaudio(values, target):
302     if any("sunaudio" in value for value in values) and (
303         target.os != "NetBSD" and target.os != "SunOS"
304     ):
305         die("Cannot enable sunaudio on %s", target.os)
306     return any("sunaudio" in value for value in values) or None
309 @depends("--enable-audio-backends", target)
310 def imply_wasapi(values, target):
311     if any("wasapi" in value for value in values) and target.os != "WINNT":
312         die("Cannot enable WASAPI on %s", target.os)
313     return any("wasapi" in value for value in values) or None
316 set_config("MOZ_AAUDIO", imply_aaudio, when="--enable-audio-backends")
318 imply_option("--enable-alsa", imply_alsa, reason="--enable-audio-backends")
320 set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")
322 imply_option("--enable-jack", imply_jack, reason="--enable-audio-backends")
324 set_config("MOZ_OPENSL", imply_opensl, when="--enable-audio-backends")
326 set_config("MOZ_OSS", imply_oss, when="--enable-audio-backends")
328 imply_option("--enable-pulseaudio", imply_pulseaudio, reason="--enable-audio-backends")
330 imply_option("--enable-sndio", imply_sndio, reason="--enable-audio-backends")
332 set_config("MOZ_SUNAUDIO", imply_sunaudio, when="--enable-audio-backends")
334 set_config("MOZ_WASAPI", imply_wasapi, when="--enable-audio-backends")
336 # ALSA cubeb backend
337 # ==============================================================
338 option("--enable-alsa", env="MOZ_ALSA", help="Enable ALSA audio backend.")
341 @depends("--enable-alsa", midir_linux_support)
342 def enable_alsa_or_midir_linux_support(alsa_enabled, midir_linux_support):
343     return alsa_enabled or midir_linux_support
346 pkg_check_modules("MOZ_ALSA", "alsa", when=enable_alsa_or_midir_linux_support)
348 set_config("MOZ_ALSA", True, when="--enable-alsa")
349 set_define("MOZ_ALSA", True, when="--enable-alsa")
351 # JACK cubeb backend
352 # ==============================================================
353 system_lib_option("--enable-jack", env="MOZ_JACK", help="Enable JACK audio backend.")
355 jack = pkg_check_modules("MOZ_JACK", "jack", when="--enable-jack")
357 set_config("MOZ_JACK", depends_if(jack)(lambda _: True))
359 # PulseAudio cubeb backend
360 # ==============================================================
361 option(
362     "--enable-pulseaudio",
363     env="MOZ_PULSEAUDIO",
364     help="{Enable|Disable} PulseAudio audio backend.",
367 pulseaudio = pkg_check_modules("MOZ_PULSEAUDIO", "libpulse", when="--enable-pulseaudio")
369 set_config("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
370 set_define("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
372 # sndio cubeb backend
373 # ==============================================================
374 system_lib_option("--enable-sndio", env="MOZ_SNDIO", help="Enable sndio audio backend.")
376 sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
378 set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
380 # Javascript engine
381 # ==============================================================
382 include("../js/moz.configure")
385 # NodeJS
386 # ==============================================================
387 include("../build/moz.configure/node.configure")
389 # JsonCpp
390 # ==============================================================
391 set_define("JSON_USE_EXCEPTION", 0)
393 # L10N
394 # ==============================================================
395 option("--with-l10n-base", nargs=1, env="L10NBASEDIR", help="Path to l10n repositories")
398 @depends("--with-l10n-base", "MOZ_AUTOMATION", build_environment)
399 @imports(_from="os.path", _import="isdir")
400 @imports(_from="os.path", _import="expanduser")
401 @imports(_from="os", _import="environ")
402 def l10n_base(value, automation, build_env):
403     if value:
404         path = value[0]
405         if not isdir(path):
406             die("Invalid value --with-l10n-base, %s doesn't exist", path)
407     elif automation:
408         path = os.path.join(build_env.topsrcdir, "../l10n-central")
409     else:
410         path = os.path.join(
411             environ.get(
412                 "MOZBUILD_STATE_PATH", expanduser(os.path.join("~", ".mozbuild"))
413             ),
414             "l10n-central",
415         )
416     return os.path.realpath(os.path.abspath(path))
419 set_config("L10NBASEDIR", l10n_base)
422 # Default toolkit
423 # ==============================================================
424 @depends(target)
425 def toolkit_choices(target):
426     if target.os == "WINNT":
427         return ("cairo-windows",)
428     elif target.os == "OSX":
429         return ("cairo-cocoa",)
430     elif target.os == "Android":
431         return ("cairo-android",)
432     else:
433         return (
434             "cairo-gtk3",
435             "cairo-gtk3-wayland",
436             "cairo-gtk3-wayland-only",
437             "cairo-gtk3-x11-wayland",
438         )
441 @depends(toolkit_choices)
442 def toolkit_default(choices):
443     return choices[0]
446 option(
447     "--enable-default-toolkit",
448     nargs=1,
449     choices=toolkit_choices,
450     default=toolkit_default,
451     help="Select default toolkit",
455 @depends("--enable-default-toolkit")
456 def full_toolkit(value):
457     if value:
458         return value[0]
461 @depends(full_toolkit)
462 def toolkit(toolkit):
463     if toolkit.startswith("cairo-gtk3"):
464         widget_toolkit = "gtk"
465     else:
466         widget_toolkit = toolkit.replace("cairo-", "")
467     return widget_toolkit
470 set_config("MOZ_WIDGET_TOOLKIT", toolkit)
471 add_old_configure_assignment("MOZ_WIDGET_TOOLKIT", toolkit)
474 @depends(toolkit)
475 def toolkit_define(toolkit):
476     if toolkit != "windows":
477         return "MOZ_WIDGET_%s" % toolkit.upper()
480 set_define(toolkit_define, True)
483 @depends(toolkit)
484 def toolkit_gtk(toolkit):
485     return toolkit == "gtk"
488 # Wayland support
489 # ==============================================================
490 wayland_headers = pkg_check_modules(
491     "MOZ_WAYLAND",
492     "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1",
493     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3"),
494     when=toolkit_gtk,
498 @depends(wayland_headers, toolkit_gtk, artifact_builds)
499 def wayland_headers(wayland, toolkit_gtk, artifacts):
500     if toolkit_gtk and artifacts:
501         return True
502     return wayland
505 set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
506 set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
508 # Hardware-accelerated video decode with VAAPI and V4L2
509 # ==============================================================
512 @depends(target, wayland_headers)
513 def vaapi(target, wayland_headers):
514     # VAAPI is only used in Wayland. It's mostly used on x86(-64) but is
515     # sometimes used on ARM/ARM64 SOCs. Wayland implies GTK and Linux.
516     if target.cpu in ("arm", "aarch64", "x86", "x86_64") and wayland_headers:
517         return True
520 @depends(target, wayland_headers)
521 def v4l2(target, wayland_headers):
522     # V4L2 decode is only used in Wayland, and generally only appears on
523     # embedded SOCs. Wayland implies GTK and Linux.
524     if target.cpu in ("arm", "aarch64", "riscv64") and wayland_headers:
525         return True
528 set_config("MOZ_ENABLE_VAAPI", True, when=vaapi)
529 set_config("MOZ_ENABLE_V4L2", True, when=v4l2)
530 set_define("MOZ_ENABLE_VAAPI", True, when=vaapi)
531 set_define("MOZ_ENABLE_V4L2", True, when=v4l2)
533 # GL Provider
534 # ==============================================================
535 option("--with-gl-provider", nargs=1, help="Set GL provider backend type")
538 @depends("--with-gl-provider")
539 def gl_provider(value):
540     if value:
541         return value[0]
544 @depends(gl_provider)
545 def gl_provider_define(provider):
546     if provider:
547         return "GLContextProvider%s" % provider
550 set_define("MOZ_GL_PROVIDER", gl_provider_define)
553 @depends(gl_provider, toolkit_gtk)
554 def gl_default_provider(value, toolkit_gtk):
555     if value:
556         return value
557     elif toolkit_gtk:
558         return "EGL"
561 set_config("MOZ_GL_PROVIDER", gl_provider)
562 set_config("MOZ_GL_DEFAULT_PROVIDER", gl_default_provider)
565 @depends(gl_default_provider)
566 def gl_provider_define(provider):
567     if provider:
568         return "GL_PROVIDER_%s" % provider
571 set_define(gl_provider_define, True)
574 # PDF printing
575 # ==============================================================
576 @depends(toolkit)
577 def pdf_printing(toolkit):
578     if toolkit in ("windows", "gtk", "android"):
579         return True
582 set_config("MOZ_PDF_PRINTING", pdf_printing)
583 set_define("MOZ_PDF_PRINTING", pdf_printing)
586 # Event loop instrumentation
587 # ==============================================================
588 option(env="MOZ_INSTRUMENT_EVENT_LOOP", help="Force-enable event loop instrumentation")
591 @depends("MOZ_INSTRUMENT_EVENT_LOOP", toolkit)
592 def instrument_event_loop(value, toolkit):
593     if value or (
594         toolkit in ("windows", "gtk", "cocoa", "android") and value.origin == "default"
595     ):
596         return True
599 set_config("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
600 set_define("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
603 # Fontconfig Freetype
604 # ==============================================================
605 option(env="USE_FC_FREETYPE", help="Force-enable the use of fontconfig freetype")
608 @depends("USE_FC_FREETYPE", toolkit)
609 def fc_freetype(value, toolkit):
610     if value or (toolkit == "gtk" and value.origin == "default"):
611         return True
614 set_define("USE_FC_FREETYPE", fc_freetype)
616 # Pango
617 # ==============================================================
618 pkg_check_modules("MOZ_PANGO", "pango >= 1.22.0", when=toolkit_gtk)
620 # Fontconfig
621 # ==============================================================
622 fontconfig_info = pkg_check_modules(
623     "_FONTCONFIG", "fontconfig >= 2.7.0", when=fc_freetype
627 @depends(fc_freetype)
628 def check_for_freetype2(fc_freetype):
629     if fc_freetype:
630         return True
633 # Check for freetype2. Flags are combined with fontconfig flags.
634 freetype2_info = pkg_check_modules(
635     "_FT2", "freetype2 >= 9.10.3", when=check_for_freetype2
639 @depends(fontconfig_info, freetype2_info)
640 def freetype2_combined_info(fontconfig_info, freetype2_info):
641     if not freetype2_info:
642         return
643     if not fontconfig_info:
644         return freetype2_info
645     return namespace(
646         cflags=freetype2_info.cflags + fontconfig_info.cflags,
647         libs=freetype2_info.libs + fontconfig_info.libs,
648     )
651 set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
653 # Apple platform decoder support
654 # ==============================================================
655 @depends(toolkit)
656 def applemedia(toolkit):
657     if toolkit in ("cocoa", "uikit"):
658         return True
661 set_config("MOZ_APPLEMEDIA", applemedia)
662 set_define("MOZ_APPLEMEDIA", applemedia)
664 # Windows Media Foundation support
665 # ==============================================================
666 option("--disable-wmf", help="Disable support for Windows Media Foundation")
669 @depends("--disable-wmf", target, "--help")
670 def wmf(value, target, _):
671     enabled = bool(value)
672     if value.origin == "default":
673         # Enable Windows Media Foundation support by default.
674         # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
675         # guaranteed to have a recent-enough SDK to build WMF.
676         enabled = target.os == "WINNT"
677     if enabled and target.os != "WINNT":
678         die("Cannot enable Windows Media Foundation support on %s", target.os)
679     if enabled:
680         return True
683 @depends(c_compiler, when=wmf)
684 def wmfmediaengine(c_compiler):
685     return c_compiler and c_compiler.type == "clang-cl"
688 set_config("MOZ_WMF", wmf)
689 set_define("MOZ_WMF", wmf)
691 set_config("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
692 set_define("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
694 # FFmpeg H264/AAC Decoding Support
695 # ==============================================================
696 option("--disable-ffmpeg", help="Disable FFmpeg for fragmented H264/AAC decoding")
699 @depends("--disable-ffmpeg", target)
700 def ffmpeg(value, target):
701     enabled = bool(value)
702     if value.origin == "default":
703         enabled = target.os not in ("Android", "WINNT")
704     if enabled:
705         return True
708 set_config("MOZ_FFMPEG", ffmpeg)
709 set_define("MOZ_FFMPEG", ffmpeg)
710 imply_option("--enable-fmp4", ffmpeg, "--enable-ffmpeg")
712 # AV1 Video Codec Support
713 # ==============================================================
714 option("--disable-av1", help="Disable av1 video support")
717 @depends("--enable-av1")
718 def av1(value):
719     if value:
720         return True
723 @depends(target, when=av1 & compile_environment)
724 def dav1d_asm(target):
725     if target.cpu in ("aarch64", "x86", "x86_64"):
726         return True
729 @depends(target, when=av1 & compile_environment)
730 def dav1d_nasm(target):
731     if target.cpu in ("x86", "x86_64"):
732         return namespace(version="2.14", what="AV1")
735 set_config("MOZ_DAV1D_ASM", dav1d_asm)
736 set_define("MOZ_DAV1D_ASM", dav1d_asm)
737 set_config("MOZ_AV1", av1)
738 set_define("MOZ_AV1", av1)
740 # JXL Image Codec Support
741 # ==============================================================
742 option("--disable-jxl", help="Disable jxl image support")
745 @depends("--disable-jxl", milestone.is_nightly)
746 def jxl(value, is_nightly):
747     if is_nightly and value:
748         return True
751 set_config("MOZ_JXL", jxl)
752 set_define("MOZ_JXL", jxl)
754 # Built-in fragmented MP4 support.
755 # ==============================================================
756 option(
757     "--disable-fmp4",
758     env="MOZ_FMP4",
759     help="Disable support for in built Fragmented MP4 parsing",
763 @depends("--disable-fmp4", target, wmf, applemedia)
764 def fmp4(value, target, wmf, applemedia):
765     enabled = bool(value)
766     if value.origin == "default":
767         # target.os == 'Android' includes all B2G versions
768         enabled = wmf or applemedia or target.os == "Android"
769     if enabled:
770         return True
773 set_config("MOZ_FMP4", fmp4)
774 set_define("MOZ_FMP4", fmp4)
777 @depends(target)
778 def sample_type_is_s16(target):
779     # Use integers over floats for audio on Android regardless of the CPU
780     # architecture, because audio backends for Android don't support floats.
781     # We also use integers on ARM because it's more efficient.
782     if target.os == "Android" or target.cpu == "arm":
783         return True
786 @depends(sample_type_is_s16)
787 def sample_type_is_float(t):
788     if not t:
789         return True
792 set_config("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
793 set_define("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16)
794 set_config("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
795 set_define("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float)
797 set_define("MOZ_VORBIS", sample_type_is_float)
798 set_config("MOZ_VORBIS", sample_type_is_float)
799 set_define("MOZ_TREMOR", sample_type_is_s16)
800 set_config("MOZ_TREMOR", sample_type_is_s16)
802 option(
803     "--disable-real-time-tracing",
804     help="Disable tracing of real-time audio callbacks",
807 set_config("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
808 set_define("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
810 # OpenMAX IL Decoding Support
811 # ==============================================================
812 option("--enable-openmax", help="Enable OpenMAX IL for video/audio decoding")
815 @depends("--enable-openmax")
816 def openmax(value):
817     enabled = bool(value)
818     if enabled:
819         return True
822 set_config("MOZ_OMX", openmax)
823 set_define("MOZ_OMX", openmax)
825 # EME Support
826 # ==============================================================
827 @depends(target, wmf)
828 def eme_choices(target, wmf):
829     if (
830         target.kernel in ("WINNT", "Linux")
831         and target.os != "Android"
832         and target.cpu in ("x86", "x86_64")
833     ):
834         if wmf:
835             return ("widevine", "wmfcdm")
836         return ("widevine",)
837     if target.kernel == "WINNT" and target.cpu == "aarch64":
838         return ("widevine",)
839     if target.os in ("OSX"):
840         return ("widevine",)
843 # Widevine is enabled by default in desktop browser builds, except
844 # on aarch64 Windows.
845 @depends(build_project, eme_choices, target)
846 def eme_default(build_project, choices, target):
847     if build_project == "browser":
848         if target.kernel != "WINNT" or target.cpu != "aarch64":
849             return choices
852 option(
853     "--enable-eme",
854     nargs="+",
855     choices=eme_choices,
856     default=eme_default,
857     when=eme_choices,
858     help="{Enable|Disable} support for Encrypted Media Extensions",
862 @depends("--enable-eme", fmp4, when=eme_choices)
863 def eme(enabled, fmp4):
864     if enabled and enabled.origin != "default" and not fmp4:
865         die("Encrypted Media Extension support requires " "Fragmented MP4 support")
868 @depends("--enable-eme", when=eme_choices)
869 def eme_modules(value):
870     return value
873 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
874 # None.
875 set_config("MOZ_EME_MODULES", eme_modules | dependable([]))
878 @depends(eme_modules, target, when=eme_modules)
879 def eme_win32_artifact(modules, target):
880     if "widevine" in modules and target.kernel == "WINNT" and target.cpu == "aarch64":
881         return True
884 set_config("MOZ_EME_WIN32_ARTIFACT", eme_win32_artifact)
887 # Media Foundation CDM support
888 # ==============================================================
889 @depends(eme_modules, when=wmfmediaengine)
890 def wmfcdm(modules):
891     if "wmfcdm" in modules:
892         return True
895 set_config("MOZ_WMF_CDM", True, when=wmfcdm)
896 set_define("MOZ_WMF_CDM", True, when=wmfcdm)
899 option(
900     name="--enable-chrome-format",
901     help="Select FORMAT of chrome files during packaging.",
902     nargs=1,
903     choices=("omni", "jar", "flat"),
904     default="omni",
908 @depends("--enable-chrome-format")
909 def packager_format(value):
910     return value[0]
913 set_config("MOZ_PACKAGER_FORMAT", packager_format)
915 # The packager minifies two different types of files: non-JS (mostly property
916 # files for l10n), and JS.  Setting MOZ_PACKAGER_MINIFY only minifies the
917 # former.  Firefox doesn't yet minify JS, due to concerns about debuggability.
919 # Also, the JS minification setup really only works correctly on Android:
920 # we need extra setup to use the newly-built shell for Linux and Windows,
921 # and cross-compilation for macOS requires some extra care.
924 @depends(target_is_android, "--enable-debug", milestone.is_nightly)
925 def enable_minify_default(is_android, debug, is_nightly):
926     if is_android and not debug and not is_nightly:
927         return ("properties", "js")
928     return ("properties",)
931 option(
932     name="--enable-minify",
933     help="Select types of files to minify during packaging.",
934     nargs="*",
935     choices=("properties", "js"),
936     default=enable_minify_default,
940 @depends("--enable-minify")
941 def enable_minify(value):
942     if "js" in value and "properties" not in value:
943         die("--enable-minify=js requires --enable-minify=properties.")
944     return namespace(
945         properties="properties" in value,
946         js="js" in value,
947     )
950 set_config("MOZ_PACKAGER_MINIFY", True, when=enable_minify.properties)
951 set_config("MOZ_PACKAGER_MINIFY_JS", True, when=enable_minify.js)
954 @depends(host, build_project)
955 def jar_maker_format(host, build_project):
956     # Multilocales for mobile/android use the same mergedirs for all locales,
957     # so we can't use symlinks for those builds.
958     if host.os == "WINNT" or build_project == "mobile/android":
959         return "flat"
960     return "symlink"
963 set_config("MOZ_JAR_MAKER_FILE_FORMAT", jar_maker_format)
966 @depends(toolkit)
967 def omnijar_name(toolkit):
968     # Fennec's static resources live in the assets/ folder of the
969     # APK.  Adding a path to the name here works because we only
970     # have one omnijar file in the final package (which is not the
971     # case on desktop).
972     return "assets/omni.ja" if toolkit == "android" else "omni.ja"
975 set_config("OMNIJAR_NAME", omnijar_name)
977 project_flag("MOZ_PLACES", help="Build Places if required", set_as_define=True)
979 project_flag(
980     "MOZ_SERVICES_HEALTHREPORT",
981     help="Build Firefox Health Reporter Service",
982     set_as_define=True,
985 project_flag(
986     "MOZ_NORMANDY",
987     help="Enable Normandy recipe runner",
988     set_as_define=True,
991 project_flag("MOZ_SERVICES_SYNC", help="Build Sync Services if required")
993 project_flag(
994     "MOZ_ANDROID_HISTORY",
995     help="Enable Android History instead of Places",
996     set_as_define=True,
999 project_flag(
1000     "MOZ_DEDICATED_PROFILES",
1001     help="Enable dedicated profiles per install",
1002     set_as_define=True,
1005 project_flag(
1006     "MOZ_BLOCK_PROFILE_DOWNGRADE",
1007     help="Block users from starting profiles last used by a newer build",
1008     set_as_define=True,
1012 @depends("MOZ_PLACES", "MOZ_ANDROID_HISTORY")
1013 def check_places_and_android_history(places, android_history):
1014     if places and android_history:
1015         die("Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.")
1018 option(
1019     env="MOZ_TELEMETRY_REPORTING",
1020     default=mozilla_official,
1021     help="Enable telemetry reporting",
1024 set_define("MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING")
1027 @depends("MOZ_TELEMETRY_REPORTING", milestone.is_nightly)
1028 def telemetry_on_by_default(reporting, is_nightly):
1029     return reporting and is_nightly
1032 set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
1035 # gpsd support
1036 # ==============================================================
1037 system_lib_option("--enable-gpsd", env="MOZ_GPSD", help="Enable gpsd support")
1040 @depends("--enable-gpsd")
1041 def gpsd(value):
1042     return bool(value)
1045 system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
1047 set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
1049 # Miscellaneous programs
1050 # ==============================================================
1052 check_prog("TAR", ("gnutar", "gtar", "tar"))
1053 check_prog("UNZIP", ("unzip",))
1055 # Key files
1056 # ==============================================================
1057 include("../build/moz.configure/keyfiles.configure")
1059 simple_keyfile("Mozilla API")
1061 simple_keyfile("Google Location Service API")
1063 simple_keyfile("Google Safebrowsing API")
1065 id_and_secret_keyfile("Bing API")
1067 simple_keyfile("Adjust SDK")
1069 id_and_secret_keyfile("Leanplum SDK")
1071 simple_keyfile("Pocket API")
1074 # WebRender Debugger integration
1075 # ==============================================================
1077 option(
1078     "--enable-webrender-debugger", help="Build the websocket debug server in WebRender"
1081 set_config(
1082     "MOZ_WEBRENDER_DEBUGGER", depends_if("--enable-webrender-debugger")(lambda _: True)
1085 # Additional system headers defined at the application level
1086 # ==============================================================
1088 option(
1089     "--enable-app-system-headers",
1090     env="MOZ_APP_SYSTEM_HEADERS",
1091     help="Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild",
1095 @depends("--enable-app-system-headers")
1096 def app_system_headers(value):
1097     if value:
1098         return True
1101 set_config("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1102 set_define("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
1104 # Printing
1105 # ==============================================================
1106 option("--disable-printing", help="Disable printing support")
1109 @depends("--disable-printing")
1110 def printing(value):
1111     if value:
1112         return True
1115 set_config("NS_PRINTING", printing)
1116 set_define("NS_PRINTING", printing)
1117 set_define("NS_PRINT_PREVIEW", printing)
1119 # Speech-dispatcher support
1120 # ==============================================================
1121 @depends(toolkit)
1122 def no_speechd_on_non_gtk(toolkit):
1123     if toolkit != "gtk":
1124         return False
1127 imply_option(
1128     "--enable-synth-speechd", no_speechd_on_non_gtk, reason="--enable-default-toolkit"
1131 option("--disable-synth-speechd", help="Disable speech-dispatcher support")
1133 set_config("MOZ_SYNTH_SPEECHD", depends_if("--disable-synth-speechd")(lambda _: True))
1135 # Speech API
1136 # ==============================================================
1137 option("--disable-webspeech", help="Disable support for HTML Speech API")
1140 @depends("--disable-webspeech")
1141 def webspeech(value):
1142     if value:
1143         return True
1146 set_config("MOZ_WEBSPEECH", webspeech)
1147 set_define("MOZ_WEBSPEECH", webspeech)
1149 # Speech API test backend
1150 # ==============================================================
1151 option(
1152     "--enable-webspeechtestbackend",
1153     default=webspeech,
1154     help="{Enable|Disable} support for HTML Speech API Test Backend",
1158 @depends_if("--enable-webspeechtestbackend")
1159 def webspeech_test_backend(value):
1160     return True
1163 set_config("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1164 set_define("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
1166 # Graphics
1167 # ==============================================================
1168 @depends(target, milestone)
1169 def skia_pdf_default(target, milestone):
1170     return milestone.is_nightly and target.os != "WINNT"
1173 option("--enable-skia-pdf", default=skia_pdf_default, help="{Enable|Disable} Skia PDF")
1175 set_config("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1176 set_define("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
1178 set_config(
1179     "SKIA_INCLUDES",
1180     [
1181         "/gfx/skia",
1182         "/gfx/skia/skia",
1183     ],
1186 system_lib_option(
1187     "--with-system-webp", help="Use system libwebp (located with pkgconfig)"
1190 system_webp = pkg_check_modules(
1191     "MOZ_WEBP", "libwebp >= 1.0.2 libwebpdemux >= 1.0.2", when="--with-system-webp"
1194 set_config("MOZ_SYSTEM_WEBP", depends(when=system_webp)(lambda: True))
1196 # Build Freetype in the tree
1197 # ==============================================================
1198 @depends(target, "--enable-skia-pdf")
1199 def tree_freetype(target, skia_pdf):
1200     if target.os == "Android" or (skia_pdf and target.os == "WINNT"):
1201         return True
1204 set_define("MOZ_TREE_FREETYPE", tree_freetype)
1205 set_config("MOZ_TREE_FREETYPE", tree_freetype)
1207 set_define("HAVE_FT_BITMAP_SIZE_Y_PPEM", tree_freetype)
1208 set_define("HAVE_FT_GLYPHSLOT_EMBOLDEN", tree_freetype)
1209 set_define("HAVE_FT_LOAD_SFNT_TABLE", tree_freetype)
1212 @depends(freetype2_combined_info, tree_freetype, build_environment)
1213 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
1214     if tree_freetype:
1215         return namespace(
1216             cflags=("-I%s/modules/freetype2/include" % build_env.topsrcdir,), libs=()
1217         )
1218     if freetype2_combined_info:
1219         return freetype2_combined_info
1222 set_config("FT2_LIBS", ft2_info.libs)
1225 @depends(target, tree_freetype, freetype2_info)
1226 def enable_cairo_ft(target, tree_freetype, freetype2_info):
1227     # Avoid defining MOZ_ENABLE_CAIRO_FT on Windows platforms because
1228     # "cairo-ft-font.c" includes <dlfcn.h>, which only exists on posix platforms
1229     return freetype2_info or (tree_freetype and target.os != "WINNT")
1232 set_config("MOZ_ENABLE_CAIRO_FT", True, when=enable_cairo_ft)
1233 set_config("CAIRO_FT_CFLAGS", ft2_info.cflags, when=enable_cairo_ft)
1236 # WebDriver (HTTP / BiDi)
1237 # ==============================================================
1239 # WebDriver is a remote control interface that enables introspection and
1240 # control of user agents. It provides a platform- and language-neutral wire
1241 # protocol as a way for out-of-process programs to remotely instruct the
1242 # behavior of web browsers.
1244 # The Gecko implementation is backed by Marionette and Remote Agent.
1245 # Both protocols are not really toolkit features, as much as Gecko engine
1246 # features. But they are enabled based on the toolkit, so here it lives.
1248 # Marionette remote protocol
1249 # -----------------------------------------------------------
1251 # Marionette is the Gecko remote protocol used for various remote control,
1252 # automation, and testing purposes throughout Gecko-based applications like
1253 # Firefox, Thunderbird, and any mobile browser built upon GeckoView.
1255 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
1256 # implementation.
1258 # The source of Marionette lives in ../remote/marionette.
1260 # For more information, see:
1261 # https://firefox-source-docs.mozilla.org/testing/marionette/index.html
1263 # Remote Agent (WebDriver BiDi / partial CDP)
1264 # -----------------------------------------------------------
1266 # The primary purpose is the implementation of the WebDriver BiDi specification.
1267 # But it also complements the existing Firefox Developer Tools Remote Debugging
1268 # Protocol (RDP) by implementing a subset of the Chrome DevTools Protocol (CDP).
1270 # The source of Remote Agent lives in ../remote.
1272 # For more information, see:
1273 # https://firefox-source-docs.mozilla.org/remote/index.html
1276 option(
1277     "--disable-webdriver",
1278     help="Disable support for WebDriver remote protocols",
1282 @depends("--disable-webdriver")
1283 def webdriver(enabled):
1284     if enabled:
1285         return True
1288 set_config("ENABLE_WEBDRIVER", webdriver)
1289 set_define("ENABLE_WEBDRIVER", webdriver)
1292 # geckodriver WebDriver implementation
1293 # ==============================================================
1295 # Turn off geckodriver for build configs we don't handle yet,
1296 # but allow --enable-geckodriver to override when compile environment is available.
1297 # --disable-tests implies disabling geckodriver.
1298 # Disable building in CI
1301 @depends(
1302     "--enable-tests", target, cross_compiling, hazard_analysis, asan, "MOZ_AUTOMATION"
1304 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
1305     if not enable_tests:
1306         return False
1307     if hazard or target.os == "Android" or (asan and cross_compile):
1308         return False
1309     if automation:
1310         return False
1311     return True
1314 option(
1315     "--enable-geckodriver",
1316     default=geckodriver_default,
1317     when="--enable-compile-environment",
1318     help="{Build|Do not build} geckodriver",
1322 @depends("--enable-geckodriver", when="--enable-compile-environment")
1323 def geckodriver(enabled):
1324     if enabled:
1325         return True
1328 set_config("MOZ_GECKODRIVER", geckodriver)
1331 # WebRTC
1332 # ========================================================
1333 @depends(target)
1334 def webrtc_default(target):
1335     # Turn off webrtc for OS's we don't handle yet, but allow
1336     # --enable-webrtc to override.
1337     os_match = False
1338     for os_fragment in (
1339         "linux",
1340         "mingw",
1341         "android",
1342         "linuxandroid",
1343         "dragonfly",
1344         "freebsd",
1345         "netbsd",
1346         "openbsd",
1347         "darwin",
1348     ):
1349         if target.raw_os.startswith(os_fragment):
1350             os_match = True
1352     cpu_match = False
1353     if (
1354         target.cpu
1355         in (
1356             "x86_64",
1357             "arm",
1358             "aarch64",
1359             "x86",
1360             "ia64",
1361             "mips32",
1362             "mips64",
1363         )
1364         or target.cpu.startswith("ppc")
1365     ):
1366         cpu_match = True
1368     if os_match and cpu_match:
1369         return True
1370     return False
1373 option(
1374     "--disable-webrtc",
1375     default=webrtc_default,
1376     help="{Enable|Disable} support for WebRTC",
1380 @depends("--disable-webrtc")
1381 def webrtc(enabled):
1382     if enabled:
1383         return True
1386 set_config("MOZ_WEBRTC", webrtc)
1387 set_define("MOZ_WEBRTC", webrtc)
1388 set_config("MOZ_SCTP", webrtc)
1389 set_define("MOZ_SCTP", webrtc)
1390 set_config("MOZ_SRTP", webrtc)
1391 set_define("MOZ_SRTP", webrtc)
1392 set_config("MOZ_WEBRTC_SIGNALING", webrtc)
1393 set_define("MOZ_WEBRTC_SIGNALING", webrtc)
1394 set_config("MOZ_PEERCONNECTION", webrtc)
1395 set_define("MOZ_PEERCONNECTION", webrtc)
1396 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1397 # opt/production builds (via MOZ_CRASH())
1398 set_config("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1399 set_define("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
1401 # RAW media
1402 # ==============================================================
1405 @depends(target, webrtc)
1406 def raw_media_default(target, webrtc):
1407     if target.os == "Android":
1408         return True
1409     if webrtc:
1410         return True
1413 option(
1414     "--enable-raw",
1415     default=raw_media_default,
1416     help="{Enable|Disable} support for RAW media",
1419 set_config("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1420 set_define("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
1423 # X11
1424 # ==============================================================
1425 @depends(webrtc, when=toolkit_gtk)
1426 def x11_libs(webrtc):
1427     libs = [
1428         "x11",
1429         "xcb",
1430         "xcb-shm",
1431         "x11-xcb",
1432         "xext",
1433         "xrandr >= 1.4.0",
1434     ]
1435     if webrtc:
1436         # third_party/libwebrtc/webrtc/webrtc_gn/moz.build adds those
1437         # manually, ensure they're available.
1438         libs += [
1439             "xcomposite",
1440             "xcursor",
1441             "xdamage",
1442             "xfixes",
1443             "xi",
1444             "xtst",
1445         ]
1446     return libs
1449 x11_headers = pkg_check_modules(
1450     "MOZ_X11",
1451     x11_libs,
1452     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1453     when=depends(full_toolkit)(
1454         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1455     ),
1459 set_config("MOZ_X11", True, when=x11_headers)
1460 set_define("MOZ_X11", True, when=x11_headers)
1462 pkg_check_modules(
1463     "MOZ_X11_SM",
1464     ["ice", "sm"],
1465     cflags_only=True,
1466     allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"),
1467     when=depends(full_toolkit)(
1468         lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland")
1469     ),
1473 # ASan Reporter Addon
1474 # ==============================================================
1475 option(
1476     "--enable-address-sanitizer-reporter",
1477     help="Enable Address Sanitizer Reporter Extension",
1481 @depends("--enable-address-sanitizer-reporter")
1482 def enable_asan_reporter(value):
1483     if value:
1484         return True
1487 set_config("MOZ_ASAN_REPORTER", enable_asan_reporter)
1488 set_define("MOZ_ASAN_REPORTER", enable_asan_reporter)
1490 # Elfhack
1491 # ==============================================================
1492 with only_when("--enable-compile-environment"):
1494     @depends(host, target)
1495     def has_elfhack(host, target):
1496         return (
1497             target.kernel == "Linux"
1498             and host.kernel == "Linux"
1499             and target.cpu in ("arm", "aarch64", "x86", "x86_64")
1500         )
1502     @depends("--enable-release", enable_linker)
1503     def default_elfhack(release, linker):
1504         # Disable elfhack when explicitly building with --enable-linker=lld
1505         if linker and linker.origin != "default" and linker[0] in ("lld", "mold"):
1506             return False
1507         return bool(release)
1509     with only_when(has_elfhack):
1510         option(
1511             "--disable-elf-hack",
1512             default=default_elfhack,
1513             help="{Enable|Disable} elf hacks",
1514         )
1516         @depends(select_linker, when="--enable-elf-hack")
1517         def use_elf_hack(linker):
1518             if linker and linker.KIND == "lld":
1519                 die(
1520                     "Cannot enable elfhack with lld."
1521                     " Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
1522                 )
1523             return True
1525         set_config("USE_ELF_HACK", use_elf_hack)
1528 @depends(build_environment)
1529 def idl_roots(build_env):
1530     return namespace(
1531         ipdl_root=os.path.join(build_env.topobjdir, "ipc", "ipdl"),
1532         webidl_root=os.path.join(build_env.topobjdir, "dom", "bindings"),
1533         xpcom_root=os.path.join(build_env.topobjdir, "xpcom", "components"),
1534     )
1537 set_config("WEBIDL_ROOT", idl_roots.webidl_root)
1538 set_config("IPDL_ROOT", idl_roots.ipdl_root)
1539 set_config("XPCOM_ROOT", idl_roots.xpcom_root)
1541 # Proxy bypass protection
1542 # ==============================================================
1544 option(
1545     "--enable-proxy-bypass-protection",
1546     help="Prevent suspected or confirmed proxy bypasses",
1550 @depends_if("--enable-proxy-bypass-protection")
1551 def proxy_bypass_protection(_):
1552     return True
1555 set_config("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1556 set_define("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
1558 # Proxy direct failover
1559 # ==============================================================
1561 option(
1562     "--disable-proxy-direct-failover",
1563     help="Disable direct failover for system requests",
1567 @depends_if("--disable-proxy-direct-failover")
1568 def proxy_direct_failover(value):
1569     if value:
1570         return True
1573 set_config("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1574 set_define("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
1576 # MIDL
1577 # ==============================================================
1580 @depends(c_compiler, toolchain_prefix)
1581 def midl_names(c_compiler, toolchain_prefix):
1582     if c_compiler and c_compiler.type in ["gcc", "clang"]:
1583         # mingw
1584         widl = ("widl",)
1585         if toolchain_prefix:
1586             prefixed = tuple("%s%s" % (p, "widl") for p in toolchain_prefix)
1587             widl = prefixed + widl
1588         return widl
1590     return ("midl.exe",)
1593 @depends(target, "--enable-compile-environment")
1594 def check_for_midl(target, compile_environment):
1595     if target.os != "WINNT":
1596         return
1598     if compile_environment:
1599         return True
1602 midl = check_prog(
1603     "MIDL",
1604     midl_names,
1605     when=check_for_midl,
1606     allow_missing=True,
1607     paths=sdk_bin_path,
1608     # MIDL being used from a python wrapper script, we can live with it
1609     # having spaces.
1610     allow_spaces=True,
1613 option(env="MIDL_FLAGS", nargs=1, help="Extra flags to pass to MIDL")
1616 @depends(
1617     "MIDL_FLAGS",
1618     target,
1619     midl,
1620     when=depends(midl, target)(lambda m, t: m and t.kernel == "WINNT"),
1622 def midl_flags(flags, target, midl):
1623     if flags:
1624         flags = flags[0].split()
1625     else:
1626         flags = []
1628     if not midl.endswith("widl"):
1629         env = {
1630             "x86": "win32",
1631             "x86_64": "x64",
1632             "aarch64": "arm64",
1633         }[target.cpu]
1634         return flags + ["-nologo", "-no_cpp", "-env", env]
1636     # widl
1637     return flags + {
1638         "x86": ["--win32", "-m32"],
1639         "x86_64": ["--win64", "-m64"],
1640     }[target.cpu]
1643 set_config("MIDL_FLAGS", midl_flags)
1645 # Accessibility
1646 # ==============================================================
1648 option("--disable-accessibility", help="Disable accessibility support")
1651 @depends("--enable-accessibility", check_for_midl, midl, c_compiler)
1652 def accessibility(value, check_for_midl, midl, c_compiler):
1653     enabled = bool(value)
1655     if not enabled:
1656         return
1658     if check_for_midl and not midl:
1659         if c_compiler and c_compiler.type in ("gcc", "clang"):
1660             die(
1661                 "You have accessibility enabled, but widl could not be found. "
1662                 "Add --disable-accessibility to your mozconfig or install widl. "
1663                 "See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details."
1664             )
1665         else:
1666             die(
1667                 "MIDL could not be found. "
1668                 "Building accessibility without MIDL is not supported."
1669             )
1671     return enabled
1674 set_config("ACCESSIBILITY", accessibility)
1675 set_define("ACCESSIBILITY", accessibility)
1678 @depends(moz_debug, developer_options)
1679 def a11y_log(debug, developer_options):
1680     return debug or developer_options
1683 set_config("A11Y_LOG", True, when=a11y_log)
1684 set_define("A11Y_LOG", True, when=a11y_log)
1687 # Addon signing
1688 # ==============================================================
1689 @depends(milestone)
1690 def require_signing(milestone):
1691     return milestone.is_release_or_beta and not milestone.is_esr
1694 option(
1695     env="MOZ_REQUIRE_SIGNING",
1696     default=require_signing,
1697     help="Enforce that add-ons are signed by the trusted root",
1700 set_config("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1701 set_define("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
1703 option(
1704     "--with-unsigned-addon-scopes",
1705     nargs="+",
1706     choices=("app", "system"),
1707     help="Addon scopes where signature is not required",
1711 @depends("--with-unsigned-addon-scopes")
1712 def unsigned_addon_scopes(scopes):
1713     return namespace(
1714         app="app" in scopes or None,
1715         system="system" in scopes or None,
1716     )
1719 set_config("MOZ_UNSIGNED_APP_SCOPE", unsigned_addon_scopes.app)
1720 set_config("MOZ_UNSIGNED_SYSTEM_SCOPE", unsigned_addon_scopes.system)
1723 # Addon sideloading
1724 # ==============================================================
1725 option(
1726     "--allow-addon-sideload",
1727     default=milestone.is_esr,
1728     help="Addon sideloading is allowed",
1732 set_config("MOZ_ALLOW_ADDON_SIDELOAD", True, when="--allow-addon-sideload")
1734 # WebExtensions API WebIDL bindings
1735 # ==============================================================
1738 @depends(milestone)
1739 def extensions_webidl_bindings_default(milestone):
1740     # Only enable the webidl bindings for the WebExtensions APIs
1741     # in Nightly.
1742     return milestone.is_nightly
1745 option(
1746     "--enable-extensions-webidl-bindings",
1747     default=extensions_webidl_bindings_default,
1748     help="{Enable|Disable} building experimental WebExtensions WebIDL bindings",
1752 @depends("--enable-extensions-webidl-bindings")
1753 def extensions_webidl_enabled(value):
1754     return bool(value)
1757 set_config("MOZ_WEBEXT_WEBIDL_ENABLED", extensions_webidl_enabled)
1759 # Launcher process (Windows only)
1760 # ==============================================================
1763 @depends(target)
1764 def launcher_process_default(target):
1765     return target.os == "WINNT"
1768 option(
1769     "--enable-launcher-process",
1770     default=launcher_process_default,
1771     help="{Enable|Disable} launcher process by default",
1775 @depends("--enable-launcher-process", target)
1776 def launcher(value, target):
1777     enabled = bool(value)
1778     if enabled and target.os != "WINNT":
1779         die("Cannot enable launcher process on %s", target.os)
1780     if enabled:
1781         return True
1784 set_config("MOZ_LAUNCHER_PROCESS", launcher)
1785 set_define("MOZ_LAUNCHER_PROCESS", launcher)
1787 # llvm-dlltool (Windows only)
1788 # ==============================================================
1791 @depends(build_project, target, "--enable-compile-environment")
1792 def check_for_llvm_dlltool(build_project, target, compile_environment):
1793     if build_project != "browser":
1794         return
1796     if target.os != "WINNT":
1797         return
1799     return compile_environment
1802 llvm_dlltool = check_prog(
1803     "LLVM_DLLTOOL",
1804     ("llvm-dlltool",),
1805     what="llvm-dlltool",
1806     when=check_for_llvm_dlltool,
1807     paths=clang_search_path,
1811 @depends(target, when=llvm_dlltool)
1812 def llvm_dlltool_flags(target):
1813     arch = {
1814         "x86": "i386",
1815         "x86_64": "i386:x86-64",
1816         "aarch64": "arm64",
1817     }[target.cpu]
1819     return ["-m", arch]
1822 set_config("LLVM_DLLTOOL_FLAGS", llvm_dlltool_flags)
1824 # BITS download (Windows only)
1825 # ==============================================================
1827 option(
1828     "--enable-bits-download",
1829     when=target_is_windows,
1830     default=target_is_windows,
1831     help="{Enable|Disable} building BITS download support",
1834 set_define(
1835     "MOZ_BITS_DOWNLOAD",
1836     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1838 set_config(
1839     "MOZ_BITS_DOWNLOAD",
1840     depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
1843 # Bundled fonts on desktop platform
1844 # ==============================================================
1847 @depends(target)
1848 def bundled_fonts_default(target):
1849     return target.os == "WINNT" or target.kernel == "Linux"
1852 @depends(build_project)
1853 def allow_bundled_fonts(project):
1854     return project == "browser" or project == "comm/mail"
1857 option(
1858     "--enable-bundled-fonts",
1859     default=bundled_fonts_default,
1860     when=allow_bundled_fonts,
1861     help="{Enable|Disable} support for bundled fonts on desktop platforms",
1864 set_define(
1865     "MOZ_BUNDLED_FONTS",
1866     depends_if("--enable-bundled-fonts", when=allow_bundled_fonts)(lambda _: True),
1869 # Reflow counting
1870 # ==============================================================
1873 @depends(moz_debug)
1874 def reflow_perf(debug):
1875     if debug:
1876         return True
1879 option(
1880     "--enable-reflow-perf",
1881     default=reflow_perf,
1882     help="{Enable|Disable} reflow performance tracing",
1885 # The difference in conditions here comes from the initial implementation
1886 # in old-configure, which was unexplained there as well.
1887 set_define("MOZ_REFLOW_PERF", depends_if("--enable-reflow-perf")(lambda _: True))
1888 set_define("MOZ_REFLOW_PERF_DSP", reflow_perf)
1890 # Layout debugger
1891 # ==============================================================
1894 @depends(moz_debug)
1895 def layout_debugger(debug):
1896     if debug:
1897         return True
1900 option(
1901     "--enable-layout-debugger",
1902     default=layout_debugger,
1903     help="{Enable|Disable} layout debugger",
1906 set_config("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1907 set_define("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
1910 # Shader Compiler for Windows (and MinGW Cross Compile)
1911 # ==============================================================
1913 with only_when(compile_environment):
1914     fxc = check_prog(
1915         "FXC",
1916         ("fxc.exe", "fxc2.exe"),
1917         when=depends(target)(lambda t: t.kernel == "WINNT"),
1918         paths=sdk_bin_path,
1919         # FXC being used from a python wrapper script, we can live with it
1920         # having spaces.
1921         allow_spaces=True,
1922     )
1925 # VPX
1926 # ===
1928 with only_when(compile_environment):
1929     system_lib_option(
1930         "--with-system-libvpx", help="Use system libvpx (located with pkgconfig)"
1931     )
1933     with only_when("--with-system-libvpx"):
1934         vpx = pkg_check_modules("MOZ_LIBVPX", "vpx >= 1.10.0")
1936         check_header(
1937             "vpx/vpx_decoder.h",
1938             flags=vpx.cflags,
1939             onerror=lambda: die(
1940                 "Couldn't find vpx/vpx_decoder.h, which is required to build "
1941                 "with system libvpx. Use --without-system-libvpx to build "
1942                 "with in-tree libvpx."
1943             ),
1944         )
1946         check_symbol(
1947             "vpx_codec_dec_init_ver",
1948             flags=vpx.libs,
1949             onerror=lambda: die(
1950                 "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1951                 "not found"
1952             ),
1953         )
1955         set_config("MOZ_SYSTEM_LIBVPX", True)
1957     @depends("--with-system-libvpx", target)
1958     def in_tree_vpx(system_libvpx, target):
1959         if system_libvpx:
1960             return
1962         arm_asm = (target.cpu == "arm") or None
1963         return namespace(arm_asm=arm_asm)
1965     @depends(target, when=in_tree_vpx)
1966     def vpx_nasm(target):
1967         if target.cpu in ("x86", "x86_64"):
1968             if target.kernel == "WINNT":
1969                 # Version 2.03 is needed for automatic safeseh support.
1970                 return namespace(version="2.03", what="VPX")
1971             return namespace(what="VPX")
1973     @depends(in_tree_vpx, vpx_nasm, target, neon_flags)
1974     def vpx_as_flags(vpx, vpx_nasm, target, neon_flags):
1975         if vpx and vpx.arm_asm:
1976             # These flags are a lie; they're just used to enable the requisite
1977             # opcodes; actual arch detection is done at runtime.
1978             return neon_flags
1979         elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64":
1980             return ("-DPIC",)
1982     set_config("VPX_USE_NASM", True, when=vpx_nasm)
1983     set_config("VPX_ASFLAGS", vpx_as_flags)
1986 # JPEG
1987 # ====
1989 with only_when(compile_environment):
1990     system_lib_option(
1991         "--with-system-jpeg",
1992         nargs="?",
1993         help="Use system libjpeg (installed at given prefix)",
1994     )
1996     @depends_if("--with-system-jpeg")
1997     def jpeg_flags(value):
1998         if len(value):
1999             return namespace(
2000                 cflags=("-I%s/include" % value[0],),
2001                 ldflags=("-L%s/lib" % value[0], "-ljpeg"),
2002             )
2003         return namespace(
2004             ldflags=("-ljpeg",),
2005         )
2007     with only_when("--with-system-jpeg"):
2008         check_symbol(
2009             "jpeg_destroy_compress",
2010             flags=jpeg_flags.ldflags,
2011             onerror=lambda: die(
2012                 "--with-system-jpeg requested but symbol "
2013                 "jpeg_destroy_compress not found."
2014             ),
2015         )
2017         c_compiler.try_compile(
2018             includes=[
2019                 "stdio.h",
2020                 "sys/types.h",
2021                 "jpeglib.h",
2022             ],
2023             body="""
2024                 #if JPEG_LIB_VERSION < 62
2025                 #error Insufficient JPEG library version
2026                 #endif
2027             """,
2028             flags=jpeg_flags.cflags,
2029             check_msg="for sufficient jpeg library version",
2030             onerror=lambda: die(
2031                 "Insufficient JPEG library version for "
2032                 "--with-system-jpeg (62 required)"
2033             ),
2034         )
2036         c_compiler.try_compile(
2037             includes=[
2038                 "stdio.h",
2039                 "sys/types.h",
2040                 "jpeglib.h",
2041             ],
2042             body="""
2043                 #ifndef JCS_EXTENSIONS
2044                 #error libjpeg-turbo JCS_EXTENSIONS required
2045                 #endif
2046             """,
2047             flags=jpeg_flags.cflags,
2048             check_msg="for sufficient libjpeg-turbo JCS_EXTENSIONS",
2049             onerror=lambda: die(
2050                 "libjpeg-turbo JCS_EXTENSIONS required for " "--with-system-jpeg"
2051             ),
2052         )
2054         set_config("MOZ_JPEG_CFLAGS", jpeg_flags.cflags)
2055         set_config("MOZ_JPEG_LIBS", jpeg_flags.ldflags)
2057     @depends("--with-system-jpeg", target, neon_flags)
2058     def in_tree_jpeg_arm(system_jpeg, target, neon_flags):
2059         if system_jpeg:
2060             return
2062         if target.cpu == "arm":
2063             return neon_flags
2064         elif target.cpu == "aarch64":
2065             return ("-march=armv8-a",)
2067     @depends("--with-system-jpeg", target)
2068     def in_tree_jpeg_mips64(system_jpeg, target):
2069         if system_jpeg:
2070             return
2072         if target.cpu == "mips64":
2073             return ("-Wa,-mloongson-mmi", "-mloongson-ext")
2075     # Compiler check from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L419
2076     jpeg_mips64_mmi = c_compiler.try_compile(
2077         body='int c = 0, a = 0, b = 0; asm("paddb %0, %1, %2" : "=f" (c) : "f" (a), "f" (b));',
2078         check_msg="for loongson mmi support",
2079         flags=in_tree_jpeg_mips64,
2080         when=in_tree_jpeg_mips64,
2081     )
2083     @depends(
2084         "--with-system-jpeg",
2085         target,
2086         in_tree_jpeg_arm,
2087         in_tree_jpeg_mips64,
2088         jpeg_mips64_mmi,
2089     )
2090     def in_tree_jpeg(
2091         system_jpeg, target, in_tree_jpeg_arm, in_tree_jpeg_mips64, jpeg_mips64_mmi
2092     ):
2093         if system_jpeg:
2094             return
2096         if target.cpu in ("arm", "aarch64"):
2097             return in_tree_jpeg_arm
2098         elif target.kernel == "Darwin":
2099             if target.cpu == "x86":
2100                 return ("-DPIC", "-DMACHO")
2101             elif target.cpu == "x86_64":
2102                 return ("-D__x86_64__", "-DPIC", "-DMACHO")
2103         elif target.kernel == "WINNT":
2104             if target.cpu == "x86":
2105                 return ("-DPIC", "-DWIN32")
2106             elif target.cpu == "x86_64":
2107                 return ("-D__x86_64__", "-DPIC", "-DWIN64", "-DMSVC")
2108         elif target.cpu == "mips32":
2109             return ("-mdspr2",)
2110         elif target.cpu == "mips64" and jpeg_mips64_mmi:
2111             return in_tree_jpeg_mips64
2112         elif target.cpu == "x86":
2113             return ("-DPIC", "-DELF")
2114         elif target.cpu == "x86_64":
2115             return ("-D__x86_64__", "-DPIC", "-DELF")
2117     @depends(target, when=depends("--with-system-jpeg")(lambda x: not x))
2118     def jpeg_nasm(target):
2119         if target.cpu in ("x86", "x86_64"):
2120             # libjpeg-turbo 2.0.6 requires nasm 2.10.
2121             return namespace(version="2.10", what="JPEG")
2123     # Compiler checks from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L258
2124     jpeg_arm_neon_vld1_s16_x3 = c_compiler.try_compile(
2125         includes=["arm_neon.h"],
2126         body="int16_t input[12] = {}; int16x4x3_t output = vld1_s16_x3(input);",
2127         check_msg="for vld1_s16_x3 in arm_neon.h",
2128         flags=in_tree_jpeg_arm,
2129         when=in_tree_jpeg_arm,
2130     )
2132     jpeg_arm_neon_vld1_u16_x2 = c_compiler.try_compile(
2133         includes=["arm_neon.h"],
2134         body="uint16_t input[8] = {}; uint16x4x2_t output = vld1_u16_x2(input);",
2135         check_msg="for vld1_u16_x2 in arm_neon.h",
2136         flags=in_tree_jpeg_arm,
2137         when=in_tree_jpeg_arm,
2138     )
2140     jpeg_arm_neon_vld1q_u8_x4 = c_compiler.try_compile(
2141         includes=["arm_neon.h"],
2142         body="uint8_t input[64] = {}; uint8x16x4_t output = vld1q_u8_x4(input);",
2143         check_msg="for vld1q_u8_x4 in arm_neon.h",
2144         flags=in_tree_jpeg_arm,
2145         when=in_tree_jpeg_arm,
2146     )
2148     set_config("LIBJPEG_TURBO_USE_NASM", True, when=jpeg_nasm)
2149     set_config("LIBJPEG_TURBO_SIMD_FLAGS", in_tree_jpeg)
2150     set_config("LIBJPEG_TURBO_HAVE_VLD1_S16_X3", jpeg_arm_neon_vld1_s16_x3)
2151     set_config("LIBJPEG_TURBO_HAVE_VLD1_U16_X2", jpeg_arm_neon_vld1_u16_x2)
2152     set_config("LIBJPEG_TURBO_HAVE_VLD1Q_U8_X4", jpeg_arm_neon_vld1q_u8_x4)
2153     set_config(
2154         "LIBJPEG_TURBO_NEON_INTRINSICS",
2155         jpeg_arm_neon_vld1_s16_x3
2156         & jpeg_arm_neon_vld1_u16_x2
2157         & jpeg_arm_neon_vld1q_u8_x4,
2158     )
2161 # PNG
2162 # ===
2163 with only_when(compile_environment):
2164     system_lib_option(
2165         "--with-system-png",
2166         nargs="?",
2167         help="Use system libpng",
2168     )
2170     @depends("--with-system-png")
2171     def deprecated_system_png_path(value):
2172         if len(value) == 1:
2173             die(
2174                 "--with-system-png=PATH is not supported anymore. Please use "
2175                 "--with-system-png and set any necessary pkg-config environment variable."
2176             )
2178     png = pkg_check_modules("MOZ_PNG", "libpng >= 1.6.35", when="--with-system-png")
2180     check_symbol(
2181         "png_get_acTL",
2182         flags=png.libs,
2183         onerror=lambda: die(
2184             "--with-system-png won't work because the system's libpng doesn't have APNG support"
2185         ),
2186         when="--with-system-png",
2187     )
2189     set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
2192 # FFmpeg's ffvpx configuration
2193 # ==============================================================
2194 with only_when(compile_environment):
2196     @depends(target)
2197     def libav_fft(target):
2198         if target.os == "Android" and target.cpu != "arm":
2199             return True
2200         return target.kernel in ("WINNT", "Darwin") or target.cpu == "x86_64"
2202     set_config("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2203     set_define("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
2206 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
2207 with only_when(compile_environment | artifact_builds):
2209     @depends(target)
2210     def ffvpx(target):
2211         enable = use_nasm = True
2212         flac_only = False
2213         flags = []
2215         if target.kernel == "WINNT":
2216             if target.cpu == "x86":
2217                 # 32-bit windows need to prefix symbols with an underscore.
2218                 flags = ["-DPIC", "-DWIN32", "-DPREFIX", "-Pconfig_win32.asm"]
2219             elif target.cpu == "x86_64":
2220                 flags = [
2221                     "-D__x86_64__",
2222                     "-DPIC",
2223                     "-DWIN64",
2224                     "-DMSVC",
2225                     "-Pconfig_win64.asm",
2226                 ]
2227             elif target.cpu == "aarch64":
2228                 flags = ["-DPIC", "-DWIN64"]
2229                 use_nasm = False
2230         elif target.kernel == "Darwin":
2231             # 32/64-bit macosx assemblers need to prefix symbols with an
2232             # underscore.
2233             flags = ["-DPIC", "-DMACHO", "-DPREFIX"]
2234             if target.cpu == "x86_64":
2235                 flags += [
2236                     "-D__x86_64__",
2237                     "-Pconfig_darwin64.asm",
2238                 ]
2239             elif target.cpu == "aarch64":
2240                 use_nasm = False
2241         elif target.cpu == "x86_64":
2242             flags = ["-D__x86_64__", "-DPIC", "-DELF", "-Pconfig_unix64.asm"]
2243         elif target.cpu in ("x86", "arm", "aarch64"):
2244             flac_only = True
2245         else:
2246             enable = False
2248         if flac_only or not enable:
2249             use_nasm = False
2251         return namespace(
2252             enable=enable,
2253             use_nasm=use_nasm,
2254             flac_only=flac_only,
2255             flags=flags,
2256         )
2258     @depends(when=ffvpx.use_nasm)
2259     def ffvpx_nasm():
2260         # nasm 2.10 for AVX-2 support.
2261         return namespace(version="2.10", what="FFVPX")
2263     # ffvpx_nasm can't indirectly depend on vpx_as_flags, because it depends
2264     # on a compiler test, so we have to do a little bit of dance here.
2265     @depends(ffvpx, vpx_as_flags, target)
2266     def ffvpx(ffvpx, vpx_as_flags, target):
2267         if ffvpx and vpx_as_flags and target.cpu in ("arm", "aarch64"):
2268             ffvpx.flags.extend(vpx_as_flags)
2269         return ffvpx
2271     set_config("MOZ_FFVPX", True, when=ffvpx.enable)
2272     set_define("MOZ_FFVPX", True, when=ffvpx.enable)
2273     set_config("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2274     set_define("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
2275     set_config("FFVPX_ASFLAGS", ffvpx.flags)
2276     set_config("FFVPX_USE_NASM", True, when=ffvpx.use_nasm)
2279 # nasm detection
2280 # ==============================================================
2281 @depends(dav1d_nasm, vpx_nasm, jpeg_nasm, ffvpx_nasm, when=compile_environment)
2282 def need_nasm(*requirements):
2283     requires = {
2284         x.what: x.version if hasattr(x, "version") else True for x in requirements if x
2285     }
2286     if requires:
2287         items = sorted(requires.keys())
2288         if len(items) > 1:
2289             what = " and ".join((", ".join(items[:-1]), items[-1]))
2290         else:
2291             what = items[0]
2292         versioned = {k: v for (k, v) in requires.items() if v is not True}
2293         return namespace(what=what, versioned=versioned)
2296 nasm = check_prog(
2297     "NASM",
2298     ["nasm"],
2299     allow_missing=True,
2300     bootstrap="nasm",
2301     when=need_nasm,
2305 @depends(nasm, need_nasm.what)
2306 def check_nasm(nasm, what):
2307     if not nasm and what:
2308         die("Nasm is required to build with %s, but it was not found." % what)
2309     return nasm
2312 @depends_if(check_nasm)
2313 @checking("nasm version")
2314 def nasm_version(nasm):
2315     version = (
2316         check_cmd_output(nasm, "-v", onerror=lambda: die("Failed to get nasm version."))
2317         .splitlines()[0]
2318         .split()[2]
2319     )
2320     return Version(version)
2323 @depends(nasm_version, need_nasm.versioned, when=need_nasm.versioned)
2324 def check_nasm_version(nasm_version, versioned):
2325     by_version = sorted(versioned.items(), key=lambda x: x[1])
2326     what, version = by_version[-1]
2327     if nasm_version < version:
2328         die(
2329             "Nasm version %s or greater is required to build with %s." % (version, what)
2330         )
2331     return nasm_version
2334 @depends(target, when=check_nasm_version)
2335 def nasm_asflags(target):
2336     asflags = {
2337         ("OSX", "x86"): ["-f", "macho32"],
2338         ("OSX", "x86_64"): ["-f", "macho64"],
2339         ("WINNT", "x86"): ["-f", "win32"],
2340         ("WINNT", "x86_64"): ["-f", "win64"],
2341     }.get((target.os, target.cpu), None)
2342     if asflags is None:
2343         # We're assuming every x86 platform we support that's
2344         # not Windows or Mac is ELF.
2345         if target.cpu == "x86":
2346             asflags = ["-f", "elf32"]
2347         elif target.cpu == "x86_64":
2348             asflags = ["-f", "elf64"]
2349     return asflags
2352 set_config("NASM_ASFLAGS", nasm_asflags)
2355 # ANGLE OpenGL->D3D translator for WebGL
2356 # ==============================================================
2358 with only_when(compile_environment & target_is_windows):
2360     def d3d_compiler_dll_result(value):
2361         if not value.path:
2362             return "provided by the OS"
2363         return value.path
2365     @depends(target, valid_windows_sdk_dir, fxc)
2366     @checking("for D3D compiler DLL", d3d_compiler_dll_result)
2367     @imports("os.path")
2368     def d3d_compiler_dll(target, windows_sdk_dir, fxc):
2369         suffix = {
2370             "x86_64": "x64",
2371         }.get(target.cpu, target.cpu)
2373         name = "d3dcompiler_47.dll"
2375         if target.cpu == "aarch64":
2376             # AArch64 Windows comes with d3dcompiler_47.dll installed
2377             return namespace(name=name, path=None)
2379         if windows_sdk_dir:
2380             path = os.path.join(windows_sdk_dir.path, "Redist", "D3D", suffix, name)
2381             error_extra = "in Windows SDK at {}".format(windows_sdk_dir.path)
2382         else:
2383             path = os.path.join(os.path.dirname(fxc), name)
2384             error_extra = "alongside FXC at {}".format(fxc)
2386         if os.path.exists(path):
2387             return namespace(name=name, path=path)
2388         die("Could not find {} {}".format(name, error_extra))
2390     set_config("MOZ_ANGLE_RENDERER", True)
2391     set_config(
2392         "MOZ_D3DCOMPILER_VISTA_DLL", d3d_compiler_dll.name, when=d3d_compiler_dll.path
2393     )
2394     set_config("MOZ_D3DCOMPILER_VISTA_DLL_PATH", d3d_compiler_dll.path)
2396 # Remoting protocol support
2397 # ==============================================================
2400 @depends(toolkit)
2401 def has_remote(toolkit):
2402     if toolkit in ("gtk", "windows", "cocoa"):
2403         return True
2406 set_config("MOZ_HAS_REMOTE", has_remote)
2407 set_define("MOZ_HAS_REMOTE", has_remote)
2409 # RLBox Library Sandboxing wasm support
2410 # ==============================================================
2413 def wasm_sandboxing_libraries():
2414     return (
2415         "graphite",
2416         "ogg",
2417         "hunspell",
2418         "expat",
2419         "woff2",
2420     )
2423 @depends(dependable(wasm_sandboxing_libraries), build_project)
2424 def default_wasm_sandboxing_libraries(libraries, build_project):
2425     if build_project != "tools/rusttests":
2426         non_default_libs = set()
2428         return tuple(l for l in libraries if l not in non_default_libs)
2431 option(
2432     "--with-wasm-sandboxed-libraries",
2433     env="WASM_SANDBOXED_LIBRARIES",
2434     help="{Enable wasm sandboxing for the selected libraries|Disable wasm sandboxing}",
2435     nargs="+",
2436     choices=dependable(wasm_sandboxing_libraries),
2437     default=default_wasm_sandboxing_libraries,
2441 @depends("--with-wasm-sandboxed-libraries")
2442 def requires_wasm_sandboxing(libraries):
2443     if libraries:
2444         return True
2447 set_config("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2448 set_define("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
2450 with only_when(requires_wasm_sandboxing & compile_environment):
2451     option(
2452         "--with-wasi-sysroot",
2453         env="WASI_SYSROOT",
2454         nargs=1,
2455         help="Path to wasi sysroot for wasm sandboxing",
2456     )
2458     @depends("--with-wasi-sysroot", requires_wasm_sandboxing)
2459     def bootstrap_wasi_sysroot(wasi_sysroot, requires_wasm_sandboxing):
2460         return requires_wasm_sandboxing and not wasi_sysroot
2462     @depends(
2463         "--with-wasi-sysroot",
2464         bootstrap_path("sysroot-wasm32-wasi", when=bootstrap_wasi_sysroot),
2465     )
2466     @imports("os")
2467     def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot):
2468         if not wasi_sysroot:
2469             return bootstrapped_sysroot
2471         wasi_sysroot = wasi_sysroot[0]
2472         if not os.path.isdir(wasi_sysroot):
2473             die("Argument to --with-wasi-sysroot must be a directory")
2474         if not os.path.isabs(wasi_sysroot):
2475             die("Argument to --with-wasi-sysroot must be an absolute path")
2477         return wasi_sysroot
2479     @depends(wasi_sysroot)
2480     def wasi_sysroot_flags(wasi_sysroot):
2481         if wasi_sysroot:
2482             log.info("Using wasi sysroot in %s", wasi_sysroot)
2483             return ["--sysroot=%s" % wasi_sysroot]
2484         return []
2486     set_config("WASI_SYSROOT", wasi_sysroot)
2488     def wasm_compiler_with_flags(compiler, sysroot_flags):
2489         if compiler:
2490             return (
2491                 compiler.wrapper + [compiler.compiler] + compiler.flags + sysroot_flags
2492             )
2494     @template
2495     def wasm_compiler_error(msg):
2496         @depends("--with-wasm-sandboxed-libraries")
2497         def wasm_compiler_error(sandboxed_libs):
2498             suggest_disable = ""
2499             if sandboxed_libs.origin == "default":
2500                 suggest_disable = " Or build with --without-wasm-sandboxed-libraries."
2501             return lambda: die(msg + suggest_disable)
2503         return wasm_compiler_error
2505     @template
2506     def check_wasm_compiler(compiler, language):
2507         compiler.try_compile(
2508             includes=["cstring" if language == "C++" else "string.h"],
2509             flags=wasi_sysroot_flags,
2510             check_msg="the wasm %s compiler can find wasi headers" % language,
2511             onerror=wasm_compiler_error(
2512                 "Cannot find wasi headers or problem with the wasm compiler. "
2513                 "Please fix the problem."
2514             ),
2515         )
2517         compiler.try_run(
2518             flags=wasi_sysroot_flags,
2519             check_msg="the wasm %s linker can find wasi libraries" % language,
2520             onerror=wasm_compiler_error(
2521                 "Cannot find wasi libraries or problem with the wasm linker. "
2522                 "Please fix the problem."
2523             ),
2524         )
2526     wasm_cc = compiler("C", wasm, other_compiler=c_compiler)
2527     check_wasm_compiler(wasm_cc, "C")
2529     @depends(wasm_cc, wasi_sysroot_flags)
2530     def wasm_cc_with_flags(wasm_cc, wasi_sysroot_flags):
2531         return wasm_compiler_with_flags(wasm_cc, wasi_sysroot_flags)
2533     set_config("WASM_CC", wasm_cc_with_flags)
2535     wasm_cxx = compiler(
2536         "C++",
2537         wasm,
2538         c_compiler=wasm_cc,
2539         other_compiler=cxx_compiler,
2540         other_c_compiler=c_compiler,
2541     )
2542     check_wasm_compiler(wasm_cxx, "C++")
2544     @depends(wasm_cxx, wasi_sysroot_flags)
2545     def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot_flags):
2546         return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot_flags)
2548     set_config("WASM_CXX", wasm_cxx_with_flags)
2550     wasm_compile_flags = dependable(["-fno-exceptions", "-fno-strict-aliasing"])
2551     option(env="WASM_CFLAGS", nargs=1, help="Options to pass to WASM_CC")
2553     @depends("WASM_CFLAGS", wasm_compile_flags)
2554     def wasm_cflags(value, wasm_compile_flags):
2555         if value:
2556             return wasm_compile_flags + value
2557         else:
2558             return wasm_compile_flags
2560     set_config("WASM_CFLAGS", wasm_cflags)
2562     option(env="WASM_CXXFLAGS", nargs=1, help="Options to pass to WASM_CXX")
2564     @depends("WASM_CXXFLAGS", wasm_compile_flags)
2565     def wasm_cxxflags(value, wasm_compile_flags):
2566         if value:
2567             return wasm_compile_flags + value
2568         else:
2569             return wasm_compile_flags
2571     set_config("WASM_CXXFLAGS", wasm_cxxflags)
2574 @depends("--with-wasm-sandboxed-libraries")
2575 def wasm_sandboxing(libraries):
2576     if not libraries:
2577         return
2579     return namespace(**{name: True for name in libraries})
2582 @template
2583 def wasm_sandboxing_config_defines():
2584     for lib in wasm_sandboxing_libraries():
2585         set_config(
2586             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2587         )
2588         set_define(
2589             "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
2590         )
2593 wasm_sandboxing_config_defines()
2596 # new Notification Store implementation
2597 # ==============================================================
2600 @depends(milestone)
2601 def new_notification_store(milestone):
2602     if milestone.is_nightly:
2603         return True
2606 set_config("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2607 set_define("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
2610 # Glean SDK Integration Crate
2611 # ==============================================================
2614 @depends(target)
2615 def glean_android(target):
2616     return target.os == "Android"
2619 set_config("MOZ_GLEAN_ANDROID", True, when=glean_android)
2620 set_define("MOZ_GLEAN_ANDROID", True, when=glean_android)
2623 # dump_syms
2624 # ==============================================================
2626 check_prog(
2627     "DUMP_SYMS",
2628     ["dump_syms"],
2629     allow_missing=True,
2630     bootstrap="dump_syms",
2631     when=compile_environment,
2635 @depends(valid_windows_sdk_dir, host)
2636 @imports(_from="os", _import="environ")
2637 def pdbstr_paths(valid_windows_sdk_dir, host):
2638     if not valid_windows_sdk_dir:
2639         return
2641     vc_host = {
2642         "x86": "x86",
2643         "x86_64": "x64",
2644     }.get(host.cpu)
2646     return [
2647         environ["PATH"],
2648         os.path.join(valid_windows_sdk_dir.path, "Debuggers", vc_host, "srcsrv"),
2649     ]
2652 check_prog(
2653     "PDBSTR",
2654     ["pdbstr.exe"],
2655     allow_missing=True,
2656     when=compile_environment & target_is_windows,
2657     paths=pdbstr_paths,
2658     allow_spaces=True,
2662 @depends("MOZ_AUTOMATION", c_compiler)
2663 def allow_missing_winchecksec(automation, c_compiler):
2664     if not automation:
2665         return True
2666     if c_compiler and c_compiler.type != "clang-cl":
2667         return True
2670 check_prog(
2671     "WINCHECKSEC",
2672     ["winchecksec.exe", "winchecksec"],
2673     bootstrap="winchecksec",
2674     allow_missing=allow_missing_winchecksec,
2675     when=compile_environment & target_is_windows,
2678 # Fork server
2679 @depends(target, build_project)
2680 def forkserver_default(target, build_project):
2681     return build_project == "browser" and (
2682         (target.os == "GNU" and target.kernel == "Linux")
2683         or target.os == "FreeBSD"
2684         or target.os == "OpenBSD"
2685     )
2688 option(
2689     "--enable-forkserver",
2690     default=forkserver_default,
2691     env="MOZ_ENABLE_FORKSERVER",
2692     help="{Enable|Disable} fork server",
2696 @depends("--enable-forkserver", target)
2697 def forkserver_flag(value, target):
2698     if (
2699         target.os == "Android"
2700         or (target.os == "GNU" and target.kernel == "Linux")
2701         or target.os == "FreeBSD"
2702         or target.os == "OpenBSD"
2703     ):
2704         return bool(value)
2705     pass
2708 set_config("MOZ_ENABLE_FORKSERVER", forkserver_flag)
2709 set_define("MOZ_ENABLE_FORKSERVER", forkserver_flag, forkserver_flag)
2711 # Crash Reporter
2712 # ==============================================================
2714 with only_when(compile_environment & target_has_linux_kernel):
2715     # Check if we need to use the breakpad_getcontext fallback.
2716     getcontext = check_symbol("getcontext")
2717     set_config("HAVE_GETCONTEXT", getcontext)
2718     set_define("HAVE_GETCONTEXT", getcontext)
2720 # NSS
2721 # ==============================================================
2722 include("../build/moz.configure/nss.configure")
2725 # Enable or disable running in background task mode: headless for
2726 # periodic, short-lived, maintenance tasks.
2727 # ==============================================================================
2728 option(
2729     "--disable-backgroundtasks",
2730     help="Disable running in background task mode",
2732 set_config("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2733 set_define("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
2736 # Update-related programs: updater, maintenance service, update agent,
2737 # default browser agent.
2738 # ==============================================================
2739 include("../build/moz.configure/update-programs.configure")
2742 # Mobile optimizations
2743 # ==============================================================
2744 option(
2745     "--enable-mobile-optimize",
2746     default=target_is_android,
2747     help="{Enable|Disable} mobile optimizations",
2750 set_define("MOZ_GFX_OPTIMIZE_MOBILE", True, when="--enable-mobile-optimize")
2751 # We ignore "paint will resample" on mobile for performance.
2752 # We may want to revisit this later.
2753 set_define("MOZ_IGNORE_PAINT_WILL_RESAMPLE", True, when="--enable-mobile-optimize")
2755 # Pref extensions
2756 # ==============================================================
2757 option("--disable-pref-extensions", help="Disable pref extensions such as autoconfig")
2758 set_config("MOZ_PREF_EXTENSIONS", True, when="--enable-pref-extensions")
2760 # Offer a way to disable the startup cache
2761 # ==============================================================
2762 option("--disable-startupcache", help="Disable startup cache")
2765 @depends("--enable-startupcache")
2766 def enable_startupcache(value):
2767     if value:
2768         return True
2771 set_define(
2772     "MOZ_DISABLE_STARTUPCACHE", True, when=depends(enable_startupcache)(lambda x: not x)
2776 # Branding
2777 # ==============================================================
2778 option(
2779     env="MOZ_APP_REMOTINGNAME",
2780     nargs=1,
2781     help="Used for the internal program name, which affects profile name "
2782     "and remoting. If not set, defaults to MOZ_APP_NAME if the update channel "
2783     "is release, and MOZ_APP_NAME-MOZ_UPDATE_CHANNEL otherwise.",
2787 @depends("MOZ_APP_REMOTINGNAME", moz_app_name, update_channel)
2788 def moz_app_remotingname(value, moz_app_name, update_channel):
2789     if value:
2790         return value[0]
2791     if update_channel == "release":
2792         return moz_app_name
2793     return moz_app_name + "-" + update_channel
2796 set_config("MOZ_APP_REMOTINGNAME", moz_app_remotingname)
2798 option(
2799     env="ANDROID_PACKAGE_NAME",
2800     nargs=1,
2801     help="Name of the Android package (default org.mozilla.$MOZ_APP_NAME)",
2805 @depends("ANDROID_PACKAGE_NAME", moz_app_name)
2806 def android_package_name(value, moz_app_name):
2807     if value:
2808         return value[0]
2809     if moz_app_name == "fennec":
2810         return "org.mozilla.fennec_aurora"
2811     return "org.mozilla.%s" % moz_app_name
2814 set_config("ANDROID_PACKAGE_NAME", android_package_name)
2817 # Miscellaneous options
2818 # ==============================================================
2819 option(env="MOZ_WINCONSOLE", nargs="?", help="Whether we can create a console window.")
2820 set_define("MOZ_WINCONSOLE", True, when=depends("MOZ_WINCONSOLE")(lambda x: x))
2823 # Alternative Crashreporter setting
2824 option(
2825     "--with-crashreporter-url",
2826     env="MOZ_CRASHREPORTER_URL",
2827     default="https://crash-reports.mozilla.com/",
2828     nargs=1,
2829     help="Set an alternative crashreporter url",
2832 set_config(
2833     "MOZ_CRASHREPORTER_URL",
2834     depends("--with-crashreporter-url")(lambda x: x[0].rstrip("/")),
2838 # Crash reporter options
2839 # ==============================================================
2840 @depends(target)
2841 def oxidized_breakpad(target):
2842     if target.kernel == "Linux" and target.os != "Android":
2843         return target.cpu in ("x86", "x86_64")
2844     return False
2847 set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2848 set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
2851 # Wine
2852 # ==============================================================
2853 @depends(target, host)
2854 def want_wine(target, host):
2855     return target.kernel == "WINNT" and host.kernel != "WINNT"
2858 wine = check_prog(
2859     "WINE",
2860     ["wine64", "wine"],
2861     when=want_wine,
2862     bootstrap="wine/bin",
2865 # DOM Streams
2866 # ==============================================================
2867 # Set this to true so the JS engine knows we're doing a browser build.
2868 set_config("MOZ_DOM_STREAMS", True)
2869 set_define("MOZ_DOM_STREAMS", True)
2871 # libevent
2872 # ==============================================================
2873 with only_when(compile_environment):
2874     system_lib_option(
2875         "--with-system-libevent",
2876         nargs="?",
2877         help="Use system libevent",
2878     )
2880     @depends("--with-system-libevent")
2881     def deprecated_system_libevent_path(value):
2882         if len(value) == 1:
2883             die(
2884                 "--with-system-libevent=PATH is not supported anymore. Please use "
2885                 "--with-system-libevent and set any necessary pkg-config environment variable."
2886             )
2888     pkg_check_modules("MOZ_LIBEVENT", "libevent", when="--with-system-libevent")
2890     set_config("MOZ_SYSTEM_LIBEVENT", True, when="--with-system-libevent")
2893 # Crash reporting
2894 # ==============================================================
2895 @depends(target, developer_options, artifact_builds)
2896 def crashreporter_default(target, developer_options, artifacts):
2897     if target.kernel in ("WINNT", "Darwin"):
2898         return True
2899     if target.kernel == "Linux" and target.cpu in ("x86", "x86_64", "arm", "aarch64"):
2900         # The crash reporter prevents crash stacktraces to be logged in the
2901         # logs on Android, so we leave it out by default in developer builds.
2902         return target.os != "Android" or not developer_options or artifacts
2905 option(
2906     "--enable-crashreporter",
2907     default=crashreporter_default,
2908     help="{Enable|Disable} crash reporting",
2912 set_config("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2913 set_define("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
2915 with only_when(compile_environment):
2916     with only_when("--enable-crashreporter"):
2917         pkg_check_modules(
2918             "MOZ_GTHREAD",
2919             "gthread-2.0",
2920             when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
2921         )
2923         set_config(
2924             "MOZ_CRASHREPORTER_INJECTOR",
2925             True,
2926             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2927         )
2928         set_define(
2929             "MOZ_CRASHREPORTER_INJECTOR",
2930             True,
2931             when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
2932         )
2935 # If we have any service that uploads data (and requires data submission
2936 # policy alert), set MOZ_DATA_REPORTING.
2937 # ==============================================================
2938 @depends(
2939     "MOZ_TELEMETRY_REPORTING",
2940     "MOZ_SERVICES_HEALTHREPORT",
2941     "--enable-crashreporter",
2942     "MOZ_NORMANDY",
2944 def data_reporting(telemetry, healthreport, crashreporter, normandy):
2945     return telemetry or healthreport or crashreporter or normandy
2948 set_config("MOZ_DATA_REPORTING", True, when=data_reporting)
2949 set_define("MOZ_DATA_REPORTING", True, when=data_reporting)
2952 # Gtk+
2953 # ==============================================================
2954 with only_when(toolkit_gtk):
2955     pkg_check_modules(
2956         "MOZ_GTK3",
2957         "gtk+-3.0 >= 3.14.0 gtk+-unix-print-3.0 glib-2.0 gobject-2.0 gio-unix-2.0",
2958     )
2960     set_define("GDK_VERSION_MIN_REQUIRED", "GDK_VERSION_3_14")
2961     set_define("GDK_VERSION_MAX_ALLOWED", "GDK_VERSION_3_14")
2963     pkg_check_modules("GLIB", "glib-2.0 >= 2.42 gobject-2.0")
2965     set_define("GLIB_VERSION_MIN_REQUIRED", "GLIB_VERSION_2_42")
2966     set_define("GLIB_VERSION_MAX_ALLOWED", "GLIB_VERSION_2_42")
2968     set_define("MOZ_ACCESSIBILITY_ATK", True, when=accessibility)
2970 # DBus
2971 # ==============================================================
2972 with only_when(toolkit_gtk):
2973     option("--disable-dbus", help="Disable dbus support")
2975     with only_when("--enable-dbus"):
2976         pkg_check_modules("MOZ_DBUS", "dbus-1 >= 0.60")
2977         pkg_check_modules("MOZ_DBUS_GLIB", "dbus-glib-1 >= 0.60")
2979         set_config("MOZ_ENABLE_DBUS", True)
2980         set_define("MOZ_ENABLE_DBUS", True)
2983 # Necko's wifi scanner
2984 # ==============================================================
2985 @depends(target)
2986 def necko_wifi_when(target):
2987     return target.os in ("WINNT", "OSX", "DragonFly", "FreeBSD") or (
2988         target.kernel == "Linux" and target.os == "GNU"
2989     )
2992 option("--disable-necko-wifi", help="Disable necko wifi scanner", when=necko_wifi_when)
2994 set_config("NECKO_WIFI", True, when="--enable-necko-wifi")
2995 set_define("NECKO_WIFI", True, when="--enable-necko-wifi")
2998 @depends(
2999     depends("--enable-necko-wifi", when=necko_wifi_when)(lambda x: x),
3000     depends("--enable-dbus", when=toolkit_gtk)(lambda x: x),
3001     when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
3003 def necko_wifi_dbus(necko_wifi, dbus):
3004     if necko_wifi and not dbus:
3005         die(
3006             "Necko WiFi scanning needs DBus on your platform, remove --disable-dbus"
3007             " or use --disable-necko-wifi"
3008         )
3009     return necko_wifi and dbus
3012 set_config("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
3013 set_define("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
3016 # Frontend JS debug mode
3017 # ==============================================================
3018 option("--enable-debug-js-modules", help="Enable debug mode for frontend JS libraries")
3020 set_config("DEBUG_JS_MODULES", True, when="--enable-debug-js-modules")
3023 # moz_dump_painting
3024 # ==============================================================
3025 option("--enable-dump-painting", help="Enable paint debugging")
3027 set_define(
3028     "MOZ_DUMP_PAINTING",
3029     True,
3030     when=depends("--enable-dump-painting", "--enable-debug")(
3031         lambda painting, debug: painting or debug
3032     ),
3034 set_define("MOZ_LAYERS_HAVE_LOG", True, when="--enable-dump-painting")
3037 # libproxy support
3038 # ==============================================================
3039 with only_when(toolkit_gtk):
3040     system_lib_option("--enable-libproxy", help="Enable libproxy support")
3042     with only_when("--enable-libproxy"):
3043         pkg_check_modules("MOZ_LIBPROXY", "libproxy-1.0")
3045         set_config("MOZ_ENABLE_LIBPROXY", True)
3046         set_define("MOZ_ENABLE_LIBPROXY", True)
3049 # Enable runtime logging
3050 # ==============================================================
3051 set_define("MOZ_LOGGING", True)
3052 set_define("FORCE_PR_LOG", True)
3054 # This will enable logging of addref, release, ctor, dtor.
3055 # ==============================================================
3056 option(
3057     "--enable-logrefcnt",
3058     default=moz_debug,
3059     help="{Enable|Disable} logging of refcounts",
3062 set_define("NS_BUILD_REFCNT_LOGGING", True, when="--enable-logrefcnt")
3065 # NegotiateAuth
3066 # ==============================================================
3067 option("--disable-negotiateauth", help="Disable GSS-API negotiation")
3069 set_config("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
3070 set_define("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
3073 # Parental control
3074 # ==============================================================
3075 option("--disable-parental-controls", help="Do not build parental controls")
3077 set_config(
3078     "MOZ_DISABLE_PARENTAL_CONTROLS",
3079     True,
3080     when=depends("--enable-parental-controls")(lambda x: not x),
3082 set_define(
3083     "MOZ_DISABLE_PARENTAL_CONTROLS",
3084     True,
3085     when=depends("--enable-parental-controls")(lambda x: not x),
3089 # Sandboxing support
3090 # ==============================================================
3091 @depends(target, tsan, asan)
3092 def sandbox_default(target, tsan, asan):
3093     # Only enable the sandbox by default on Linux, OpenBSD, macOS, and Windows
3094     if target.kernel == "Linux" and target.os == "GNU":
3095         # Bug 1182565: TSan conflicts with sandboxing on Linux.
3096         # Bug 1287971: LSan also conflicts with sandboxing on Linux.
3097         if tsan or asan:
3098             return False
3099         # Linux sandbox is only available on x86{,_64} and arm{,64}.
3100         return target.cpu in ("x86", "x86_64", "arm", "aarch64")
3101     return target.kernel in ("WINNT", "Darwin", "OpenBSD")
3104 option(
3105     "--enable-sandbox",
3106     default=sandbox_default,
3107     help="{Enable|Disable} sandboxing support",
3110 set_config("MOZ_SANDBOX", True, when="--enable-sandbox")
3111 set_define("MOZ_SANDBOX", True, when="--enable-sandbox")
3113 with only_when(depends(target.kernel)(lambda k: k not in ("Darwin", "WINNT"))):
3114     set_define("MOZ_CONTENT_TEMP_DIR", True, when="--enable-sandbox")
3116 # Searching of system directories for extensions.
3117 # ==============================================================
3118 # Note: this switch is meant to be used for test builds whose behavior should
3119 # not depend on what happens to be installed on the local machine.
3120 option(
3121     "--disable-system-extension-dirs",
3122     help="Disable searching system- and account-global directories for extensions"
3123     " of any kind; use only profile-specific extension directories",
3126 set_define("ENABLE_SYSTEM_EXTENSION_DIRS", True, when="--enable-system-extension-dirs")
3129 # Pixman
3130 # ==============================================================
3131 with only_when(compile_environment):
3132     system_lib_option(
3133         "--enable-system-pixman", help="Use system pixman (located with pkgconfig)"
3134     )
3136     @depends("--enable-system-pixman")
3137     def in_tree_pixman(pixman):
3138         return not pixman
3140     set_config("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3141     set_define("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
3143     pkg_check_modules("MOZ_PIXMAN", "pixman-1 >= 0.36.0", when="--enable-system-pixman")
3144     # Set MOZ_PIXMAN_CFLAGS to an explicit empty value when --enable-system-pixman is *not* used,
3145     # for layout/style/extra-bindgen-flags
3146     set_config("MOZ_PIXMAN_CFLAGS", [], when=in_tree_pixman)
3149 # Universalchardet
3150 # ==============================================================
3151 with only_when(compile_environment):
3152     option("--disable-universalchardet", help="Disable universal encoding detection")
3154     set_config("MOZ_UNIVERSALCHARDET", True, when="--enable-universalchardet")
3157 # Disable zipwriter
3158 # ==============================================================
3159 with only_when(compile_environment):
3160     option("--disable-zipwriter", help="Disable zipwriter component")
3162     set_config("MOZ_ZIPWRITER", True, when="--enable-zipwriter")
3165 # Location of the mozilla user directory
3166 # ==============================================================
3167 with only_when(compile_environment):
3169     @depends(target)
3170     def default_user_appdir(target):
3171         if target.kernel in ("WINNT", "Darwin"):
3172             return "Mozilla"
3173         return ".mozilla"
3175     option(
3176         "--with-user-appdir",
3177         nargs=1,
3178         default=default_user_appdir,
3179         help="Set user-specific appdir",
3180     )
3182     @depends("--with-user-appdir")
3183     def user_appdir(appdir):
3184         if not appdir:
3185             die("--without-user-appdir is not a valid option.")
3186         if "/" in appdir[0]:
3187             die("--with-user-appdir must be a single relative path.")
3188         return '"{}"'.format(appdir[0])
3190     set_define("MOZ_USER_DIR", user_appdir)
3193 # Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
3194 # ==============================================================
3195 with only_when(compile_environment):
3196     have_sin_len = c_compiler.try_compile(
3197         includes=["netinet/in.h"],
3198         body="struct sockaddr_in x; void *foo = (void*) &x.sin_len;",
3199         check_msg="for sin_len in struct sockaddr_in",
3200     )
3201     have_sin6_len = c_compiler.try_compile(
3202         includes=["netinet/in.h"],
3203         body="struct sockaddr_in6 x; void *foo = (void*) &x.sin6_len;",
3204         check_msg="for sin_len6 in struct sockaddr_in6",
3205     )
3206     set_define("HAVE_SIN_LEN", have_sin_len)
3207     set_define("HAVE_SIN6_LEN", have_sin6_len)
3208     # HAVE_CONN_LEN must be the same as HAVE_SIN_LEN and HAVE_SIN6_LEN
3209     set_define("HAVE_SCONN_LEN", have_sin_len & have_sin6_len)
3210     set_define(
3211         "HAVE_SA_LEN",
3212         c_compiler.try_compile(
3213             includes=["netinet/in.h"],
3214             body="struct sockaddr x; void *foo = (void*) &x.sa_len;",
3215             check_msg="for sa_len in struct sockaddr",
3216         ),
3217     )
3220 # Check for pthread_cond_timedwait_monotonic_np
3221 # ==============================================================
3222 with only_when(compile_environment):
3223     set_define(
3224         "HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC",
3225         c_compiler.try_compile(
3226             includes=["pthread.h"],
3227             body="pthread_cond_timedwait_monotonic_np(0, 0, 0);",
3228             # -Werror to catch any "implicit declaration" warning that means the function
3229             # is not supported.
3230             flags=["-Werror=implicit-function-declaration"],
3231             check_msg="for pthread_cond_timedwait_monotonic_np",
3232         ),
3233     )
3236 # Custom dynamic linker for Android
3237 # ==============================================================
3238 with only_when(target_has_linux_kernel & compile_environment):
3239     option(
3240         env="MOZ_LINKER",
3241         default=depends(target.os, when="--enable-jemalloc")(
3242             lambda os: os == "Android"
3243         ),
3244         help="{Enable|Disable} custom dynamic linker",
3245     )
3247     set_config("MOZ_LINKER", True, when="MOZ_LINKER")
3248     set_define("MOZ_LINKER", True, when="MOZ_LINKER")
3249     add_old_configure_assignment("MOZ_LINKER", True, when="MOZ_LINKER")
3251     moz_linker = depends(when="MOZ_LINKER")(lambda: True)
3254 # 32-bits ethtool_cmd.speed
3255 # ==============================================================
3256 with only_when(target_has_linux_kernel & compile_environment):
3257     set_config(
3258         "MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI",
3259         c_compiler.try_compile(
3260             includes=["linux/ethtool.h"],
3261             body="struct ethtool_cmd cmd; cmd.speed_hi = 0;",
3262             check_msg="for 32-bits ethtool_cmd.speed",
3263         ),
3264     )
3266 # Gamepad support
3267 # ==============================================================
3268 check_header(
3269     "linux/joystick.h",
3270     onerror=lambda: die(
3271         "Can't find header linux/joystick.h, needed for gamepad support."
3272         " Please install Linux kernel headers."
3273     ),
3274     when=target_has_linux_kernel & compile_environment,
3277 # Smart card support
3278 # ==============================================================
3279 @depends(build_project)
3280 def disable_smart_cards(build_project):
3281     return build_project == "mobile/android"
3284 set_config("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3285 set_define("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
3287 # Enable UniFFI fixtures
3288 # ==============================================================
3289 # These are used to test the uniffi-bindgen-gecko-js code generation.  They
3290 # should not be enabled in release builds.
3292 option(
3293     "--enable-uniffi-fixtures",
3294     help="Enable UniFFI Fixtures/Examples",
3297 set_config("MOZ_UNIFFI_FIXTURES", True, when="--enable-uniffi-fixtures")
3299 # Checks for library functions
3300 # ==============================================================
3301 with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
3302     set_define("HAVE_STAT64", check_symbol("stat64"))
3303     set_define("HAVE_LSTAT64", check_symbol("lstat64"))
3304     set_define("HAVE_TRUNCATE64", check_symbol("truncate64"))
3305     set_define("HAVE_STATVFS64", check_symbol("statvfs64"))
3306     set_define("HAVE_STATVFS", check_symbol("statvfs"))
3307     set_define("HAVE_STATFS64", check_symbol("statfs64"))
3308     set_define("HAVE_STATFS", check_symbol("statfs"))
3309     set_define("HAVE_LUTIMES", check_symbol("lutimes"))
3310     set_define("HAVE_POSIX_FADVISE", check_symbol("posix_fadvise"))
3311     set_define("HAVE_POSIX_FALLOCATE", check_symbol("posix_fallocate"))
3313     set_define("HAVE_ARC4RANDOM", check_symbol("arc4random"))
3314     set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf"))
3315     set_define("HAVE_MALLINFO", check_symbol("mallinfo"))
3317 # System policies
3318 # ==============================================================
3320 option(
3321     "--disable-system-policies",
3322     help="Disable reading policies from Windows registry, macOS's file system attributes, and /etc/firefox",
3325 set_config("MOZ_SYSTEM_POLICIES", True, when="--enable-system-policies")
3327 # Allow disabling the creation a legacy profile
3328 # ==============================================================
3330 option(
3331     "--disable-legacy-profile-creation",
3332     help="Disable the creation a legacy profile, to be used by old versions "
3333     "of Firefox, when no profiles exist.",
3336 set_config("MOZ_CREATE_LEGACY_PROFILE", True, when="--enable-legacy-profile-creation")
3339 # STL wrapping
3340 # ==============================================================
3341 set_config("WRAP_STL_INCLUDES", True)
3342 set_config(
3343     "STL_FLAGS",
3344     depends(build_environment.dist)(lambda dist: [f"-I{dist}/stl_wrappers"]),
3348 # Perl detection
3349 # ==============================================================
3350 @depends(target)
3351 def need_perl(target):
3352     # Ideally, we'd also depend on gnu_as here, but that adds complications.
3353     return target.cpu == "arm"
3356 perl = check_prog("PERL", ("perl5", "perl"), when=need_perl)
3359 @template
3360 def perl_version_check(min_version):
3361     @depends(perl)
3362     @checking("for minimum required perl version >= %s" % min_version)
3363     def get_perl_version(perl):
3364         return Version(
3365             check_cmd_output(
3366                 perl,
3367                 "-e",
3368                 "print $]",
3369                 onerror=lambda: die("Failed to get perl version."),
3370             )
3371         )
3373     @depends(get_perl_version)
3374     def check_perl_version(version):
3375         if version < min_version:
3376             die("Perl %s or higher is required.", min_version)
3378     @depends(perl)
3379     @checking("for full perl installation")
3380     @imports("subprocess")
3381     def has_full_perl_installation(perl):
3382         ret = subprocess.call([perl, "-e", "use Config; exit(!-d $Config{archlib})"])
3383         return ret == 0
3385     @depends(has_full_perl_installation)
3386     def require_full_perl_installation(has_full_perl_installation):
3387         if not has_full_perl_installation:
3388             die(
3389                 "Cannot find Config.pm or $Config{archlib}. "
3390                 "A full perl installation is required."
3391             )
3394 with only_when(need_perl):
3395     perl_version_check("5.006")