summaryrefslogtreecommitdiffstats
path: root/toolkit/moz.configure
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/moz.configure')
-rw-r--r--toolkit/moz.configure3684
1 files changed, 3684 insertions, 0 deletions
diff --git a/toolkit/moz.configure b/toolkit/moz.configure
new file mode 100644
index 0000000000..b616109b1f
--- /dev/null
+++ b/toolkit/moz.configure
@@ -0,0 +1,3684 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+# Set the MOZ_CONFIGURE_OPTIONS variable with all the options that
+# were passed somehow (environment, command line, mozconfig)
+@dependable
+@imports(_from="mozbuild.shellutil", _import="quote")
+@imports(_from="mozbuild.util", _import="ensure_unicode")
+@imports(_from="mozbuild.util", _import="system_encoding")
+@imports("__sandbox__")
+def all_configure_options():
+ result = []
+ previous = None
+ for option in __sandbox__._options.values():
+ # __sandbox__._options contains items for both option.name and
+ # option.env. But it's also an OrderedDict, meaning both are
+ # consecutive.
+ # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not
+ # interesting.
+ if option == previous or option.env in ("OLD_CONFIGURE", "MOZCONFIG"):
+ continue
+ previous = option
+ value = __sandbox__._value_for(option)
+ # We only want options that were explicitly given on the command
+ # line, the environment, or mozconfig, and that differ from the
+ # defaults.
+ if (
+ value is not None
+ and value.origin not in ("default", "implied")
+ and value != option.default
+ ):
+ result.append(
+ ensure_unicode(__sandbox__._raw_options[option], system_encoding)
+ )
+ # We however always include options that are sent to old configure
+ # because we don't know their actual defaults. (Keep the conditions
+ # separate for ease of understanding and ease of removal)
+ elif (
+ option.help == "Help missing for old configure options"
+ and option in __sandbox__._raw_options
+ ):
+ result.append(
+ ensure_unicode(__sandbox__._raw_options[option], system_encoding)
+ )
+
+ # We shouldn't need this, but currently, quote will return a byte string
+ # if result is empty, and that's not wanted here.
+ if not result:
+ return ""
+
+ return quote(*result)
+
+
+set_config("MOZ_CONFIGURE_OPTIONS", all_configure_options)
+
+
+@depends(target)
+def fold_libs(target):
+ return target.os in ("WINNT", "OSX", "Android")
+
+
+set_config("MOZ_FOLD_LIBS", fold_libs)
+
+# Profiling
+# ==============================================================
+# Some of the options here imply an option from js/moz.configure,
+# so, need to be declared before the include.
+
+option(
+ "--enable-jprof",
+ env="MOZ_JPROF",
+ help="Enable jprof profiling tool (needs mozilla/tools/jprof)",
+)
+
+
+@depends("--enable-jprof")
+def jprof(value):
+ if value:
+ return True
+
+
+set_config("MOZ_JPROF", jprof)
+set_define("MOZ_JPROF", jprof)
+imply_option("--enable-profiling", jprof)
+
+
+@depends(target)
+def gecko_profiler(target):
+ if target.os == "Android":
+ return target.cpu in ("aarch64", "arm", "x86", "x86_64")
+ elif target.kernel == "Linux":
+ return target.cpu in ("aarch64", "arm", "x86", "x86_64", "mips64")
+ elif target.kernel == "FreeBSD":
+ return target.cpu in ("aarch64", "x86_64")
+ return target.os in ("OSX", "WINNT")
+
+
+@depends(gecko_profiler)
+def gecko_profiler_define(value):
+ if value:
+ return True
+
+
+set_config("MOZ_GECKO_PROFILER", gecko_profiler_define)
+set_define("MOZ_GECKO_PROFILER", gecko_profiler_define)
+
+
+# Whether code to parse ELF binaries should be compiled for the Gecko profiler
+# (for symbol table dumping).
+@depends(gecko_profiler, target)
+def gecko_profiler_parse_elf(value, target):
+ # Currently we only want to build this code on Linux (including Android) and BSD.
+ # For Android, this is in order to dump symbols from Android system, where
+ # on other platforms there exist alternatives that don't require bloating
+ # up our binary size. For Linux more generally, we use this in profile
+ # pre-symbolication support, since MozDescribeCodeAddress doesn't do
+ # anything useful on that platform. (Ideally, we would update
+ # MozDescribeCodeAddress to call into some Rust crates that parse ELF and
+ # DWARF data, but build system issues currently prevent Rust from being
+ # used in mozglue.)
+ if value and (target.kernel == "Linux" or target.kernel == "FreeBSD"):
+ return True
+
+
+set_config("MOZ_GECKO_PROFILER_PARSE_ELF", gecko_profiler_parse_elf)
+set_define("MOZ_GECKO_PROFILER_PARSE_ELF", gecko_profiler_parse_elf)
+
+# enable this by default if the profiler is enabled
+# Note: also requires jemalloc
+set_config("MOZ_PROFILER_MEMORY", gecko_profiler_define)
+set_define("MOZ_PROFILER_MEMORY", gecko_profiler_define)
+
+
+@depends(
+ "--enable-debug",
+ milestone,
+ build_project,
+ # Artifact builds are included because the downloaded artifacts can
+ # have DMD enabled.
+ when=artifact_builds | depends(when="--enable-replace-malloc")(lambda: True),
+)
+def dmd_default(debug, milestone, build_project):
+ return bool(build_project == "browser" and (debug or milestone.is_nightly))
+
+
+option(
+ "--enable-dmd",
+ env="MOZ_DMD",
+ default=dmd_default,
+ help="{Enable|Disable} Dark Matter Detector (heap profiler). "
+ "Also enables jemalloc, replace-malloc and profiling",
+)
+
+
+@depends("--enable-dmd")
+def dmd(value):
+ if value:
+ return True
+
+
+set_config("MOZ_DMD", dmd)
+set_define("MOZ_DMD", dmd)
+imply_option("--enable-profiling", dmd)
+imply_option("--enable-jemalloc", dmd, when=compile_environment)
+imply_option("--enable-replace-malloc", dmd, when=compile_environment)
+
+
+# midir-based Web MIDI support
+# ==============================================================
+@depends(target)
+def midir_linux_support(target):
+ return (
+ target.kernel == "Linux" and target.os != "Android" and target.cpu != "riscv64"
+ )
+
+
+@depends(target, midir_linux_support)
+def midir_support(target, midir_linux_support):
+ if target.os in ("WINNT", "OSX") or midir_linux_support:
+ return True
+
+
+set_config("MOZ_WEBMIDI_MIDIR_IMPL", midir_support)
+
+
+# Enable various cubeb backends
+# ==============================================================
+@depends(target)
+def audio_backends_default(target):
+ if target.os == "Android":
+ return (
+ "aaudio",
+ "opensl",
+ )
+ elif target.os in ("DragonFly", "FreeBSD", "SunOS"):
+ return ("oss",)
+ elif target.os == "OpenBSD":
+ return ("sndio",)
+ elif target.os == "OSX":
+ return ("audiounit",)
+ elif target.os == "NetBSD":
+ return ("sunaudio",)
+ elif target.os == "SunOS":
+ return ("sunaudio",)
+ elif target.os == "WINNT":
+ return ("wasapi",)
+ else:
+ return ("pulseaudio",)
+
+
+option(
+ "--enable-audio-backends",
+ nargs="+",
+ choices=(
+ "aaudio",
+ "alsa",
+ "audiounit",
+ "jack",
+ "opensl",
+ "oss",
+ "pulseaudio",
+ "sndio",
+ "sunaudio",
+ "wasapi",
+ ),
+ default=audio_backends_default,
+ help="{Enable|Disable} various cubeb backends",
+)
+
+
+@depends("--enable-audio-backends", target)
+def imply_aaudio(values, target):
+ if any("aaudio" in value for value in values) and target.os != "Android":
+ die("Cannot enable AAudio on %s", target.os)
+ return any("aaudio" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_alsa(values, target):
+ if (
+ any("alsa" in value for value in values)
+ and target.kernel != "Linux"
+ and target.os != "FreeBSD"
+ ):
+ die("Cannot enable ALSA on %s", target.os)
+ return any("alsa" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_audiounit(values, target):
+ if (
+ any("audiounit" in value for value in values)
+ and target.os != "OSX"
+ and target.kernel != "Darwin"
+ ):
+ die("Cannot enable AudioUnit on %s", target.os)
+ return any("audiounit" in value for value in values) or None
+
+
+@depends("--enable-audio-backends")
+def imply_jack(values):
+ return any("jack" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_opensl(values, target):
+ if any("opensl" in value for value in values) and target.os != "Android":
+ die("Cannot enable OpenSL on %s", target.os)
+ return any("opensl" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_oss(values, target):
+ if any("oss" in value for value in values) and (
+ target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
+ ):
+ die("Cannot enable OSS on %s", target.os)
+ return any("oss" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_pulseaudio(values, target):
+ if any("pulseaudio" in value for value in values) and (
+ target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
+ ):
+ die("Cannot enable PulseAudio on %s", target.os)
+ return any("pulseaudio" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_sndio(values, target):
+ if any("sndio" in value for value in values) and (
+ target.os == "Android" or target.os == "OSX" or target.os == "WINNT"
+ ):
+ die("Cannot enable sndio on %s", target.os)
+ return any("sndio" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_sunaudio(values, target):
+ if any("sunaudio" in value for value in values) and (
+ target.os != "NetBSD" and target.os != "SunOS"
+ ):
+ die("Cannot enable sunaudio on %s", target.os)
+ return any("sunaudio" in value for value in values) or None
+
+
+@depends("--enable-audio-backends", target)
+def imply_wasapi(values, target):
+ if any("wasapi" in value for value in values) and target.os != "WINNT":
+ die("Cannot enable WASAPI on %s", target.os)
+ return any("wasapi" in value for value in values) or None
+
+
+set_config("MOZ_AAUDIO", imply_aaudio, when="--enable-audio-backends")
+
+imply_option("--enable-alsa", imply_alsa, reason="--enable-audio-backends")
+
+set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")
+
+imply_option("--enable-jack", imply_jack, reason="--enable-audio-backends")
+
+set_config("MOZ_OPENSL", imply_opensl, when="--enable-audio-backends")
+
+set_config("MOZ_OSS", imply_oss, when="--enable-audio-backends")
+
+imply_option("--enable-pulseaudio", imply_pulseaudio, reason="--enable-audio-backends")
+
+imply_option("--enable-sndio", imply_sndio, reason="--enable-audio-backends")
+
+set_config("MOZ_SUNAUDIO", imply_sunaudio, when="--enable-audio-backends")
+
+set_config("MOZ_WASAPI", imply_wasapi, when="--enable-audio-backends")
+
+# ALSA cubeb backend
+# ==============================================================
+option("--enable-alsa", env="MOZ_ALSA", help="Enable ALSA audio backend.")
+
+
+@depends("--enable-alsa", midir_linux_support)
+def enable_alsa_or_midir_linux_support(alsa_enabled, midir_linux_support):
+ return alsa_enabled or midir_linux_support
+
+
+pkg_check_modules("MOZ_ALSA", "alsa", when=enable_alsa_or_midir_linux_support)
+
+set_config("MOZ_ALSA", True, when="--enable-alsa")
+set_define("MOZ_ALSA", True, when="--enable-alsa")
+
+# JACK cubeb backend
+# ==============================================================
+system_lib_option("--enable-jack", env="MOZ_JACK", help="Enable JACK audio backend.")
+
+jack = pkg_check_modules("MOZ_JACK", "jack", when="--enable-jack")
+
+set_config("MOZ_JACK", depends_if(jack)(lambda _: True))
+
+# PulseAudio cubeb backend
+# ==============================================================
+option(
+ "--enable-pulseaudio",
+ env="MOZ_PULSEAUDIO",
+ help="{Enable|Disable} PulseAudio audio backend.",
+)
+
+pulseaudio = pkg_check_modules("MOZ_PULSEAUDIO", "libpulse", when="--enable-pulseaudio")
+
+set_config("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
+set_define("MOZ_PULSEAUDIO", depends_if(pulseaudio)(lambda _: True))
+
+# sndio cubeb backend
+# ==============================================================
+system_lib_option("--enable-sndio", env="MOZ_SNDIO", help="Enable sndio audio backend.")
+
+sndio = pkg_check_modules("MOZ_SNDIO", "sndio", when="--enable-sndio")
+
+set_config("MOZ_SNDIO", depends_if(sndio)(lambda _: True))
+
+# Javascript engine
+# ==============================================================
+include("../js/moz.configure")
+
+
+# NodeJS
+# ==============================================================
+include("../build/moz.configure/node.configure")
+
+# JsonCpp
+# ==============================================================
+set_define("JSON_USE_EXCEPTION", 0)
+
+# L10N
+# ==============================================================
+option("--with-l10n-base", nargs=1, env="L10NBASEDIR", help="Path to l10n repositories")
+
+
+@depends("--with-l10n-base", "MOZ_AUTOMATION", build_environment)
+@imports(_from="os.path", _import="isdir")
+@imports(_from="os.path", _import="expanduser")
+@imports(_from="os", _import="environ")
+def l10n_base(value, automation, build_env):
+ if value:
+ path = value[0]
+ if not isdir(path):
+ die("Invalid value --with-l10n-base, %s doesn't exist", path)
+ elif automation:
+ path = os.path.join(build_env.topsrcdir, "../l10n-central")
+ else:
+ path = os.path.join(
+ environ.get(
+ "MOZBUILD_STATE_PATH", expanduser(os.path.join("~", ".mozbuild"))
+ ),
+ "l10n-central",
+ )
+ return os.path.realpath(os.path.abspath(path))
+
+
+set_config("L10NBASEDIR", l10n_base)
+
+
+# Default toolkit
+# ==============================================================
+@depends(target)
+def toolkit_choices(target):
+ if target.os == "WINNT":
+ return ("cairo-windows",)
+ elif target.os == "OSX":
+ return ("cairo-cocoa",)
+ elif target.os == "Android":
+ return ("cairo-android",)
+ else:
+ # cairo-gtk3 - X11 backend with optional Wayland backend (auto detected)
+ # cairo-gtk3-wayland - Wayland backend with optional X11 backend (auto detected)
+ # cairo-gtk3-x11-wayland - builds explicitly with X11 & Wayland backends
+ return (
+ "cairo-gtk3",
+ "cairo-gtk3-wayland",
+ "cairo-gtk3-x11-wayland",
+ "cairo-gtk3-wayland-only",
+ "cairo-gtk3-x11-only",
+ )
+
+
+@depends(toolkit_choices)
+def toolkit_default(choices):
+ return choices[0]
+
+
+option(
+ "--enable-default-toolkit",
+ nargs=1,
+ choices=toolkit_choices,
+ default=toolkit_default,
+ help="Select default toolkit",
+)
+
+
+@depends("--enable-default-toolkit")
+def full_toolkit(value):
+ if value:
+ return value[0]
+
+
+@depends(full_toolkit)
+def toolkit(toolkit):
+ if toolkit.startswith("cairo-gtk3"):
+ widget_toolkit = "gtk"
+ else:
+ widget_toolkit = toolkit.replace("cairo-", "")
+ return widget_toolkit
+
+
+set_config("MOZ_WIDGET_TOOLKIT", toolkit)
+add_old_configure_assignment("MOZ_WIDGET_TOOLKIT", toolkit)
+
+
+@depends(toolkit)
+def toolkit_define(toolkit):
+ if toolkit != "windows":
+ return "MOZ_WIDGET_%s" % toolkit.upper()
+
+
+set_define(toolkit_define, True)
+
+
+@depends(toolkit)
+def toolkit_gtk(toolkit):
+ return toolkit == "gtk"
+
+
+@depends(toolkit_gtk, full_toolkit)
+def toolkit_gtk_x11(toolkit_gtk, full_toolkit):
+ return toolkit_gtk and full_toolkit != "cairo-gtk3-wayland-only"
+
+
+@depends(full_toolkit)
+def toolkit_gtk_x11_optional(full_toolkit):
+ return full_toolkit == "cairo-gtk3-wayland"
+
+
+@depends(toolkit_gtk, full_toolkit)
+def toolkit_gtk_wayland(toolkit_gtk, full_toolkit):
+ return toolkit_gtk and full_toolkit != "cairo-gtk3-x11-only"
+
+
+@depends(full_toolkit)
+def toolkit_gtk_wayland_optional(full_toolkit):
+ return full_toolkit == "cairo-gtk3"
+
+
+# Wayland support
+# ==============================================================
+wayland_headers = pkg_check_modules(
+ "MOZ_WAYLAND",
+ "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1",
+ allow_missing=toolkit_gtk_wayland_optional,
+ when=toolkit_gtk_wayland,
+)
+
+
+@depends(wayland_headers, toolkit_gtk, artifact_builds, toolkit_gtk_wayland)
+def wayland_headers(wayland, toolkit_gtk, artifacts, toolkit_gtk_wayland):
+ if not toolkit_gtk_wayland:
+ return False
+ if toolkit_gtk and artifacts:
+ return True
+ return wayland
+
+
+set_config("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
+set_define("MOZ_WAYLAND", depends_if(wayland_headers)(lambda _: True))
+
+
+# Hardware-accelerated video decode with VAAPI and V4L2 on Linux
+# ==============================================================
+set_config("MOZ_ENABLE_VAAPI", True, when=toolkit_gtk)
+set_define("MOZ_ENABLE_VAAPI", True, when=toolkit_gtk)
+
+
+@depends(target, toolkit_gtk)
+def v4l2(target, toolkit_gtk):
+ # V4L2 decode is only used in GTK/Linux and generally only appears on
+ # embedded SOCs.
+ if target.cpu in ("arm", "aarch64", "riscv64") and toolkit_gtk:
+ return True
+
+
+set_config("MOZ_ENABLE_V4L2", True, when=v4l2)
+set_define("MOZ_ENABLE_V4L2", True, when=v4l2)
+
+# GL Provider
+# ==============================================================
+option("--with-gl-provider", nargs=1, help="Set GL provider backend type")
+
+
+@depends("--with-gl-provider")
+def gl_provider(value):
+ if value:
+ return value[0]
+
+
+@depends(gl_provider)
+def gl_provider_define(provider):
+ if provider:
+ return "GLContextProvider%s" % provider
+
+
+set_define("MOZ_GL_PROVIDER", gl_provider_define)
+
+
+@depends(gl_provider, toolkit_gtk)
+def gl_default_provider(value, toolkit_gtk):
+ if value:
+ return value
+ elif toolkit_gtk:
+ return "EGL"
+
+
+set_config("MOZ_GL_PROVIDER", gl_provider)
+set_config("MOZ_GL_DEFAULT_PROVIDER", gl_default_provider)
+
+
+@depends(gl_default_provider)
+def gl_provider_define(provider):
+ if provider:
+ return "GL_PROVIDER_%s" % provider
+
+
+set_define(gl_provider_define, True)
+
+
+# PDF printing
+# ==============================================================
+@depends(toolkit)
+def pdf_printing(toolkit):
+ if toolkit in ("windows", "gtk", "android"):
+ return True
+
+
+set_config("MOZ_PDF_PRINTING", pdf_printing)
+set_define("MOZ_PDF_PRINTING", pdf_printing)
+
+
+# Event loop instrumentation
+# ==============================================================
+option(env="MOZ_INSTRUMENT_EVENT_LOOP", help="Force-enable event loop instrumentation")
+
+
+@depends("MOZ_INSTRUMENT_EVENT_LOOP", toolkit)
+def instrument_event_loop(value, toolkit):
+ if value or (
+ toolkit in ("windows", "gtk", "cocoa", "android") and value.origin == "default"
+ ):
+ return True
+
+
+set_config("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
+set_define("MOZ_INSTRUMENT_EVENT_LOOP", instrument_event_loop)
+
+
+# Fontconfig Freetype
+# ==============================================================
+option(env="USE_FC_FREETYPE", help="Force-enable the use of fontconfig freetype")
+
+
+@depends("USE_FC_FREETYPE", toolkit)
+def fc_freetype(value, toolkit):
+ if value or (toolkit == "gtk" and value.origin == "default"):
+ return True
+
+
+set_define("USE_FC_FREETYPE", fc_freetype)
+
+# Pango
+# ==============================================================
+pkg_check_modules("MOZ_PANGO", "pango >= 1.22.0", when=toolkit_gtk)
+
+# Fontconfig
+# ==============================================================
+fontconfig_info = pkg_check_modules(
+ "_FONTCONFIG", "fontconfig >= 2.7.0", when=fc_freetype
+)
+
+
+@depends(fc_freetype)
+def check_for_freetype2(fc_freetype):
+ if fc_freetype:
+ return True
+
+
+# Check for freetype2. Flags are combined with fontconfig flags.
+freetype2_info = pkg_check_modules(
+ "_FT2", "freetype2 >= 9.10.3", when=check_for_freetype2
+)
+
+
+@depends(fontconfig_info, freetype2_info)
+def freetype2_combined_info(fontconfig_info, freetype2_info):
+ if not freetype2_info:
+ return
+ if not fontconfig_info:
+ return freetype2_info
+ return namespace(
+ cflags=freetype2_info.cflags + fontconfig_info.cflags,
+ libs=freetype2_info.libs + fontconfig_info.libs,
+ )
+
+
+set_define("MOZ_HAVE_FREETYPE2", depends_if(freetype2_info)(lambda _: True))
+
+
+# Apple platform decoder support
+# ==============================================================
+@depends(toolkit)
+def applemedia(toolkit):
+ if toolkit in ("cocoa", "uikit"):
+ return True
+
+
+set_config("MOZ_APPLEMEDIA", applemedia)
+set_define("MOZ_APPLEMEDIA", applemedia)
+
+# Windows Media Foundation support
+# ==============================================================
+option("--disable-wmf", help="Disable support for Windows Media Foundation")
+
+
+@depends("--disable-wmf", target, "--help")
+def wmf(value, target, _):
+ enabled = bool(value)
+ if value.origin == "default":
+ # Enable Windows Media Foundation support by default.
+ # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
+ # guaranteed to have a recent-enough SDK to build WMF.
+ enabled = target.os == "WINNT"
+ if enabled and target.os != "WINNT":
+ die("Cannot enable Windows Media Foundation support on %s", target.os)
+ if enabled:
+ return True
+
+
+@depends(artifact_builds, c_compiler, when=wmf)
+def wmfmediaengine(artifact_builds, c_compiler):
+ if c_compiler:
+ return c_compiler.type == "clang-cl"
+ return bool(artifact_builds)
+
+
+set_config("MOZ_WMF", wmf)
+set_define("MOZ_WMF", wmf)
+
+set_config("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
+set_define("MOZ_WMF_MEDIA_ENGINE", True, when=wmfmediaengine)
+
+# FFmpeg H264/AAC Decoding Support
+# ==============================================================
+option("--disable-ffmpeg", help="Disable FFmpeg for fragmented H264/AAC decoding")
+
+
+@depends("--disable-ffmpeg", target)
+def ffmpeg(value, target):
+ enabled = bool(value)
+ if value.origin == "default":
+ enabled = target.os not in ("Android", "WINNT")
+ if enabled:
+ return True
+
+
+set_config("MOZ_FFMPEG", ffmpeg)
+set_define("MOZ_FFMPEG", ffmpeg)
+
+# AV1 Video Codec Support
+# ==============================================================
+option("--disable-av1", help="Disable av1 video support")
+
+
+@depends("--enable-av1")
+def av1(value):
+ if value:
+ return True
+
+
+@depends(target, when=av1 & compile_environment)
+def dav1d_asm(target):
+ if target.cpu in ("aarch64", "x86", "x86_64"):
+ return True
+
+
+@depends(target, when=av1 & compile_environment)
+def dav1d_nasm(target):
+ if target.cpu in ("x86", "x86_64"):
+ return namespace(version="2.14", what="AV1")
+
+
+set_config("MOZ_DAV1D_ASM", dav1d_asm)
+set_define("MOZ_DAV1D_ASM", dav1d_asm)
+set_config("MOZ_AV1", av1)
+set_define("MOZ_AV1", av1)
+
+# JXL Image Codec Support
+# ==============================================================
+option("--disable-jxl", help="Disable jxl image support")
+
+
+@depends("--disable-jxl", milestone.is_nightly)
+def jxl(value, is_nightly):
+ if is_nightly and value:
+ return True
+
+
+set_config("MOZ_JXL", jxl)
+set_define("MOZ_JXL", jxl)
+
+set_config("MOZ_SAMPLE_TYPE_FLOAT32", True)
+set_define("MOZ_SAMPLE_TYPE_FLOAT32", True)
+
+set_define("MOZ_VORBIS", True)
+set_config("MOZ_VORBIS", True)
+
+option(
+ "--disable-real-time-tracing",
+ help="Disable tracing of real-time audio callbacks",
+)
+
+set_config("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
+set_define("MOZ_REAL_TIME_TRACING", True, when="--enable-real-time-tracing")
+
+# OpenMAX IL Decoding Support
+# ==============================================================
+option("--enable-openmax", help="Enable OpenMAX IL for video/audio decoding")
+
+
+@depends("--enable-openmax")
+def openmax(value):
+ enabled = bool(value)
+ if enabled:
+ return True
+
+
+set_config("MOZ_OMX", openmax)
+set_define("MOZ_OMX", openmax)
+
+
+# EME Support
+# ==============================================================
+@depends(target, wmf)
+def eme_choices(target, wmf):
+ if (
+ target.kernel in ("WINNT", "Linux")
+ and target.os != "Android"
+ and target.cpu in ("x86", "x86_64")
+ ):
+ if wmf:
+ return ("widevine", "wmfcdm")
+ return ("widevine",)
+ if target.kernel == "WINNT" and target.cpu == "aarch64":
+ return ("widevine",)
+ if target.os in ("OSX"):
+ return ("widevine",)
+
+
+# Widevine is enabled by default in desktop browser builds.
+@depends(build_project, eme_choices)
+def eme_default(build_project, choices):
+ if build_project == "browser":
+ return choices
+
+
+option(
+ "--enable-eme",
+ nargs="+",
+ choices=eme_choices,
+ default=eme_default,
+ when=eme_choices,
+ help="{Enable|Disable} support for Encrypted Media Extensions",
+)
+
+
+@depends("--enable-eme", when=eme_choices)
+def eme_modules(value):
+ return value
+
+
+# Fallback to an empty list when eme_choices is empty, setting eme_modules to
+# None.
+set_config("MOZ_EME_MODULES", eme_modules | dependable([]))
+
+
+# Media Foundation CDM support
+# ==============================================================
+@depends(eme_modules, when=wmfmediaengine)
+def wmfcdm(modules):
+ if "wmfcdm" in modules:
+ return True
+
+
+set_config("MOZ_WMF_CDM", True, when=wmfcdm)
+set_define("MOZ_WMF_CDM", True, when=wmfcdm)
+
+
+option(
+ name="--enable-chrome-format",
+ help="Select FORMAT of chrome files during packaging.",
+ nargs=1,
+ choices=("omni", "jar", "flat"),
+ default="omni",
+)
+
+
+@depends("--enable-chrome-format")
+def packager_format(value):
+ return value[0]
+
+
+set_config("MOZ_PACKAGER_FORMAT", packager_format)
+
+# The packager minifies two different types of files: non-JS (mostly property
+# files for l10n), and JS. Setting MOZ_PACKAGER_MINIFY only minifies the
+# former. Firefox doesn't yet minify JS, due to concerns about debuggability.
+#
+# Also, the JS minification setup really only works correctly on Android:
+# we need extra setup to use the newly-built shell for Linux and Windows,
+# and cross-compilation for macOS requires some extra care.
+
+
+@depends(target_is_android, "--enable-debug", milestone.is_nightly)
+def enable_minify_default(is_android, debug, is_nightly):
+ if is_android and not debug and not is_nightly:
+ return ("properties", "js")
+ return ("properties",)
+
+
+option(
+ name="--enable-minify",
+ help="Select types of files to minify during packaging.",
+ nargs="*",
+ choices=("properties", "js"),
+ default=enable_minify_default,
+)
+
+
+@depends("--enable-minify")
+def enable_minify(value):
+ if "js" in value and "properties" not in value:
+ die("--enable-minify=js requires --enable-minify=properties.")
+ return namespace(
+ properties="properties" in value,
+ js="js" in value,
+ )
+
+
+set_config("MOZ_PACKAGER_MINIFY", True, when=enable_minify.properties)
+set_config("MOZ_PACKAGER_MINIFY_JS", True, when=enable_minify.js)
+
+
+@depends(host, build_project)
+def jar_maker_format(host, build_project):
+ # Multilocales for mobile/android use the same mergedirs for all locales,
+ # so we can't use symlinks for those builds.
+ if host.os == "WINNT" or build_project == "mobile/android":
+ return "flat"
+ return "symlink"
+
+
+set_config("MOZ_JAR_MAKER_FILE_FORMAT", jar_maker_format)
+
+
+@depends(toolkit)
+def omnijar_name(toolkit):
+ # Fennec's static resources live in the assets/ folder of the
+ # APK. Adding a path to the name here works because we only
+ # have one omnijar file in the final package (which is not the
+ # case on desktop).
+ return "assets/omni.ja" if toolkit == "android" else "omni.ja"
+
+
+set_config("OMNIJAR_NAME", omnijar_name)
+
+project_flag("MOZ_PLACES", help="Build Places if required", set_as_define=True)
+
+project_flag(
+ "MOZ_SERVICES_HEALTHREPORT",
+ help="Build Firefox Health Reporter Service",
+ set_as_define=True,
+)
+
+project_flag(
+ "MOZ_NORMANDY",
+ help="Enable Normandy recipe runner",
+ set_as_define=True,
+)
+
+project_flag("MOZ_SERVICES_SYNC", help="Build Sync Services if required")
+
+project_flag(
+ "MOZ_ANDROID_HISTORY",
+ help="Enable Android History instead of Places",
+ set_as_define=True,
+)
+
+project_flag(
+ "MOZ_DEDICATED_PROFILES",
+ help="Enable dedicated profiles per install",
+ set_as_define=True,
+)
+
+project_flag(
+ "MOZ_BLOCK_PROFILE_DOWNGRADE",
+ help="Block users from starting profiles last used by a newer build",
+ set_as_define=True,
+)
+
+
+@depends("MOZ_PLACES", "MOZ_ANDROID_HISTORY")
+def check_places_and_android_history(places, android_history):
+ if places and android_history:
+ die("Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.")
+
+
+option(
+ env="MOZ_TELEMETRY_REPORTING",
+ default=mozilla_official,
+ help="Enable telemetry reporting",
+)
+
+set_define("MOZ_TELEMETRY_REPORTING", True, when="MOZ_TELEMETRY_REPORTING")
+
+
+@depends("MOZ_TELEMETRY_REPORTING", milestone.is_nightly)
+def telemetry_on_by_default(reporting, is_nightly):
+ return reporting and is_nightly
+
+
+set_define("MOZ_TELEMETRY_ON_BY_DEFAULT", True, when=telemetry_on_by_default)
+
+
+# gpsd support
+# ==============================================================
+system_lib_option("--enable-gpsd", env="MOZ_GPSD", help="Enable gpsd support")
+
+
+@depends("--enable-gpsd")
+def gpsd(value):
+ return bool(value)
+
+
+system_gpsd = pkg_check_modules("MOZ_GPSD", "libgps >= 3.11", when=gpsd)
+
+set_config("MOZ_GPSD", depends_if(system_gpsd)(lambda _: True))
+
+# Miscellaneous programs
+# ==============================================================
+
+check_prog("TAR", ("gnutar", "gtar", "tar"))
+check_prog("UNZIP", ("unzip",))
+
+# Key files
+# ==============================================================
+include("../build/moz.configure/keyfiles.configure")
+
+simple_keyfile("Mozilla API")
+
+simple_keyfile("Google Location Service API")
+
+simple_keyfile("Google Safebrowsing API")
+
+id_and_secret_keyfile("Bing API")
+
+simple_keyfile("Adjust SDK")
+
+id_and_secret_keyfile("Leanplum SDK")
+
+simple_keyfile("Pocket API")
+
+
+# WebRender Debugger integration
+# ==============================================================
+
+option(
+ "--enable-webrender-debugger", help="Build the websocket debug server in WebRender"
+)
+
+set_config(
+ "MOZ_WEBRENDER_DEBUGGER", depends_if("--enable-webrender-debugger")(lambda _: True)
+)
+
+# Additional system headers defined at the application level
+# ==============================================================
+
+option(
+ "--enable-app-system-headers",
+ env="MOZ_APP_SYSTEM_HEADERS",
+ help="Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild",
+)
+
+
+@depends("--enable-app-system-headers")
+def app_system_headers(value):
+ if value:
+ return True
+
+
+set_config("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
+set_define("MOZ_APP_SYSTEM_HEADERS", app_system_headers)
+
+# Printing
+# ==============================================================
+option("--disable-printing", help="Disable printing support")
+
+
+@depends("--disable-printing")
+def printing(value):
+ if value:
+ return True
+
+
+set_config("NS_PRINTING", printing)
+set_define("NS_PRINTING", printing)
+set_define("NS_PRINT_PREVIEW", printing)
+
+
+# Speech-dispatcher support
+# ==============================================================
+@depends(toolkit)
+def no_speechd_on_non_gtk(toolkit):
+ if toolkit != "gtk":
+ return False
+
+
+imply_option(
+ "--enable-synth-speechd", no_speechd_on_non_gtk, reason="--enable-default-toolkit"
+)
+
+option("--disable-synth-speechd", help="Disable speech-dispatcher support")
+
+set_config("MOZ_SYNTH_SPEECHD", depends_if("--disable-synth-speechd")(lambda _: True))
+
+# Speech API
+# ==============================================================
+option("--disable-webspeech", help="Disable support for HTML Speech API")
+
+
+@depends("--disable-webspeech")
+def webspeech(value):
+ if value:
+ return True
+
+
+set_config("MOZ_WEBSPEECH", webspeech)
+set_define("MOZ_WEBSPEECH", webspeech)
+
+# Speech API test backend
+# ==============================================================
+option(
+ "--enable-webspeechtestbackend",
+ default=webspeech,
+ help="{Enable|Disable} support for HTML Speech API Test Backend",
+)
+
+
+@depends_if("--enable-webspeechtestbackend")
+def webspeech_test_backend(value):
+ return True
+
+
+set_config("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
+set_define("MOZ_WEBSPEECH_TEST_BACKEND", webspeech_test_backend)
+
+
+# Graphics
+# ==============================================================
+@depends(target, milestone)
+def skia_pdf_default(target, milestone):
+ return milestone.is_nightly and target.os != "WINNT"
+
+
+option("--enable-skia-pdf", default=skia_pdf_default, help="{Enable|Disable} Skia PDF")
+
+set_config("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
+set_define("MOZ_ENABLE_SKIA_PDF", True, when="--enable-skia-pdf")
+
+set_config(
+ "SKIA_INCLUDES",
+ [
+ "/gfx/skia",
+ "/gfx/skia/skia",
+ ],
+)
+
+system_lib_option(
+ "--with-system-webp", help="Use system libwebp (located with pkgconfig)"
+)
+
+system_webp = pkg_check_modules(
+ "MOZ_WEBP", "libwebp >= 1.0.2 libwebpdemux >= 1.0.2", when="--with-system-webp"
+)
+
+set_config("MOZ_SYSTEM_WEBP", depends(when=system_webp)(lambda: True))
+
+
+# Build Freetype in the tree
+# ==============================================================
+@depends(target, "--enable-skia-pdf")
+def tree_freetype(target, skia_pdf):
+ if target.os == "Android" or (skia_pdf and target.os == "WINNT"):
+ return True
+
+
+set_define("MOZ_TREE_FREETYPE", tree_freetype)
+set_config("MOZ_TREE_FREETYPE", tree_freetype)
+
+set_define("HAVE_FT_BITMAP_SIZE_Y_PPEM", tree_freetype)
+set_define("HAVE_FT_GLYPHSLOT_EMBOLDEN", tree_freetype)
+set_define("HAVE_FT_LOAD_SFNT_TABLE", tree_freetype)
+
+
+@depends(freetype2_combined_info, tree_freetype, build_environment)
+def ft2_info(freetype2_combined_info, tree_freetype, build_env):
+ if tree_freetype:
+ return namespace(
+ cflags=("-I%s/modules/freetype2/include" % build_env.topsrcdir,), libs=()
+ )
+ if freetype2_combined_info:
+ return freetype2_combined_info
+
+
+set_config("FT2_LIBS", ft2_info.libs)
+
+
+@depends(target, tree_freetype, freetype2_info)
+def enable_cairo_ft(target, tree_freetype, freetype2_info):
+ # Avoid defining MOZ_ENABLE_CAIRO_FT on Windows platforms because
+ # "cairo-ft-font.c" includes <dlfcn.h>, which only exists on posix platforms
+ return freetype2_info or (tree_freetype and target.os != "WINNT")
+
+
+set_config("MOZ_ENABLE_CAIRO_FT", True, when=enable_cairo_ft)
+set_config("CAIRO_FT_CFLAGS", ft2_info.cflags, when=enable_cairo_ft)
+
+
+# WebDriver (HTTP / BiDi)
+# ==============================================================
+#
+# WebDriver is a remote control interface that enables introspection and
+# control of user agents. It provides a platform- and language-neutral wire
+# protocol as a way for out-of-process programs to remotely instruct the
+# behavior of web browsers.
+#
+# The Gecko implementation is backed by Marionette and Remote Agent.
+# Both protocols are not really toolkit features, as much as Gecko engine
+# features. But they are enabled based on the toolkit, so here it lives.
+#
+# Marionette remote protocol
+# -----------------------------------------------------------
+#
+# Marionette is the Gecko remote protocol used for various remote control,
+# automation, and testing purposes throughout Gecko-based applications like
+# Firefox, Thunderbird, and any mobile browser built upon GeckoView.
+#
+# It also backs ../testing/geckodriver, which is Mozilla's WebDriver
+# implementation.
+#
+# The source of Marionette lives in ../remote/marionette.
+#
+# For more information, see:
+# https://firefox-source-docs.mozilla.org/testing/marionette/index.html
+#
+# Remote Agent (WebDriver BiDi / partial CDP)
+# -----------------------------------------------------------
+#
+# The primary purpose is the implementation of the WebDriver BiDi specification.
+# But it also complements the existing Firefox Developer Tools Remote Debugging
+# Protocol (RDP) by implementing a subset of the Chrome DevTools Protocol (CDP).
+#
+# The source of Remote Agent lives in ../remote.
+#
+# For more information, see:
+# https://firefox-source-docs.mozilla.org/remote/index.html
+
+
+option(
+ "--disable-webdriver",
+ help="Disable support for WebDriver remote protocols",
+)
+
+
+@depends("--disable-webdriver")
+def webdriver(enabled):
+ if enabled:
+ return True
+
+
+set_config("ENABLE_WEBDRIVER", webdriver)
+set_define("ENABLE_WEBDRIVER", webdriver)
+
+
+# geckodriver WebDriver implementation
+# ==============================================================
+#
+# Turn off geckodriver for build configs we don't handle yet,
+# but allow --enable-geckodriver to override when compile environment is available.
+# --disable-tests implies disabling geckodriver.
+# Disable building in CI
+
+
+@depends(
+ "--enable-tests", target, cross_compiling, hazard_analysis, asan, "MOZ_AUTOMATION"
+)
+def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
+ if not enable_tests:
+ return False
+ if hazard or target.os == "Android" or (asan and cross_compile):
+ return False
+ if automation:
+ return False
+ return True
+
+
+option(
+ "--enable-geckodriver",
+ default=geckodriver_default,
+ when="--enable-compile-environment",
+ help="{Build|Do not build} geckodriver",
+)
+
+
+@depends("--enable-geckodriver", when="--enable-compile-environment")
+def geckodriver(enabled):
+ if enabled:
+ return True
+
+
+set_config("MOZ_GECKODRIVER", geckodriver)
+
+
+# WebRTC
+# ========================================================
+@depends(target)
+def webrtc_default(target):
+ # Turn off webrtc for OS's we don't handle yet, but allow
+ # --enable-webrtc to override.
+ os_match = target.kernel in (
+ "Linux",
+ "WINNT",
+ "DragonFly",
+ "FreeBSD",
+ "kFreeBSD",
+ "NetBSD",
+ "OpenBSD",
+ )
+
+ if not os_match:
+ os_match = target.os in ("OSX",)
+
+ cpu_match = target.cpu in (
+ "x86_64",
+ "arm",
+ "aarch64",
+ "x86",
+ "ia64",
+ "mips32",
+ "mips64",
+ "ppc",
+ "ppc64",
+ "riscv64",
+ )
+
+ return os_match and cpu_match and target.endianness == "little"
+
+
+option(
+ "--disable-webrtc",
+ default=webrtc_default,
+ help="{Enable|Disable} support for WebRTC",
+)
+
+
+@depends("--disable-webrtc")
+def webrtc(enabled):
+ if enabled:
+ return True
+
+
+set_config("MOZ_WEBRTC", webrtc)
+set_define("MOZ_WEBRTC", webrtc)
+set_config("MOZ_SCTP", webrtc)
+set_define("MOZ_SCTP", webrtc)
+set_config("MOZ_SRTP", webrtc)
+set_define("MOZ_SRTP", webrtc)
+set_config("MOZ_WEBRTC_SIGNALING", webrtc)
+set_define("MOZ_WEBRTC_SIGNALING", webrtc)
+set_config("MOZ_PEERCONNECTION", webrtc)
+set_define("MOZ_PEERCONNECTION", webrtc)
+# MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
+# opt/production builds (via MOZ_CRASH())
+set_config("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
+set_define("MOZ_WEBRTC_ASSERT_ALWAYS", webrtc)
+
+# RAW media
+# ==============================================================
+
+
+@depends(target, webrtc)
+def raw_media_default(target, webrtc):
+ if target.os == "Android":
+ return True
+ if webrtc:
+ return True
+
+
+option(
+ "--enable-raw",
+ default=raw_media_default,
+ help="{Enable|Disable} support for RAW media",
+)
+
+set_config("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
+set_define("MOZ_RAW", depends_if("--enable-raw")(lambda _: True))
+
+
+# X11
+# ==============================================================
+@depends(webrtc, when=toolkit_gtk)
+def x11_libs(webrtc):
+ libs = [
+ "x11",
+ "xcb",
+ "xcb-shm",
+ "x11-xcb",
+ "xext",
+ "xrandr >= 1.4.0",
+ ]
+ if webrtc:
+ # third_party/libwebrtc/webrtc/webrtc_gn/moz.build adds those
+ # manually, ensure they're available.
+ libs += [
+ "xcomposite",
+ "xcursor",
+ "xdamage",
+ "xfixes",
+ "xi",
+ ]
+ return libs
+
+
+x11_headers = pkg_check_modules(
+ "MOZ_X11",
+ x11_libs,
+ allow_missing=toolkit_gtk_x11_optional,
+ when=toolkit_gtk_x11,
+)
+
+
+set_config("MOZ_X11", True, when=x11_headers)
+set_define("MOZ_X11", True, when=x11_headers)
+
+pkg_check_modules(
+ "MOZ_X11_SM",
+ ["ice", "sm"],
+ cflags_only=True,
+ allow_missing=toolkit_gtk_x11_optional,
+ when=toolkit_gtk_x11,
+)
+
+
+# ASan Reporter Addon
+# ==============================================================
+option(
+ "--enable-address-sanitizer-reporter",
+ help="Enable Address Sanitizer Reporter Extension",
+)
+
+
+@depends("--enable-address-sanitizer-reporter")
+def enable_asan_reporter(value):
+ if value:
+ return True
+
+
+set_config("MOZ_ASAN_REPORTER", enable_asan_reporter)
+set_define("MOZ_ASAN_REPORTER", enable_asan_reporter)
+
+# Checks for library functions
+# ==============================================================
+with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
+ set_define("HAVE_STAT64", check_symbol("stat64"))
+ set_define("HAVE_LSTAT64", check_symbol("lstat64"))
+ set_define("HAVE_TRUNCATE64", check_symbol("truncate64"))
+ set_define("HAVE_STATVFS64", check_symbol("statvfs64"))
+ set_define("HAVE_STATVFS", check_symbol("statvfs"))
+ set_define("HAVE_STATFS64", check_symbol("statfs64"))
+ set_define("HAVE_STATFS", check_symbol("statfs"))
+ set_define("HAVE_LUTIMES", check_symbol("lutimes"))
+ set_define("HAVE_POSIX_FADVISE", check_symbol("posix_fadvise"))
+ set_define("HAVE_POSIX_FALLOCATE", check_symbol("posix_fallocate"))
+ set_define("HAVE_EVENTFD", check_symbol("eventfd"))
+
+ have_arc4random = check_symbol("arc4random")
+ set_define("HAVE_ARC4RANDOM", have_arc4random)
+ set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf"))
+ set_define("HAVE_MALLINFO", check_symbol("mallinfo"))
+
+# Checks for headers
+# ==============================================================
+with only_when(compile_environment & depends(target.os)(lambda os: os != "WINNT")):
+ set_define("HAVE_SYSIOCCOM_H", check_header("sys/ioccom.h"))
+
+# Elfhack
+# ==============================================================
+with only_when("--enable-compile-environment"):
+
+ @depends(host, target)
+ def has_elfhack(host, target):
+ return (
+ target.kernel == "Linux"
+ and host.kernel == "Linux"
+ and target.cpu in ("arm", "aarch64", "x86", "x86_64")
+ )
+
+ option(
+ "--disable-elf-hack",
+ nargs="?",
+ choices=("legacy", "relr"),
+ help="{Enable|Disable} elf hacks",
+ when=has_elfhack,
+ )
+
+ @depends("--enable-elf-hack", when=has_elfhack)
+ def may_enable_legacy_elfhack(enable):
+ if enable and enable != ("relr",):
+ return enable
+
+ @depends("--enable-elf-hack", when=has_elfhack)
+ def may_enable_relrhack(enable):
+ if enable and enable != ("legacy",):
+ return enable
+
+ @depends(
+ have_arc4random,
+ android_version,
+ when=target_has_linux_kernel,
+ )
+ def may_use_pack_relative_relocs(have_arc4random, android_version):
+ # Packed relative relocations are only supported on Android since
+ # version 11 (API 30), and in glibc since version 2.36.
+ # glibc 2.36 also added the arc4random function, which is our proxy
+ # to detect this (or newer) version being used.
+ # When targetting those newer versions, we allow ourselves to use
+ # packed relative relocations rather than elfhack.
+ if android_version:
+ return android_version >= 30
+ return have_arc4random
+
+ @depends(
+ c_compiler,
+ extra_toolchain_flags,
+ linker_ldflags,
+ readelf,
+ when=may_use_pack_relative_relocs | may_enable_relrhack,
+ )
+ @checking("for -z pack-relative-relocs option to ld", bool)
+ @imports(_from="__builtin__", _import="FileNotFoundError")
+ @imports("os")
+ @imports(_from="tempfile", _import="mkstemp")
+ @imports("textwrap")
+ def has_pack_relative_relocs(
+ c_compiler,
+ extra_toolchain_flags,
+ linker_ldflags,
+ readelf,
+ ):
+ try:
+ fd, path = mkstemp(prefix="conftest.")
+ os.close(fd)
+
+ pack_rel_relocs = ["-Wl,-z,pack-relative-relocs"]
+ if (
+ try_invoke_compiler(
+ # No configure_cache because it would not create the
+ # expected output file.
+ None,
+ [c_compiler.compiler] + c_compiler.flags,
+ c_compiler.language,
+ # The resulting binary is expected to have relative
+ # relocations, the `ptr` variable attempts to ensure
+ # there is at least one. This requires the executable
+ # being built as position independent.
+ "int main() { return 0; }\nint (*ptr)() = main;",
+ pack_rel_relocs
+ + ["-pie", "-o", path]
+ + (extra_toolchain_flags or [])
+ + linker_ldflags,
+ wrapper=c_compiler.wrapper,
+ onerror=lambda: None,
+ )
+ is not None
+ ):
+ # BFD ld ignores options it doesn't understand. So check
+ # that we did get packed relative relocations (DT_RELR).
+ env = os.environ.copy()
+ env["LANG"] = "C"
+ dyn = check_cmd_output(readelf, "-d", path, env=env).splitlines()
+ tags = [
+ int(l.split()[0], 16) for l in dyn if l.strip().startswith("0x")
+ ]
+ # Older versions of readelf don't know about DT_RELR but will
+ # still display the tag number.
+ if 0x23 in tags:
+ needed = [l for l in dyn if l.split()[1:2] == ["(NEEDED)"]]
+ is_glibc = any(l.endswith("[libc.so.6]") for l in needed)
+ # The mold linker doesn't add a GLIBC_ABI_DT_RELR version
+ # dependency, which ld.so doesn't like.
+ # https://github.com/rui314/mold/issues/653#issuecomment-1670274638
+ if is_glibc:
+ versions = check_cmd_output(readelf, "-V", path, env=env)
+ if "GLIBC_ABI_DT_RELR" in versions.split():
+ return pack_rel_relocs
+ else:
+ return pack_rel_relocs
+ finally:
+ try:
+ os.remove(path)
+ except FileNotFoundError:
+ pass
+
+ @depends(
+ has_pack_relative_relocs,
+ may_enable_legacy_elfhack,
+ may_enable_relrhack,
+ may_use_pack_relative_relocs,
+ when=has_pack_relative_relocs,
+ )
+ def pack_relative_relocs_flags(
+ flags,
+ may_enable_legacy_elfhack,
+ may_enable_relrhack,
+ may_use_pack_relative_relocs,
+ ):
+ # When relrhack is enabled, we don't pass the flag to the linker because
+ # relrhack will take care of it.
+ if may_enable_relrhack and may_enable_relrhack.origin != "default":
+ return None
+ # if elfhack is explicitly enabled instead of relrhack, we prioritize it
+ # over packed relative relocs.
+ if may_enable_legacy_elfhack and may_enable_legacy_elfhack.origin != "default":
+ return None
+ if may_use_pack_relative_relocs:
+ return flags
+
+ add_old_configure_assignment("PACK_REL_RELOC_FLAGS", pack_relative_relocs_flags)
+
+ @depends(
+ select_linker,
+ pack_relative_relocs_flags,
+ has_pack_relative_relocs,
+ may_enable_legacy_elfhack,
+ may_enable_relrhack,
+ when=has_elfhack,
+ )
+ def which_elf_hack(
+ linker,
+ pack_relative_relocs_flags,
+ has_pack_relative_relocs,
+ may_enable_legacy_elfhack,
+ may_enable_relrhack,
+ ):
+ if pack_relative_relocs_flags:
+ return
+ if may_enable_relrhack:
+ if has_pack_relative_relocs:
+ return "relr"
+ elif (
+ may_enable_relrhack.origin != "default"
+ and not may_enable_legacy_elfhack
+ ):
+ die(
+ "Cannot enable relrhack without linker support for -z pack-relative-relocs"
+ )
+ if may_enable_legacy_elfhack:
+ if linker and linker.KIND in ("lld", "mold"):
+ if may_enable_legacy_elfhack.origin != "default":
+ die(
+ f"Cannot enable elfhack with {linker.KIND}."
+ " Use --enable-linker=bfd, --enable-linker=gold, or --disable-elf-hack"
+ )
+ else:
+ return "legacy"
+
+ set_config(
+ "USE_ELF_HACK", True, when=depends(which_elf_hack)(lambda x: x == "legacy")
+ )
+
+ use_relrhack = depends(which_elf_hack)(lambda x: x == "relr")
+ set_config("RELRHACK", True, when=use_relrhack)
+
+ @depends(c_compiler, linker_ldflags, when=use_relrhack)
+ def relrhack_real_linker(c_compiler, linker_ldflags):
+ ld = "ld"
+ for flag in linker_ldflags:
+ if flag.startswith("-fuse-ld="):
+ ld = "ld." + flag[len("-fuse-ld=") :]
+ ld = check_cmd_output(
+ c_compiler.compiler, f"--print-prog-name={ld}", *c_compiler.flags
+ )
+ return ld.rstrip()
+
+ @depends(relrhack_real_linker, when=use_relrhack)
+ def relrhack_linker(ld):
+ return os.path.basename(ld)
+
+ set_config("RELRHACK_LINKER", relrhack_linker)
+
+ std_filesystem = host_cxx_compiler.try_run(
+ header="#include <filesystem>",
+ body='auto foo = std::filesystem::absolute("");',
+ flags=host_linker_ldflags,
+ when=use_relrhack,
+ onerror=lambda: None,
+ )
+
+ stdcxxfs = host_cxx_compiler.try_run(
+ header="#include <filesystem>",
+ body='auto foo = std::filesystem::absolute("");',
+ flags=depends(host_linker_ldflags)(
+ lambda flags: (flags or []) + ["-lstdc++fs"]
+ ),
+ check_msg="whether std::filesystem requires -lstdc++fs",
+ when=use_relrhack & depends(std_filesystem)(lambda x: not x),
+ onerror=lambda: None,
+ )
+
+ set_config("RELRHACK_LIBS", ["stdc++fs"], when=stdcxxfs)
+
+ @depends(build_environment, relrhack_real_linker, when=use_relrhack)
+ def relrhack_ldflags(build_env, ld):
+ flags = [
+ "-B",
+ os.path.join(build_env.topobjdir, "build", "unix", "elfhack"),
+ ]
+ if os.path.basename(ld) != ld:
+ flags.append(f"-Wl,--real-linker,{ld}")
+ return flags
+
+ set_config("RELRHACK_LDFLAGS", relrhack_ldflags)
+
+
+@depends(build_environment)
+def idl_roots(build_env):
+ return namespace(
+ ipdl_root=os.path.join(build_env.topobjdir, "ipc", "ipdl"),
+ webidl_root=os.path.join(build_env.topobjdir, "dom", "bindings"),
+ xpcom_root=os.path.join(build_env.topobjdir, "xpcom", "components"),
+ )
+
+
+set_config("WEBIDL_ROOT", idl_roots.webidl_root)
+set_config("IPDL_ROOT", idl_roots.ipdl_root)
+set_config("XPCOM_ROOT", idl_roots.xpcom_root)
+
+# Proxy bypass protection
+# ==============================================================
+
+option(
+ "--enable-proxy-bypass-protection",
+ help="Prevent suspected or confirmed proxy bypasses",
+)
+
+
+@depends_if("--enable-proxy-bypass-protection")
+def proxy_bypass_protection(_):
+ return True
+
+
+set_config("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
+set_define("MOZ_PROXY_BYPASS_PROTECTION", proxy_bypass_protection)
+
+# Proxy direct failover
+# ==============================================================
+
+option(
+ "--disable-proxy-direct-failover",
+ help="Disable direct failover for system requests",
+)
+
+
+@depends_if("--disable-proxy-direct-failover")
+def proxy_direct_failover(value):
+ if value:
+ return True
+
+
+set_config("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
+set_define("MOZ_PROXY_DIRECT_FAILOVER", proxy_direct_failover)
+
+# MIDL
+# ==============================================================
+
+
+@depends(c_compiler, toolchain_prefix)
+def midl_names(c_compiler, toolchain_prefix):
+ if c_compiler and c_compiler.type in ["gcc", "clang"]:
+ # mingw
+ widl = ("widl",)
+ if toolchain_prefix:
+ prefixed = tuple("%s%s" % (p, "widl") for p in toolchain_prefix)
+ widl = prefixed + widl
+ return widl
+
+ return ("midl.exe",)
+
+
+@depends(target, "--enable-compile-environment")
+def check_for_midl(target, compile_environment):
+ if target.os != "WINNT":
+ return
+
+ if compile_environment:
+ return True
+
+
+midl = check_prog(
+ "MIDL",
+ midl_names,
+ when=check_for_midl,
+ allow_missing=True,
+ paths=sdk_bin_path,
+ # MIDL being used from a python wrapper script, we can live with it
+ # having spaces.
+ allow_spaces=True,
+)
+
+option(env="MIDL_FLAGS", nargs=1, help="Extra flags to pass to MIDL")
+
+
+@depends(
+ "MIDL_FLAGS",
+ target,
+ midl,
+ when=depends(midl, target)(lambda m, t: m and t.kernel == "WINNT"),
+)
+def midl_flags(flags, target, midl):
+ if flags:
+ flags = flags[0].split()
+ else:
+ flags = []
+
+ if not midl.endswith("widl"):
+ env = {
+ "x86": "win32",
+ "x86_64": "x64",
+ "aarch64": "arm64",
+ }[target.cpu]
+ return flags + ["-nologo", "-no_cpp", "-env", env]
+
+ # widl
+ return (
+ flags
+ + {
+ "x86": ["--win32", "-m32"],
+ "x86_64": ["--win64", "-m64"],
+ }[target.cpu]
+ )
+
+
+set_config("MIDL_FLAGS", midl_flags)
+
+# Accessibility
+# ==============================================================
+
+option("--disable-accessibility", help="Disable accessibility support")
+
+
+@depends("--enable-accessibility", check_for_midl, midl, c_compiler)
+def accessibility(value, check_for_midl, midl, c_compiler):
+ enabled = bool(value)
+
+ if not enabled:
+ return
+
+ if check_for_midl and not midl:
+ if c_compiler and c_compiler.type in ("gcc", "clang"):
+ die(
+ "You have accessibility enabled, but widl could not be found. "
+ "Add --disable-accessibility to your mozconfig or install widl. "
+ "See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details."
+ )
+ else:
+ die(
+ "MIDL could not be found. "
+ "Building accessibility without MIDL is not supported."
+ )
+
+ return enabled
+
+
+set_config("ACCESSIBILITY", accessibility)
+set_define("ACCESSIBILITY", accessibility)
+
+
+@depends(moz_debug, developer_options)
+def a11y_log(debug, developer_options):
+ return debug or developer_options
+
+
+set_config("A11Y_LOG", True, when=a11y_log)
+set_define("A11Y_LOG", True, when=a11y_log)
+
+
+# Addon signing
+# ==============================================================
+@depends(milestone)
+def require_signing(milestone):
+ return milestone.is_release_or_beta and not milestone.is_esr
+
+
+option(
+ env="MOZ_REQUIRE_SIGNING",
+ default=require_signing,
+ help="Enforce that add-ons are signed by the trusted root",
+)
+
+set_config("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
+set_define("MOZ_REQUIRE_SIGNING", True, when="MOZ_REQUIRE_SIGNING")
+
+option(
+ "--with-unsigned-addon-scopes",
+ nargs="+",
+ choices=("app", "system"),
+ help="Addon scopes where signature is not required",
+)
+
+
+@depends("--with-unsigned-addon-scopes")
+def unsigned_addon_scopes(scopes):
+ return namespace(
+ app="app" in scopes or None,
+ system="system" in scopes or None,
+ )
+
+
+set_config("MOZ_UNSIGNED_APP_SCOPE", unsigned_addon_scopes.app)
+set_config("MOZ_UNSIGNED_SYSTEM_SCOPE", unsigned_addon_scopes.system)
+
+
+# Addon sideloading
+# ==============================================================
+option(
+ "--allow-addon-sideload",
+ default=milestone.is_esr,
+ help="Addon sideloading is allowed",
+)
+
+
+set_config("MOZ_ALLOW_ADDON_SIDELOAD", True, when="--allow-addon-sideload")
+
+# WebExtensions API WebIDL bindings
+# ==============================================================
+
+
+@depends(milestone)
+def extensions_webidl_bindings_default(milestone):
+ # Only enable the webidl bindings for the WebExtensions APIs
+ # in Nightly.
+ return milestone.is_nightly
+
+
+option(
+ "--enable-extensions-webidl-bindings",
+ default=extensions_webidl_bindings_default,
+ help="{Enable|Disable} building experimental WebExtensions WebIDL bindings",
+)
+
+
+@depends("--enable-extensions-webidl-bindings")
+def extensions_webidl_enabled(value):
+ return bool(value)
+
+
+set_config("MOZ_WEBEXT_WEBIDL_ENABLED", extensions_webidl_enabled)
+
+# Launcher process (Windows only)
+# ==============================================================
+
+
+@depends(target)
+def launcher_process_default(target):
+ return target.os == "WINNT"
+
+
+option(
+ "--enable-launcher-process",
+ default=launcher_process_default,
+ help="{Enable|Disable} launcher process by default",
+)
+
+
+@depends("--enable-launcher-process", target)
+def launcher(value, target):
+ enabled = bool(value)
+ if enabled and target.os != "WINNT":
+ die("Cannot enable launcher process on %s", target.os)
+ if enabled:
+ return True
+
+
+set_config("MOZ_LAUNCHER_PROCESS", launcher)
+set_define("MOZ_LAUNCHER_PROCESS", launcher)
+
+# llvm-dlltool (Windows only)
+# ==============================================================
+
+
+@depends(build_project, target, "--enable-compile-environment")
+def check_for_llvm_dlltool(build_project, target, compile_environment):
+ if build_project != "browser":
+ return
+
+ if target.os != "WINNT":
+ return
+
+ return compile_environment
+
+
+llvm_dlltool = check_prog(
+ "LLVM_DLLTOOL",
+ ("llvm-dlltool",),
+ what="llvm-dlltool",
+ when=check_for_llvm_dlltool,
+ paths=clang_search_path,
+)
+
+
+@depends(target, when=llvm_dlltool)
+def llvm_dlltool_flags(target):
+ arch = {
+ "x86": "i386",
+ "x86_64": "i386:x86-64",
+ "aarch64": "arm64",
+ }[target.cpu]
+
+ return ["-m", arch]
+
+
+set_config("LLVM_DLLTOOL_FLAGS", llvm_dlltool_flags)
+
+# BITS download (Windows only)
+# ==============================================================
+
+option(
+ "--enable-bits-download",
+ when=target_is_windows,
+ default=target_is_windows,
+ help="{Enable|Disable} building BITS download support",
+)
+
+set_define(
+ "MOZ_BITS_DOWNLOAD",
+ depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
+)
+set_config(
+ "MOZ_BITS_DOWNLOAD",
+ depends_if("--enable-bits-download", when=target_is_windows)(lambda _: True),
+)
+
+# Bundled fonts on desktop platform
+# ==============================================================
+
+
+@depends(target)
+def bundled_fonts_default(target):
+ return target.os == "WINNT" or target.kernel == "Linux"
+
+
+@depends(build_project)
+def allow_bundled_fonts(project):
+ return project == "browser" or project == "comm/mail"
+
+
+option(
+ "--enable-bundled-fonts",
+ default=bundled_fonts_default,
+ when=allow_bundled_fonts,
+ help="{Enable|Disable} support for bundled fonts on desktop platforms",
+)
+
+set_define(
+ "MOZ_BUNDLED_FONTS",
+ depends_if("--enable-bundled-fonts", when=allow_bundled_fonts)(lambda _: True),
+)
+
+# Reflow counting
+# ==============================================================
+
+
+@depends(moz_debug)
+def reflow_perf(debug):
+ if debug:
+ return True
+
+
+option(
+ "--enable-reflow-perf",
+ default=reflow_perf,
+ help="{Enable|Disable} reflow performance tracing",
+)
+
+# The difference in conditions here comes from the initial implementation
+# in old-configure, which was unexplained there as well.
+set_define("MOZ_REFLOW_PERF", depends_if("--enable-reflow-perf")(lambda _: True))
+set_define("MOZ_REFLOW_PERF_DSP", reflow_perf)
+
+# Layout debugger
+# ==============================================================
+
+
+@depends(moz_debug)
+def layout_debugger(debug):
+ if debug:
+ return True
+
+
+option(
+ "--enable-layout-debugger",
+ default=layout_debugger,
+ help="{Enable|Disable} layout debugger",
+)
+
+set_config("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
+set_define("MOZ_LAYOUT_DEBUGGER", True, when="--enable-layout-debugger")
+
+
+# Shader Compiler for Windows (and MinGW Cross Compile)
+# ==============================================================
+
+with only_when(compile_environment):
+ fxc = check_prog(
+ "FXC",
+ ("fxc.exe", "fxc2.exe"),
+ when=depends(target)(lambda t: t.kernel == "WINNT"),
+ paths=sdk_bin_path,
+ # FXC being used from a python wrapper script, we can live with it
+ # having spaces.
+ allow_spaces=True,
+ )
+
+
+# VPX
+# ===
+
+with only_when(compile_environment):
+ system_lib_option(
+ "--with-system-libvpx", help="Use system libvpx (located with pkgconfig)"
+ )
+
+ with only_when("--with-system-libvpx"):
+ vpx = pkg_check_modules("MOZ_LIBVPX", "vpx >= 1.10.0")
+
+ check_header(
+ "vpx/vpx_decoder.h",
+ flags=vpx.cflags,
+ onerror=lambda: die(
+ "Couldn't find vpx/vpx_decoder.h, which is required to build "
+ "with system libvpx. Use --without-system-libvpx to build "
+ "with in-tree libvpx."
+ ),
+ )
+
+ check_symbol(
+ "vpx_codec_dec_init_ver",
+ flags=vpx.libs,
+ onerror=lambda: die(
+ "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
+ "not found"
+ ),
+ )
+
+ set_config("MOZ_SYSTEM_LIBVPX", True)
+
+ @depends("--with-system-libvpx", target)
+ def in_tree_vpx(system_libvpx, target):
+ if system_libvpx:
+ return
+
+ arm_asm = (target.cpu == "arm") or None
+ return namespace(arm_asm=arm_asm)
+
+ @depends(target, when=in_tree_vpx)
+ def vpx_nasm(target):
+ if target.cpu in ("x86", "x86_64"):
+ if target.kernel == "WINNT":
+ # Version 2.03 is needed for automatic safeseh support.
+ return namespace(version="2.03", what="VPX")
+ return namespace(what="VPX")
+
+ @depends(in_tree_vpx, vpx_nasm, target, neon_flags)
+ def vpx_as_flags(vpx, vpx_nasm, target, neon_flags):
+ if vpx and vpx.arm_asm:
+ # These flags are a lie; they're just used to enable the requisite
+ # opcodes; actual arch detection is done at runtime.
+ return neon_flags
+ elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64":
+ return ("-DPIC",)
+
+ set_config("VPX_USE_NASM", True, when=vpx_nasm)
+ set_config("VPX_ASFLAGS", vpx_as_flags)
+
+
+# JPEG
+# ====
+
+with only_when(compile_environment):
+ system_lib_option(
+ "--with-system-jpeg",
+ nargs="?",
+ help="Use system libjpeg (installed at given prefix)",
+ )
+
+ @depends_if("--with-system-jpeg")
+ def jpeg_flags(value):
+ if len(value):
+ return namespace(
+ cflags=("-I%s/include" % value[0],),
+ ldflags=("-L%s/lib" % value[0], "-ljpeg"),
+ )
+ return namespace(
+ ldflags=("-ljpeg",),
+ )
+
+ with only_when("--with-system-jpeg"):
+ check_symbol(
+ "jpeg_destroy_compress",
+ flags=jpeg_flags.ldflags,
+ onerror=lambda: die(
+ "--with-system-jpeg requested but symbol "
+ "jpeg_destroy_compress not found."
+ ),
+ )
+
+ c_compiler.try_compile(
+ includes=[
+ "stdio.h",
+ "sys/types.h",
+ "jpeglib.h",
+ ],
+ body="""
+ #if JPEG_LIB_VERSION < 62
+ #error Insufficient JPEG library version
+ #endif
+ """,
+ flags=jpeg_flags.cflags,
+ check_msg="for sufficient jpeg library version",
+ onerror=lambda: die(
+ "Insufficient JPEG library version for "
+ "--with-system-jpeg (62 required)"
+ ),
+ )
+
+ c_compiler.try_compile(
+ includes=[
+ "stdio.h",
+ "sys/types.h",
+ "jpeglib.h",
+ ],
+ body="""
+ #ifndef JCS_EXTENSIONS
+ #error libjpeg-turbo JCS_EXTENSIONS required
+ #endif
+ """,
+ flags=jpeg_flags.cflags,
+ check_msg="for sufficient libjpeg-turbo JCS_EXTENSIONS",
+ onerror=lambda: die(
+ "libjpeg-turbo JCS_EXTENSIONS required for " "--with-system-jpeg"
+ ),
+ )
+
+ set_config("MOZ_JPEG_CFLAGS", jpeg_flags.cflags)
+ set_config("MOZ_JPEG_LIBS", jpeg_flags.ldflags)
+
+ @depends("--with-system-jpeg", target, neon_flags)
+ def in_tree_jpeg_arm(system_jpeg, target, neon_flags):
+ if system_jpeg:
+ return
+
+ if target.cpu == "arm":
+ return neon_flags
+ elif target.cpu == "aarch64":
+ return ("-march=armv8-a",)
+
+ @depends("--with-system-jpeg", target)
+ def in_tree_jpeg_mips64(system_jpeg, target):
+ if system_jpeg:
+ return
+
+ if target.cpu == "mips64":
+ return ("-Wa,-mloongson-mmi", "-mloongson-ext")
+
+ # Compiler check from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L419
+ jpeg_mips64_mmi = c_compiler.try_compile(
+ body='int c = 0, a = 0, b = 0; asm("paddb %0, %1, %2" : "=f" (c) : "f" (a), "f" (b));',
+ check_msg="for loongson mmi support",
+ flags=in_tree_jpeg_mips64,
+ when=in_tree_jpeg_mips64,
+ )
+
+ @depends(
+ "--with-system-jpeg",
+ target,
+ in_tree_jpeg_arm,
+ in_tree_jpeg_mips64,
+ jpeg_mips64_mmi,
+ )
+ def in_tree_jpeg(
+ system_jpeg, target, in_tree_jpeg_arm, in_tree_jpeg_mips64, jpeg_mips64_mmi
+ ):
+ if system_jpeg:
+ return
+
+ if target.cpu in ("arm", "aarch64"):
+ return in_tree_jpeg_arm
+ elif target.kernel == "Darwin":
+ if target.cpu == "x86":
+ return ("-DPIC", "-DMACHO")
+ elif target.cpu == "x86_64":
+ return ("-D__x86_64__", "-DPIC", "-DMACHO")
+ elif target.kernel == "WINNT":
+ if target.cpu == "x86":
+ return ("-DPIC", "-DWIN32")
+ elif target.cpu == "x86_64":
+ return ("-D__x86_64__", "-DPIC", "-DWIN64", "-DMSVC")
+ elif target.cpu == "mips32":
+ return ("-mdspr2",)
+ elif target.cpu == "mips64" and jpeg_mips64_mmi:
+ return in_tree_jpeg_mips64
+ elif target.cpu == "x86":
+ return ("-DPIC", "-DELF")
+ elif target.cpu == "x86_64":
+ return ("-D__x86_64__", "-DPIC", "-DELF")
+
+ @depends(target, when=depends("--with-system-jpeg")(lambda x: not x))
+ def jpeg_nasm(target):
+ if target.cpu in ("x86", "x86_64"):
+ # libjpeg-turbo 2.0.6 requires nasm 2.10.
+ return namespace(version="2.10", what="JPEG")
+
+ # Compiler checks from https://github.com/libjpeg-turbo/libjpeg-turbo/blob/57ba02a408a9a55ccff25aae8b164632a3a4f177/simd/CMakeLists.txt#L258
+ jpeg_arm_neon_vld1_s16_x3 = c_compiler.try_compile(
+ includes=["arm_neon.h"],
+ body="int16_t input[12] = {}; int16x4x3_t output = vld1_s16_x3(input);",
+ check_msg="for vld1_s16_x3 in arm_neon.h",
+ flags=in_tree_jpeg_arm,
+ when=in_tree_jpeg_arm,
+ )
+
+ jpeg_arm_neon_vld1_u16_x2 = c_compiler.try_compile(
+ includes=["arm_neon.h"],
+ body="uint16_t input[8] = {}; uint16x4x2_t output = vld1_u16_x2(input);",
+ check_msg="for vld1_u16_x2 in arm_neon.h",
+ flags=in_tree_jpeg_arm,
+ when=in_tree_jpeg_arm,
+ )
+
+ jpeg_arm_neon_vld1q_u8_x4 = c_compiler.try_compile(
+ includes=["arm_neon.h"],
+ body="uint8_t input[64] = {}; uint8x16x4_t output = vld1q_u8_x4(input);",
+ check_msg="for vld1q_u8_x4 in arm_neon.h",
+ flags=in_tree_jpeg_arm,
+ when=in_tree_jpeg_arm,
+ )
+
+ set_config("LIBJPEG_TURBO_USE_NASM", True, when=jpeg_nasm)
+ set_config("LIBJPEG_TURBO_SIMD_FLAGS", in_tree_jpeg)
+ set_config("LIBJPEG_TURBO_HAVE_VLD1_S16_X3", jpeg_arm_neon_vld1_s16_x3)
+ set_config("LIBJPEG_TURBO_HAVE_VLD1_U16_X2", jpeg_arm_neon_vld1_u16_x2)
+ set_config("LIBJPEG_TURBO_HAVE_VLD1Q_U8_X4", jpeg_arm_neon_vld1q_u8_x4)
+ set_config(
+ "LIBJPEG_TURBO_NEON_INTRINSICS",
+ jpeg_arm_neon_vld1_s16_x3
+ & jpeg_arm_neon_vld1_u16_x2
+ & jpeg_arm_neon_vld1q_u8_x4,
+ )
+
+
+# PNG
+# ===
+with only_when(compile_environment):
+ system_lib_option(
+ "--with-system-png",
+ nargs="?",
+ help="Use system libpng",
+ )
+
+ @depends("--with-system-png")
+ def deprecated_system_png_path(value):
+ if len(value) == 1:
+ die(
+ "--with-system-png=PATH is not supported anymore. Please use "
+ "--with-system-png and set any necessary pkg-config environment variable."
+ )
+
+ png = pkg_check_modules("MOZ_PNG", "libpng >= 1.6.35", when="--with-system-png")
+
+ check_symbol(
+ "png_get_acTL",
+ flags=png.libs,
+ onerror=lambda: die(
+ "--with-system-png won't work because the system's libpng doesn't have APNG support"
+ ),
+ when="--with-system-png",
+ )
+
+ set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png")
+
+
+# FFmpeg's ffvpx configuration
+# ==============================================================
+with only_when(compile_environment):
+
+ @depends(target)
+ def libav_fft(target):
+ if target.os == "Android" and target.cpu != "arm":
+ return True
+ return target.kernel in ("WINNT", "Darwin") or target.cpu == "x86_64"
+
+ set_config("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
+ set_define("MOZ_LIBAV_FFT", depends(when=libav_fft)(lambda: True))
+
+
+# Artifact builds need MOZ_FFVPX defined as if compilation happened.
+with only_when(compile_environment | artifact_builds):
+
+ @depends(target)
+ def ffvpx(target):
+ enable = use_nasm = True
+ flac_only = False
+ flags = []
+
+ if target.kernel == "WINNT":
+ if target.cpu == "x86":
+ # 32-bit windows need to prefix symbols with an underscore.
+ flags = ["-DPIC", "-DWIN32", "-DPREFIX", "-Pconfig_win32.asm"]
+ elif target.cpu == "x86_64":
+ flags = [
+ "-D__x86_64__",
+ "-DPIC",
+ "-DWIN64",
+ "-DMSVC",
+ "-Pconfig_win64.asm",
+ ]
+ elif target.cpu == "aarch64":
+ flags = ["-DPIC", "-DWIN64"]
+ use_nasm = False
+ elif target.kernel == "Darwin":
+ # 32/64-bit macosx assemblers need to prefix symbols with an
+ # underscore.
+ flags = ["-DPIC", "-DMACHO", "-DPREFIX"]
+ if target.cpu == "x86_64":
+ flags += [
+ "-D__x86_64__",
+ "-Pconfig_darwin64.asm",
+ ]
+ elif target.cpu == "aarch64":
+ use_nasm = False
+ elif target.cpu == "x86_64":
+ flags = ["-D__x86_64__", "-DPIC", "-DELF", "-Pconfig_unix64.asm"]
+ elif target.cpu in ("x86", "arm", "aarch64"):
+ flac_only = True
+ else:
+ enable = False
+
+ if flac_only or not enable:
+ use_nasm = False
+
+ return namespace(
+ enable=enable,
+ use_nasm=use_nasm,
+ flac_only=flac_only,
+ flags=flags,
+ )
+
+ @depends(when=ffvpx.use_nasm)
+ def ffvpx_nasm():
+ # nasm 2.10 for AVX-2 support.
+ return namespace(version="2.10", what="FFVPX")
+
+ # ffvpx_nasm can't indirectly depend on vpx_as_flags, because it depends
+ # on a compiler test, so we have to do a little bit of dance here.
+ @depends(ffvpx, vpx_as_flags, target)
+ def ffvpx(ffvpx, vpx_as_flags, target):
+ if ffvpx and vpx_as_flags and target.cpu in ("arm", "aarch64"):
+ ffvpx.flags.extend(vpx_as_flags)
+ return ffvpx
+
+ set_config("MOZ_FFVPX", True, when=ffvpx.enable)
+ set_define("MOZ_FFVPX", True, when=ffvpx.enable)
+ set_config("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
+ set_define("MOZ_FFVPX_AUDIOONLY", True, when=ffvpx.flac_only)
+ set_config("FFVPX_ASFLAGS", ffvpx.flags)
+ set_config("FFVPX_USE_NASM", True, when=ffvpx.use_nasm)
+
+
+# nasm detection
+# ==============================================================
+@depends(dav1d_nasm, vpx_nasm, jpeg_nasm, ffvpx_nasm, when=compile_environment)
+def need_nasm(*requirements):
+ requires = {
+ x.what: x.version if hasattr(x, "version") else True for x in requirements if x
+ }
+ if requires:
+ items = sorted(requires.keys())
+ if len(items) > 1:
+ what = " and ".join((", ".join(items[:-1]), items[-1]))
+ else:
+ what = items[0]
+ versioned = {k: v for (k, v) in requires.items() if v is not True}
+ return namespace(what=what, versioned=versioned)
+
+
+nasm = check_prog(
+ "NASM",
+ ["nasm"],
+ allow_missing=True,
+ bootstrap="nasm",
+ when=need_nasm,
+)
+
+
+@depends(nasm, need_nasm.what)
+def check_nasm(nasm, what):
+ if not nasm and what:
+ die("Nasm is required to build with %s, but it was not found." % what)
+ return nasm
+
+
+@depends_if(check_nasm)
+@checking("nasm version")
+def nasm_version(nasm):
+ version = (
+ check_cmd_output(nasm, "-v", onerror=lambda: die("Failed to get nasm version."))
+ .splitlines()[0]
+ .split()[2]
+ )
+ return Version(version)
+
+
+@depends(nasm_version, need_nasm.versioned, when=need_nasm.versioned)
+def check_nasm_version(nasm_version, versioned):
+ by_version = sorted(versioned.items(), key=lambda x: x[1])
+ what, version = by_version[-1]
+ if nasm_version < version:
+ die(
+ "Nasm version %s or greater is required to build with %s." % (version, what)
+ )
+ return nasm_version
+
+
+@depends(target, when=check_nasm_version)
+def nasm_asflags(target):
+ asflags = {
+ ("OSX", "x86"): ["-f", "macho32"],
+ ("OSX", "x86_64"): ["-f", "macho64"],
+ ("WINNT", "x86"): ["-f", "win32"],
+ ("WINNT", "x86_64"): ["-f", "win64"],
+ }.get((target.os, target.cpu), None)
+ if asflags is None:
+ # We're assuming every x86 platform we support that's
+ # not Windows or Mac is ELF.
+ if target.cpu == "x86":
+ asflags = ["-f", "elf32"]
+ elif target.cpu == "x86_64":
+ asflags = ["-f", "elf64"]
+ return asflags
+
+
+set_config("NASM_ASFLAGS", nasm_asflags)
+
+
+# ANGLE OpenGL->D3D translator for WebGL
+# ==============================================================
+
+with only_when(compile_environment & target_is_windows):
+ set_config("MOZ_ANGLE_RENDERER", True)
+
+# Remoting protocol support
+# ==============================================================
+
+
+@depends(toolkit)
+def has_remote(toolkit):
+ if toolkit in ("gtk", "windows", "cocoa"):
+ return True
+
+
+set_config("MOZ_HAS_REMOTE", has_remote)
+set_define("MOZ_HAS_REMOTE", has_remote)
+
+# RLBox Library Sandboxing wasm support
+# ==============================================================
+
+
+def wasm_sandboxing_libraries():
+ return (
+ "graphite",
+ "ogg",
+ "hunspell",
+ "expat",
+ "woff2",
+ "soundtouch",
+ )
+
+
+@depends(dependable(wasm_sandboxing_libraries), build_project)
+def default_wasm_sandboxing_libraries(libraries, build_project):
+ if build_project != "tools/rusttests":
+ non_default_libs = {}
+
+ return tuple(l for l in libraries if l not in non_default_libs)
+
+
+option(
+ "--with-wasm-sandboxed-libraries",
+ env="WASM_SANDBOXED_LIBRARIES",
+ help="{Enable wasm sandboxing for the selected libraries|Disable wasm sandboxing}",
+ nargs="+",
+ choices=dependable(wasm_sandboxing_libraries),
+ default=default_wasm_sandboxing_libraries,
+)
+
+
+@depends("--with-wasm-sandboxed-libraries")
+def requires_wasm_sandboxing(libraries):
+ if libraries:
+ return True
+
+
+set_config("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
+set_define("MOZ_USING_WASM_SANDBOXING", requires_wasm_sandboxing)
+
+with only_when(requires_wasm_sandboxing & compile_environment):
+ option(
+ "--with-wasi-sysroot",
+ env="WASI_SYSROOT",
+ nargs=1,
+ help="Path to wasi sysroot for wasm sandboxing",
+ )
+
+ @depends("--with-wasi-sysroot", requires_wasm_sandboxing)
+ def bootstrap_wasi_sysroot(wasi_sysroot, requires_wasm_sandboxing):
+ return requires_wasm_sandboxing and not wasi_sysroot
+
+ @depends(
+ "--with-wasi-sysroot",
+ bootstrap_path("sysroot-wasm32-wasi", when=bootstrap_wasi_sysroot),
+ )
+ @imports("os")
+ def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot):
+ if not wasi_sysroot:
+ return bootstrapped_sysroot
+
+ wasi_sysroot = wasi_sysroot[0]
+ if not os.path.isdir(wasi_sysroot):
+ die("Argument to --with-wasi-sysroot must be a directory")
+ if not os.path.isabs(wasi_sysroot):
+ die("Argument to --with-wasi-sysroot must be an absolute path")
+
+ return wasi_sysroot
+
+ @depends(wasi_sysroot)
+ def wasi_sysroot_flags(wasi_sysroot):
+ if wasi_sysroot:
+ log.info("Using wasi sysroot in %s", wasi_sysroot)
+ return ["--sysroot=%s" % wasi_sysroot]
+ return []
+
+ set_config("WASI_SYSROOT", wasi_sysroot)
+
+ def wasm_compiler_with_flags(compiler, sysroot_flags):
+ if compiler:
+ return (
+ compiler.wrapper + [compiler.compiler] + compiler.flags + sysroot_flags
+ )
+
+ @template
+ def wasm_compiler_error(msg):
+ @depends("--with-wasm-sandboxed-libraries")
+ def wasm_compiler_error(sandboxed_libs):
+ suggest_disable = ""
+ if sandboxed_libs.origin == "default":
+ suggest_disable = " Or build with --without-wasm-sandboxed-libraries."
+ return lambda: die(msg + suggest_disable)
+
+ return wasm_compiler_error
+
+ @template
+ def check_wasm_compiler(compiler, language):
+ compiler.try_compile(
+ includes=["cstring" if language == "C++" else "string.h"],
+ flags=wasi_sysroot_flags,
+ check_msg="the wasm %s compiler can find wasi headers" % language,
+ onerror=wasm_compiler_error(
+ "Cannot find wasi headers or problem with the wasm compiler. "
+ "Please fix the problem."
+ ),
+ )
+
+ compiler.try_run(
+ flags=wasi_sysroot_flags,
+ check_msg="the wasm %s linker can find wasi libraries" % language,
+ onerror=wasm_compiler_error(
+ "Cannot find wasi libraries or problem with the wasm linker. "
+ "Please fix the problem."
+ ),
+ )
+
+ wasm_cc = compiler("C", wasm, other_compiler=c_compiler)
+ check_wasm_compiler(wasm_cc, "C")
+
+ @depends(wasm_cc, wasi_sysroot_flags)
+ def wasm_cc_with_flags(wasm_cc, wasi_sysroot_flags):
+ return wasm_compiler_with_flags(wasm_cc, wasi_sysroot_flags)
+
+ set_config("WASM_CC", wasm_cc_with_flags)
+
+ wasm_cxx = compiler(
+ "C++",
+ wasm,
+ c_compiler=wasm_cc,
+ other_compiler=cxx_compiler,
+ other_c_compiler=c_compiler,
+ )
+ check_wasm_compiler(wasm_cxx, "C++")
+
+ @depends(wasm_cxx, wasi_sysroot_flags)
+ def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot_flags):
+ return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot_flags)
+
+ set_config("WASM_CXX", wasm_cxx_with_flags)
+
+ wasm_compile_flags = dependable(["-fno-exceptions", "-fno-strict-aliasing"])
+ option(env="WASM_CFLAGS", nargs=1, help="Options to pass to WASM_CC")
+
+ @depends("WASM_CFLAGS", wasm_compile_flags)
+ def wasm_cflags(value, wasm_compile_flags):
+ if value:
+ return wasm_compile_flags + value
+ else:
+ return wasm_compile_flags
+
+ set_config("WASM_CFLAGS", wasm_cflags)
+
+ option(env="WASM_CXXFLAGS", nargs=1, help="Options to pass to WASM_CXX")
+
+ @depends("WASM_CXXFLAGS", wasm_compile_flags)
+ def wasm_cxxflags(value, wasm_compile_flags):
+ if value:
+ return wasm_compile_flags + value
+ else:
+ return wasm_compile_flags
+
+ set_config("WASM_CXXFLAGS", wasm_cxxflags)
+
+
+@depends("--with-wasm-sandboxed-libraries")
+def wasm_sandboxing(libraries):
+ if not libraries:
+ return
+
+ return namespace(**{name: True for name in libraries})
+
+
+@template
+def wasm_sandboxing_config_defines():
+ for lib in wasm_sandboxing_libraries():
+ set_config(
+ "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
+ )
+ set_define(
+ "MOZ_WASM_SANDBOXING_%s" % lib.upper(), getattr(wasm_sandboxing, lib)
+ )
+
+
+wasm_sandboxing_config_defines()
+
+
+with only_when(compile_environment & wasm_sandboxing.hunspell):
+ clock_in_wasi_sysroot = wasm_cc.try_run(
+ header="#include <time.h>",
+ body="clock();",
+ check_msg="for clock() in wasi sysroot",
+ flags=depends(wasi_sysroot_flags)(
+ lambda sysroot_flags: ["-Werror"] + sysroot_flags
+ ),
+ )
+
+ wasi_emulated_clock = wasm_cc.try_run(
+ header="#include <time.h>",
+ body="clock();",
+ check_msg="for emulated clock() in wasi sysroot",
+ flags=depends(wasi_sysroot_flags)(
+ lambda sysroot_flags: [
+ "-Werror",
+ "-D_WASI_EMULATED_PROCESS_CLOCKS",
+ "-lwasi-emulated-process-clocks",
+ ]
+ + sysroot_flags
+ ),
+ when=depends(clock_in_wasi_sysroot)(lambda x: not x),
+ onerror=lambda: die("Can't find clock() in wasi sysroot."),
+ )
+
+ set_config("MOZ_WASI_EMULATED_CLOCK", True, when=wasi_emulated_clock)
+
+
+# new Notification Store implementation
+# ==============================================================
+
+
+@depends(milestone)
+def new_notification_store(milestone):
+ if milestone.is_nightly:
+ return True
+
+
+set_config("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
+set_define("MOZ_NEW_NOTIFICATION_STORE", True, when=new_notification_store)
+
+
+# Auxiliary files persistence on application close
+# ==============================================================
+
+option(
+ "--enable-disk-remnant-avoidance",
+ help="Prevent persistence of auxiliary files on application close",
+)
+
+
+set_config(
+ "MOZ_AVOID_DISK_REMNANT_ON_CLOSE",
+ True,
+ when="--enable-disk-remnant-avoidance",
+)
+
+
+# Glean SDK Integration Crate
+# ==============================================================
+
+
+@depends(target)
+def glean_android(target):
+ return target.os == "Android"
+
+
+set_config("MOZ_GLEAN_ANDROID", True, when=glean_android)
+set_define("MOZ_GLEAN_ANDROID", True, when=glean_android)
+
+
+# dump_syms
+# ==============================================================
+
+check_prog(
+ "DUMP_SYMS",
+ ["dump_syms"],
+ allow_missing=True,
+ bootstrap="dump_syms",
+ when=compile_environment,
+)
+
+
+@depends(valid_windows_sdk_dir, host)
+@imports(_from="os", _import="environ")
+def pdbstr_paths(valid_windows_sdk_dir, host):
+ if not valid_windows_sdk_dir:
+ return
+
+ vc_host = {
+ "x86": "x86",
+ "x86_64": "x64",
+ }.get(host.cpu)
+
+ return [
+ environ["PATH"],
+ os.path.join(valid_windows_sdk_dir.path, "Debuggers", vc_host, "srcsrv"),
+ ]
+
+
+check_prog(
+ "PDBSTR",
+ ["pdbstr.exe"],
+ allow_missing=True,
+ when=compile_environment & target_is_windows,
+ paths=pdbstr_paths,
+ allow_spaces=True,
+)
+
+
+@depends("MOZ_AUTOMATION", c_compiler)
+def allow_missing_winchecksec(automation, c_compiler):
+ if not automation:
+ return True
+ if c_compiler and c_compiler.type != "clang-cl":
+ return True
+
+
+check_prog(
+ "WINCHECKSEC",
+ ["winchecksec.exe", "winchecksec"],
+ bootstrap="winchecksec",
+ allow_missing=allow_missing_winchecksec,
+ when=compile_environment & target_is_windows,
+)
+
+
+# Fork server
+@depends(target, build_project)
+def forkserver_default(target, build_project):
+ return build_project == "browser" and (
+ (target.os == "GNU" and target.kernel == "Linux")
+ or target.os == "FreeBSD"
+ or target.os == "OpenBSD"
+ )
+
+
+option(
+ "--enable-forkserver",
+ default=forkserver_default,
+ env="MOZ_ENABLE_FORKSERVER",
+ help="{Enable|Disable} fork server",
+)
+
+
+@depends("--enable-forkserver", target)
+def forkserver_flag(value, target):
+ if (
+ target.os == "Android"
+ or (target.os == "GNU" and target.kernel == "Linux")
+ or target.os == "FreeBSD"
+ or target.os == "OpenBSD"
+ ):
+ return bool(value)
+ pass
+
+
+set_config("MOZ_ENABLE_FORKSERVER", forkserver_flag)
+set_define("MOZ_ENABLE_FORKSERVER", forkserver_flag, forkserver_flag)
+
+# Crash Reporter
+# ==============================================================
+
+with only_when(compile_environment & target_has_linux_kernel):
+ # Check if we need to use the breakpad_getcontext fallback.
+ getcontext = check_symbol("getcontext")
+ set_config("HAVE_GETCONTEXT", getcontext)
+ set_define("HAVE_GETCONTEXT", getcontext)
+
+# NSS
+# ==============================================================
+include("../build/moz.configure/nss.configure")
+
+
+# Enable or disable running in background task mode: headless for
+# periodic, short-lived, maintenance tasks.
+# ==============================================================================
+option(
+ "--disable-backgroundtasks",
+ help="Disable running in background task mode",
+)
+set_config("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
+set_define("MOZ_BACKGROUNDTASKS", True, when="--enable-backgroundtasks")
+
+
+# Update-related programs: updater, maintenance service, update agent,
+# default browser agent.
+# ==============================================================
+include("../build/moz.configure/update-programs.configure")
+
+
+# Mobile optimizations
+# ==============================================================
+option(
+ "--enable-mobile-optimize",
+ default=target_is_android,
+ help="{Enable|Disable} mobile optimizations",
+)
+
+set_define("MOZ_GFX_OPTIMIZE_MOBILE", True, when="--enable-mobile-optimize")
+# We ignore "paint will resample" on mobile for performance.
+# We may want to revisit this later.
+set_define("MOZ_IGNORE_PAINT_WILL_RESAMPLE", True, when="--enable-mobile-optimize")
+
+# Pref extensions
+# ==============================================================
+option("--disable-pref-extensions", help="Disable pref extensions such as autoconfig")
+set_config("MOZ_PREF_EXTENSIONS", True, when="--enable-pref-extensions")
+
+# Offer a way to disable the startup cache
+# ==============================================================
+option("--disable-startupcache", help="Disable startup cache")
+
+
+@depends("--enable-startupcache")
+def enable_startupcache(value):
+ if value:
+ return True
+
+
+set_define(
+ "MOZ_DISABLE_STARTUPCACHE", True, when=depends(enable_startupcache)(lambda x: not x)
+)
+
+
+# Branding
+# ==============================================================
+option(
+ env="MOZ_APP_REMOTINGNAME",
+ nargs=1,
+ help="Used for the internal program name, which affects profile name "
+ "and remoting. If not set, defaults to MOZ_APP_NAME if the update channel "
+ "is release, and MOZ_APP_NAME-MOZ_UPDATE_CHANNEL otherwise.",
+)
+
+
+@depends("MOZ_APP_REMOTINGNAME", moz_app_name, update_channel)
+def moz_app_remotingname(value, moz_app_name, update_channel):
+ if value:
+ return value[0]
+ if update_channel == "release":
+ return moz_app_name
+ return moz_app_name + "-" + update_channel
+
+
+set_config("MOZ_APP_REMOTINGNAME", moz_app_remotingname)
+
+option(
+ env="ANDROID_PACKAGE_NAME",
+ nargs=1,
+ help="Name of the Android package (default org.mozilla.$MOZ_APP_NAME)",
+)
+
+
+@depends("ANDROID_PACKAGE_NAME", moz_app_name)
+def android_package_name(value, moz_app_name):
+ if value:
+ return value[0]
+ if moz_app_name == "fennec":
+ return "org.mozilla.fennec_aurora"
+ return "org.mozilla.%s" % moz_app_name
+
+
+set_config("ANDROID_PACKAGE_NAME", android_package_name)
+
+
+# Miscellaneous options
+# ==============================================================
+option(env="MOZ_WINCONSOLE", nargs="?", help="Whether we can create a console window.")
+set_define("MOZ_WINCONSOLE", True, when=depends("MOZ_WINCONSOLE")(lambda x: x))
+
+
+# Alternative Crashreporter setting
+option(
+ "--with-crashreporter-url",
+ env="MOZ_CRASHREPORTER_URL",
+ default="https://crash-reports.mozilla.com/",
+ nargs=1,
+ help="Set an alternative crashreporter url",
+)
+
+set_config(
+ "MOZ_CRASHREPORTER_URL",
+ depends("--with-crashreporter-url")(lambda x: x[0].rstrip("/")),
+)
+
+
+# Crash reporter options
+# ==============================================================
+@depends(target)
+def oxidized_breakpad(target):
+ if target.kernel == "Linux":
+ return target.cpu in ("aarch64", "arm", "x86", "x86_64")
+ return False
+
+
+set_config("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
+set_define("MOZ_OXIDIZED_BREAKPAD", True, when=oxidized_breakpad)
+
+
+# Wine
+# ==============================================================
+@depends(target, host)
+def want_wine(target, host):
+ return target.kernel == "WINNT" and host.kernel != "WINNT"
+
+
+wine = check_prog(
+ "WINE",
+ ["wine64", "wine"],
+ when=want_wine,
+ bootstrap="wine/bin",
+)
+
+# DOM Streams
+# ==============================================================
+# Set this to true so the JS engine knows we're doing a browser build.
+set_config("MOZ_DOM_STREAMS", True)
+set_define("MOZ_DOM_STREAMS", True)
+
+# libevent
+# ==============================================================
+with only_when(compile_environment):
+ system_lib_option(
+ "--with-system-libevent",
+ nargs="?",
+ help="Use system libevent",
+ )
+
+ @depends("--with-system-libevent")
+ def deprecated_system_libevent_path(value):
+ if len(value) == 1:
+ die(
+ "--with-system-libevent=PATH is not supported anymore. Please use "
+ "--with-system-libevent and set any necessary pkg-config environment variable."
+ )
+
+ pkg_check_modules("MOZ_LIBEVENT", "libevent", when="--with-system-libevent")
+
+ set_config("MOZ_SYSTEM_LIBEVENT", True, when="--with-system-libevent")
+
+
+# Crash reporting
+# ==============================================================
+@depends(target, developer_options, artifact_builds)
+def crashreporter_default(target, developer_options, artifacts):
+ if target.kernel in ("WINNT", "Darwin"):
+ return True
+ if target.kernel == "Linux" and target.cpu in ("x86", "x86_64", "arm", "aarch64"):
+ # The crash reporter prevents crash stacktraces to be logged in the
+ # logs on Android, so we leave it out by default in developer builds.
+ return target.os != "Android" or not developer_options or artifacts
+
+
+option(
+ "--enable-crashreporter",
+ default=crashreporter_default,
+ help="{Enable|Disable} crash reporting",
+)
+
+
+set_config("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
+set_define("MOZ_CRASHREPORTER", True, when="--enable-crashreporter")
+
+with only_when(compile_environment):
+ with only_when("--enable-crashreporter"):
+ pkg_check_modules(
+ "MOZ_GTHREAD",
+ "gthread-2.0",
+ when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
+ )
+
+ set_config(
+ "MOZ_CRASHREPORTER_INJECTOR",
+ True,
+ when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
+ )
+ set_define(
+ "MOZ_CRASHREPORTER_INJECTOR",
+ True,
+ when=depends(target)(lambda t: t.os == "WINNT" and t.bitness == 32),
+ )
+
+
+# If we have any service that uploads data (and requires data submission
+# policy alert), set MOZ_DATA_REPORTING.
+# ==============================================================
+@depends(
+ "MOZ_TELEMETRY_REPORTING",
+ "MOZ_SERVICES_HEALTHREPORT",
+ "--enable-crashreporter",
+ "MOZ_NORMANDY",
+)
+def data_reporting(telemetry, healthreport, crashreporter, normandy):
+ return telemetry or healthreport or crashreporter or normandy
+
+
+set_config("MOZ_DATA_REPORTING", True, when=data_reporting)
+set_define("MOZ_DATA_REPORTING", True, when=data_reporting)
+
+
+# Gtk+
+# ==============================================================
+with only_when(toolkit_gtk):
+ pkg_check_modules(
+ "MOZ_GTK3",
+ "gtk+-3.0 >= 3.14.0 gtk+-unix-print-3.0 glib-2.0 gobject-2.0 gio-unix-2.0",
+ )
+
+ set_define("GDK_VERSION_MIN_REQUIRED", "GDK_VERSION_3_14")
+ set_define("GDK_VERSION_MAX_ALLOWED", "GDK_VERSION_3_14")
+
+ pkg_check_modules("GLIB", "glib-2.0 >= 2.42 gobject-2.0")
+
+ set_define("GLIB_VERSION_MIN_REQUIRED", "GLIB_VERSION_2_42")
+ set_define("GLIB_VERSION_MAX_ALLOWED", "GLIB_VERSION_2_42")
+
+ set_define("MOZ_ACCESSIBILITY_ATK", True, when=accessibility)
+
+# DBus
+# ==============================================================
+with only_when(toolkit_gtk):
+ option("--disable-dbus", help="Disable dbus support")
+
+ with only_when("--enable-dbus"):
+ pkg_check_modules("MOZ_DBUS", "dbus-1 >= 0.60")
+
+ set_config("MOZ_ENABLE_DBUS", True)
+ set_define("MOZ_ENABLE_DBUS", True)
+
+
+# Necko's wifi scanner
+# ==============================================================
+@depends(target)
+def necko_wifi_when(target):
+ return target.os in ("WINNT", "OSX", "DragonFly", "FreeBSD") or (
+ target.kernel == "Linux" and target.os == "GNU"
+ )
+
+
+option("--disable-necko-wifi", help="Disable necko wifi scanner", when=necko_wifi_when)
+
+set_config("NECKO_WIFI", True, when="--enable-necko-wifi")
+set_define("NECKO_WIFI", True, when="--enable-necko-wifi")
+
+
+@depends(
+ depends("--enable-necko-wifi", when=necko_wifi_when)(lambda x: x),
+ depends("--enable-dbus", when=toolkit_gtk)(lambda x: x),
+ when=depends(target)(lambda t: t.os == "GNU" and t.kernel == "Linux"),
+)
+def necko_wifi_dbus(necko_wifi, dbus):
+ if necko_wifi and not dbus:
+ die(
+ "Necko WiFi scanning needs DBus on your platform, remove --disable-dbus"
+ " or use --disable-necko-wifi"
+ )
+ return necko_wifi and dbus
+
+
+set_config("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
+set_define("NECKO_WIFI_DBUS", True, when=necko_wifi_dbus)
+
+
+# Frontend JS debug mode
+# ==============================================================
+option("--enable-debug-js-modules", help="Enable debug mode for frontend JS libraries")
+
+set_config("DEBUG_JS_MODULES", True, when="--enable-debug-js-modules")
+
+
+# moz_dump_painting
+# ==============================================================
+option("--enable-dump-painting", help="Enable paint debugging")
+
+set_define(
+ "MOZ_DUMP_PAINTING",
+ True,
+ when=depends("--enable-dump-painting", "--enable-debug")(
+ lambda painting, debug: painting or debug
+ ),
+)
+set_define("MOZ_LAYERS_HAVE_LOG", True, when="--enable-dump-painting")
+
+
+# libproxy support
+# ==============================================================
+with only_when(toolkit_gtk):
+ system_lib_option("--enable-libproxy", help="Enable libproxy support")
+
+ with only_when("--enable-libproxy"):
+ pkg_check_modules("MOZ_LIBPROXY", "libproxy-1.0")
+
+ set_config("MOZ_ENABLE_LIBPROXY", True)
+ set_define("MOZ_ENABLE_LIBPROXY", True)
+
+
+# Enable runtime logging
+# ==============================================================
+set_define("MOZ_LOGGING", True)
+set_define("FORCE_PR_LOG", True)
+
+# This will enable logging of addref, release, ctor, dtor.
+# ==============================================================
+option(
+ "--enable-logrefcnt",
+ default=moz_debug,
+ help="{Enable|Disable} logging of refcounts",
+)
+
+set_define("NS_BUILD_REFCNT_LOGGING", True, when="--enable-logrefcnt")
+
+
+# NegotiateAuth
+# ==============================================================
+option("--disable-negotiateauth", help="Disable GSS-API negotiation")
+
+set_config("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
+set_define("MOZ_AUTH_EXTENSION", True, when="--enable-negotiateauth")
+
+
+# Parental control
+# ==============================================================
+option("--disable-parental-controls", help="Do not build parental controls")
+
+set_config(
+ "MOZ_DISABLE_PARENTAL_CONTROLS",
+ True,
+ when=depends("--enable-parental-controls")(lambda x: not x),
+)
+set_define(
+ "MOZ_DISABLE_PARENTAL_CONTROLS",
+ True,
+ when=depends("--enable-parental-controls")(lambda x: not x),
+)
+
+
+# Sandboxing support
+# ==============================================================
+@depends(target, tsan, asan)
+def sandbox_default(target, tsan, asan):
+ # Only enable the sandbox by default on Linux, OpenBSD, macOS, and Windows
+ if target.kernel == "Linux" and target.os == "GNU":
+ # Bug 1182565: TSan conflicts with sandboxing on Linux.
+ # Bug 1287971: LSan also conflicts with sandboxing on Linux.
+ if tsan or asan:
+ return False
+ # Linux sandbox is only available on x86{,_64} and arm{,64}.
+ return target.cpu in ("x86", "x86_64", "arm", "aarch64")
+ return target.kernel in ("WINNT", "Darwin", "OpenBSD")
+
+
+option(
+ "--enable-sandbox",
+ default=sandbox_default,
+ help="{Enable|Disable} sandboxing support",
+)
+
+set_config("MOZ_SANDBOX", True, when="--enable-sandbox")
+set_define("MOZ_SANDBOX", True, when="--enable-sandbox")
+
+with only_when(depends(target.kernel)(lambda k: k not in ("Darwin", "WINNT"))):
+ set_define("MOZ_CONTENT_TEMP_DIR", True, when="--enable-sandbox")
+
+# Searching of system directories for extensions.
+# ==============================================================
+# Note: this switch is meant to be used for test builds whose behavior should
+# not depend on what happens to be installed on the local machine.
+option(
+ "--disable-system-extension-dirs",
+ help="Disable searching system- and account-global directories for extensions"
+ " of any kind; use only profile-specific extension directories",
+)
+
+set_define("ENABLE_SYSTEM_EXTENSION_DIRS", True, when="--enable-system-extension-dirs")
+
+
+# Pixman
+# ==============================================================
+with only_when(compile_environment):
+ system_lib_option(
+ "--enable-system-pixman", help="Use system pixman (located with pkgconfig)"
+ )
+
+ @depends("--enable-system-pixman")
+ def in_tree_pixman(pixman):
+ return not pixman
+
+ set_config("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
+ set_define("MOZ_TREE_PIXMAN", True, when=in_tree_pixman)
+
+ pkg_check_modules("MOZ_PIXMAN", "pixman-1 >= 0.36.0", when="--enable-system-pixman")
+ # Set MOZ_PIXMAN_CFLAGS to an explicit empty value when --enable-system-pixman is *not* used,
+ # for layout/style/extra-bindgen-flags
+ set_config("MOZ_PIXMAN_CFLAGS", [], when=in_tree_pixman)
+
+
+# Universalchardet
+# ==============================================================
+with only_when(compile_environment):
+ option("--disable-universalchardet", help="Disable universal encoding detection")
+
+ set_config("MOZ_UNIVERSALCHARDET", True, when="--enable-universalchardet")
+
+
+# Disable zipwriter
+# ==============================================================
+with only_when(compile_environment):
+ option("--disable-zipwriter", help="Disable zipwriter component")
+
+ set_config("MOZ_ZIPWRITER", True, when="--enable-zipwriter")
+
+
+# Location of the mozilla user directory
+# ==============================================================
+with only_when(compile_environment):
+
+ @depends(target)
+ def default_user_appdir(target):
+ if target.kernel in ("WINNT", "Darwin"):
+ return "Mozilla"
+ return ".mozilla"
+
+ option(
+ "--with-user-appdir",
+ nargs=1,
+ default=default_user_appdir,
+ help="Set user-specific appdir",
+ )
+
+ @depends("--with-user-appdir")
+ def user_appdir(appdir):
+ if not appdir:
+ die("--without-user-appdir is not a valid option.")
+ if "/" in appdir[0]:
+ die("--with-user-appdir must be a single relative path.")
+ return '"{}"'.format(appdir[0])
+
+ set_define("MOZ_USER_DIR", user_appdir)
+
+
+# Check for sin_len and sin6_len - used by SCTP; only appears in Mac/*BSD generally
+# ==============================================================
+with only_when(compile_environment):
+ have_sin_len = c_compiler.try_compile(
+ includes=["netinet/in.h"],
+ body="struct sockaddr_in x; void *foo = (void*) &x.sin_len;",
+ check_msg="for sin_len in struct sockaddr_in",
+ )
+ have_sin6_len = c_compiler.try_compile(
+ includes=["netinet/in.h"],
+ body="struct sockaddr_in6 x; void *foo = (void*) &x.sin6_len;",
+ check_msg="for sin_len6 in struct sockaddr_in6",
+ )
+ set_define("HAVE_SIN_LEN", have_sin_len)
+ set_define("HAVE_SIN6_LEN", have_sin6_len)
+ # HAVE_CONN_LEN must be the same as HAVE_SIN_LEN and HAVE_SIN6_LEN
+ set_define("HAVE_SCONN_LEN", have_sin_len & have_sin6_len)
+ set_define(
+ "HAVE_SA_LEN",
+ c_compiler.try_compile(
+ includes=["netinet/in.h"],
+ body="struct sockaddr x; void *foo = (void*) &x.sa_len;",
+ check_msg="for sa_len in struct sockaddr",
+ ),
+ )
+
+
+# Check for pthread_cond_timedwait_monotonic_np
+# ==============================================================
+with only_when(compile_environment):
+ set_define(
+ "HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC",
+ c_compiler.try_compile(
+ includes=["pthread.h"],
+ body="pthread_cond_timedwait_monotonic_np(0, 0, 0);",
+ # -Werror to catch any "implicit declaration" warning that means the function
+ # is not supported.
+ flags=["-Werror=implicit-function-declaration"],
+ check_msg="for pthread_cond_timedwait_monotonic_np",
+ ),
+ )
+
+
+# Custom dynamic linker for Android
+# ==============================================================
+with only_when(target_has_linux_kernel & compile_environment):
+ option(
+ env="MOZ_LINKER",
+ default=depends(target.os, when="--enable-jemalloc")(
+ lambda os: os == "Android"
+ ),
+ help="{Enable|Disable} custom dynamic linker",
+ )
+
+ set_config("MOZ_LINKER", True, when="MOZ_LINKER")
+ set_define("MOZ_LINKER", True, when="MOZ_LINKER")
+ add_old_configure_assignment("MOZ_LINKER", True, when="MOZ_LINKER")
+
+ moz_linker = depends(when="MOZ_LINKER")(lambda: True)
+
+
+# 32-bits ethtool_cmd.speed
+# ==============================================================
+with only_when(target_has_linux_kernel & compile_environment):
+ set_config(
+ "MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI",
+ c_compiler.try_compile(
+ includes=["linux/ethtool.h"],
+ body="struct ethtool_cmd cmd; cmd.speed_hi = 0;",
+ check_msg="for 32-bits ethtool_cmd.speed",
+ ),
+ )
+
+# Gamepad support
+# ==============================================================
+check_header(
+ "linux/joystick.h",
+ onerror=lambda: die(
+ "Can't find header linux/joystick.h, needed for gamepad support."
+ " Please install Linux kernel headers."
+ ),
+ when=target_has_linux_kernel & compile_environment,
+)
+
+
+# Smart card support
+# ==============================================================
+@depends(build_project)
+def disable_smart_cards(build_project):
+ return build_project == "mobile/android"
+
+
+set_config("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
+set_define("MOZ_NO_SMART_CARDS", True, when=disable_smart_cards)
+
+# Enable UniFFI fixtures
+# ==============================================================
+# These are used to test the uniffi-bindgen-gecko-js code generation. They
+# should not be enabled in release builds.
+
+option(
+ "--enable-uniffi-fixtures",
+ help="Enable UniFFI Fixtures/Examples",
+)
+
+set_config("MOZ_UNIFFI_FIXTURES", True, when="--enable-uniffi-fixtures")
+
+# System policies
+# ==============================================================
+
+option(
+ "--disable-system-policies",
+ help="Disable reading policies from Windows registry, macOS's file system attributes, and /etc/firefox",
+)
+
+set_config("MOZ_SYSTEM_POLICIES", True, when="--enable-system-policies")
+
+# Allow disabling the creation a legacy profile
+# ==============================================================
+
+option(
+ "--disable-legacy-profile-creation",
+ help="Disable the creation a legacy profile, to be used by old versions "
+ "of Firefox, when no profiles exist.",
+)
+
+set_config("MOZ_CREATE_LEGACY_PROFILE", True, when="--enable-legacy-profile-creation")
+
+
+# STL wrapping
+# ==============================================================
+set_config("WRAP_STL_INCLUDES", True)
+set_config(
+ "STL_FLAGS",
+ depends(build_environment.dist)(lambda dist: [f"-I{dist}/stl_wrappers"]),
+)
+
+
+# Perl detection
+# ==============================================================
+@depends(target)
+def need_perl(target):
+ # Ideally, we'd also depend on gnu_as here, but that adds complications.
+ return target.cpu == "arm"
+
+
+perl = check_prog("PERL", ("perl5", "perl"), when=need_perl)
+
+
+@template
+def perl_version_check(min_version):
+ @depends(perl)
+ @checking("for minimum required perl version >= %s" % min_version)
+ def get_perl_version(perl):
+ return Version(
+ check_cmd_output(
+ perl,
+ "-e",
+ "print $]",
+ onerror=lambda: die("Failed to get perl version."),
+ )
+ )
+
+ @depends(get_perl_version)
+ def check_perl_version(version):
+ if version < min_version:
+ die("Perl %s or higher is required.", min_version)
+
+ @depends(perl)
+ @checking("for full perl installation")
+ @imports("subprocess")
+ def has_full_perl_installation(perl):
+ ret = subprocess.call([perl, "-e", "use Config; exit(!-d $Config{archlib})"])
+ return ret == 0
+
+ @depends(has_full_perl_installation)
+ def require_full_perl_installation(has_full_perl_installation):
+ if not has_full_perl_installation:
+ die(
+ "Cannot find Config.pm or $Config{archlib}. "
+ "A full perl installation is required."
+ )
+
+
+with only_when(need_perl):
+ perl_version_check("5.006")
+
+
+# windows-rs as bootstrappable toolchain
+# ==============================================================
+# The in-tree windows crate's purpose is to avoid vendoring the
+# original windows crate, which is too large.
+# The ideal solution would be for cargo to allow exceptions to
+# vendoring, but it doesn't.
+# The adopted solution is to somehow use the crate contents from
+# a directory given via the mozbuild config, or bootstrapped.
+#
+# Unfortunately, doing `include!(mozbuild::windows_rs_path!("src/lib.rs"))`
+# in the crate's lib.rs doesn't work because of
+# https://github.com/rust-lang/rust/issues/66920.
+#
+# Previous versions of the windows crate had submodules declared
+# directly in lib.rs. Annotating each of them with
+# `#[path = concat!(mozbuild::windows_rs_path!("path/to/mod.rs"))]`
+# unfortunately also didn't work, because of
+# https://github.com/rust-lang/rust/issues/48250.
+#
+# Thankfully, newer versions of the windows crate now only have an
+# `include!` at the end of lib.rs, so we can get away with simply
+# replacing it with an `include!` that uses `mozbuild::windows_rs_path!`.
+#
+# We ensure that the in-tree contents match what we expect based on
+# the original crate.
+# The expectations are as such:
+# - Cargo.toml is identical to the original one with the addition of the
+# following two lines at the end (after an empty line):
+# [dependencies.mozbuild]
+# version = "0.1"
+# - src/lib.rs is mostly identical to the original one, with two notable
+# differences:
+# - the addition of `#![allow(warnings)]` on the first line, because if
+# the crate had been vendored normally, it would not be affected by
+# `-D warnings`, and `#![allow(warnings)]` mimicks that.
+# - the replacement of any
+# `include!("path/file.rs")`
+# with
+# `include!(mozbuild::windows_rs_path!("src/path/file.rs"))`
+with only_when(target_is_windows & compile_environment):
+ option(
+ env="MOZ_WINDOWS_RS_DIR",
+ nargs=1,
+ help="Path to the source of the 'windows' Rust crate",
+ )
+
+ @depends(
+ "MOZ_WINDOWS_RS_DIR",
+ bootstrap_path(
+ "windows-rs",
+ when=depends("MOZ_WINDOWS_RS_DIR")(lambda x: not x),
+ ),
+ build_environment.topsrcdir,
+ )
+ @checking("for the windows rust crate source")
+ @imports(_from="__builtin__", _import="open")
+ @imports("re")
+ @imports("toml")
+ def windows_rs_dir(dir, bootstrapped, topsrcdir):
+ if bootstrapped:
+ dir = bootstrapped
+ elif dir:
+ dir = dir[0]
+
+ raw_cargo_toml = open(
+ os.path.join(topsrcdir, "build/rust/windows/Cargo.toml")
+ ).read()
+ cargo_toml = toml.loads(raw_cargo_toml)
+ expected_version = cargo_toml["package"]["version"]
+
+ if not dir:
+ raise FatalCheckError(
+ "Cannot find the windows rust crate source.\n"
+ f"Try downloading it with `cargo download -x windows={expected_version}`\n"
+ "(you may need to `cargo install cargo-download` first)\n"
+ f"and set `MOZ_WINDOWS_RS_DIR` to location of the `windows-{expected_version}`"
+ " directory"
+ )
+
+ raw_cargo_toml_orig = open(os.path.join(dir, "Cargo.toml")).read()
+ cargo_toml = toml.loads(raw_cargo_toml_orig)
+ version = cargo_toml["package"]["version"]
+ if version != expected_version:
+ raise FatalCheckError(
+ f"The windows rust crate source in {dir} contains version "
+ f"{version}, but expected {expected_version}."
+ )
+ # Now that we've done the basic sanity check, let's go deeper.
+ DEPENDENCIES = '\n[dependencies.mozbuild]\nversion = "0.1"\n'
+ if not raw_cargo_toml.endswith(DEPENDENCIES):
+ configure_error("In-tree windows crate is missing dependency on mozbuild")
+ if raw_cargo_toml[: -len(DEPENDENCIES)] != raw_cargo_toml_orig:
+ configure_error("In-tree windows crate Cargo.toml doesn't match original")
+
+ lib_rs = open(os.path.join(topsrcdir, "build/rust/windows/src/lib.rs")).read()
+ lib_rs_orig = open(os.path.join(dir, "src/lib.rs")).read()
+ lib_rs_expected = "#![allow(warnings)]\n" + re.sub(
+ r'include!\("([^"]*)"\)',
+ r'include!(mozbuild::windows_rs_path!("src/\1"))',
+ lib_rs_orig,
+ )
+ if lib_rs != lib_rs_expected:
+ configure_error("In-tree windows crate lib.rs doesn't match original")
+
+ return dir
+
+ set_config("MOZ_WINDOWS_RS_DIR", windows_rs_dir)