# -*- 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) add_old_configure_assignment("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" @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 == "WINNT": return ("wasapi",) else: return ("pulseaudio",) option( "--enable-audio-backends", nargs="+", choices=( "aaudio", "alsa", "audiounit", "jack", "opensl", "oss", "pulseaudio", "sndio", "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_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_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") # 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)) # 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") # 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: return ( "cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-wayland-only", "cairo-gtk3-x11-wayland", ) @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" # Wayland support # ============================================================== wayland_headers = pkg_check_modules( "MOZ_WAYLAND", "gtk+-wayland-3.0 >= 3.14 xkbcommon >= 0.4.1 libdrm >= 2.4", allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3"), when=toolkit_gtk, ) @depends(wayland_headers, toolkit_gtk, artifact_builds) def wayland_headers(wayland, toolkit_gtk, artifacts): 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)) # 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, wayland_headers, toolkit_gtk) def gl_default_provider(value, wayland, toolkit_gtk): if value: return value elif wayland: return "EGL" elif toolkit_gtk: return "GLX" 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 add_old_configure_assignment("USE_FC_FREETYPE", fc_freetype) 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) 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 set_config("MOZ_WMF", wmf) set_define("MOZ_WMF", wmf) # 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) imply_option("--enable-fmp4", ffmpeg, "--enable-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) # Built-in fragmented MP4 support. # ============================================================== option( "--disable-fmp4", env="MOZ_FMP4", help="Disable support for in built Fragmented MP4 parsing", ) @depends("--disable-fmp4", target, wmf, applemedia) def fmp4(value, target, wmf, applemedia): enabled = bool(value) if value.origin == "default": # target.os == 'Android' includes all B2G versions enabled = wmf or applemedia or target.os == "Android" if enabled: return True set_config("MOZ_FMP4", fmp4) set_define("MOZ_FMP4", fmp4) add_old_configure_assignment("MOZ_FMP4", fmp4) @depends(target) def sample_type_is_s16(target): # Use integers over floats for audio on Android regardless of the CPU # architecture, because audio backends for Android don't support floats. # We also use integers on ARM because it's more efficient. if target.os == "Android" or target.cpu == "arm": return True @depends(sample_type_is_s16) def sample_type_is_float(t): if not t: return True set_config("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16) set_define("MOZ_SAMPLE_TYPE_S16", sample_type_is_s16) set_config("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float) set_define("MOZ_SAMPLE_TYPE_FLOAT32", sample_type_is_float) set_define("MOZ_VORBIS", sample_type_is_float) set_config("MOZ_VORBIS", sample_type_is_float) set_define("MOZ_TREMOR", sample_type_is_s16) set_config("MOZ_TREMOR", sample_type_is_s16) # 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) def eme_choices(target): if ( target.kernel in ("WINNT", "Linux") and target.os != "Android" and target.cpu in ("x86", "x86_64") ): 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, except # on aarch64 Windows. @depends(build_project, eme_choices, target) def eme_default(build_project, choices, target): if build_project == "browser": if target.kernel != "WINNT" or target.cpu != "aarch64": 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", fmp4, when=eme_choices) def eme(enabled, fmp4): if enabled and enabled.origin != "default" and not fmp4: die("Encrypted Media Extension support requires " "Fragmented MP4 support") @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([])) @depends(eme_modules, target, when=eme_modules) def eme_win32_artifact(modules, target): if "widevine" in modules and target.kernel == "WINNT" and target.cpu == "aarch64": return True set_config("MOZ_EME_WIN32_ARTIFACT", eme_win32_artifact) 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_for_old_configure=True, set_as_define=True, ) project_flag( "MOZ_NORMANDY", help="Enable Normandy recipe runner", set_for_old_configure=True, 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") add_old_configure_assignment( "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",)) check_prog("GN", ("gn",), allow_missing=True) # 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) add_old_configure_assignment("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 , 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 = False for os_fragment in ( "linux", "mingw", "android", "linuxandroid", "dragonfly", "freebsd", "netbsd", "openbsd", "darwin", ): if target.raw_os.startswith(os_fragment): os_match = True cpu_match = False if ( target.cpu in ( "x86_64", "arm", "aarch64", "x86", "ia64", "mips32", "mips64", ) or target.cpu.startswith("ppc") ): cpu_match = True if os_match and cpu_match: return True return False 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", "xtst", ] return libs x11_headers = pkg_check_modules( "MOZ_X11", x11_libs, allow_missing=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"), when=depends(full_toolkit)( lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland") ), ) 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=depends(full_toolkit)(lambda t: t == "cairo-gtk3-wayland"), when=depends(full_toolkit)( lambda t: t in ("cairo-gtk3", "cairo-gtk3-wayland", "cairo-gtk3-x11-wayland") ), ) # 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) add_old_configure_assignment("MOZ_ASAN_REPORTER", enable_asan_reporter) # 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") ) @depends("--enable-release", enable_linker) def default_elfhack(release, linker): # Disable elfhack when explicitly building with --enable-linker=lld if linker and linker.origin != "default" and linker[0] == "lld": return False return bool(release) with only_when(has_elfhack): option( "--disable-elf-hack", default=default_elfhack, help="{Enable|Disable} elf hacks", ) set_config("USE_ELF_HACK", depends_if("--enable-elf-hack")(lambda _: True)) @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.8.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") # Building with -mfpu=neon requires either the "softfp" or the # "hardfp" ABI. Depending on the compiler's default target, and the # CFLAGS, the default ABI might be neither, in which case it is the # "softfloat" ABI. # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so # we can safely mix code built with both ABIs. So, if we detect # that compiling uses the "softfloat" ABI, force the use of the # "softfp" ABI instead. # Confusingly, the __SOFTFP__ preprocessor variable indicates the # "softfloat" ABI, not the "softfp" ABI. # Note: VPX_ASFLAGS is also used in CFLAGS. softfp = cxx_compiler.try_compile( body=""" #ifndef __SOFTFP__ #error "compiler target supports -mfpu=neon, so we don't have to add extra flags" #endif""", when=in_tree_vpx.arm_asm, ) @depends(in_tree_vpx, vpx_nasm, softfp, target) def vpx_as_flags(vpx, vpx_nasm, softfp, target): 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. flags = ["-march=armv7-a", "-mfpu=neon"] if softfp: flags.append("-mfloat-abi=softfp") elif vpx and vpx_nasm and target.os != "WINNT" and target.cpu != "x86_64": flags = ["-DPIC"] return flags 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) def in_tree_jpeg_arm(system_jpeg, target): if system_jpeg: return if target.cpu == "arm": return ("-march=armv7-a", "-mfpu=neon") 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): return target.kernel == "WINNT" 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": if target.cpu == "x86_64": # 32/64-bit macosx asemblers need to prefix symbols with an # underscore. flags = [ "-D__x86_64__", "-DPIC", "-DMACHO", "-DPREFIX", "-Pconfig_darwin64.asm", ] else: flac_only = True 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 if use_nasm: # default disabled components flags.append("-Pdefaults_disabled.asm") 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): def d3d_compiler_dll_result(value): if not value.path: return "provided by the OS" return value.path @depends(target, valid_windows_sdk_dir, fxc) @checking("for D3D compiler DLL", d3d_compiler_dll_result) @imports("os.path") def d3d_compiler_dll(target, windows_sdk_dir, fxc): suffix = { "x86_64": "x64", }.get(target.cpu, target.cpu) name = "d3dcompiler_47.dll" if target.cpu == "aarch64": # AArch64 Windows comes with d3dcompiler_47.dll installed return namespace(name=name, path=None) if windows_sdk_dir: path = os.path.join(windows_sdk_dir.path, "Redist", "D3D", suffix, name) error_extra = "in Windows SDK at {}".format(windows_sdk_dir.path) else: path = os.path.join(os.path.dirname(fxc), name) error_extra = "alongside FXC at {}".format(fxc) if os.path.exists(path): return namespace(name=name, path=path) die("Could not find {} {}".format(name, error_extra)) set_config("MOZ_ANGLE_RENDERER", True) set_config( "MOZ_D3DCOMPILER_VISTA_DLL", d3d_compiler_dll.name, when=d3d_compiler_dll.path ) set_config("MOZ_D3DCOMPILER_VISTA_DLL_PATH", d3d_compiler_dll.path) # 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", ) @depends(dependable(wasm_sandboxing_libraries)) def default_wasm_sandboxing_libraries(libraries): non_default_libs = set() 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), "--with-wasm-sandboxed-libraries", ) @imports("os") def wasi_sysroot(wasi_sysroot, bootstrapped_sysroot, sandboxed_libs): if not wasi_sysroot: if not bootstrapped_sysroot: suggest_disable = "" if sandboxed_libs.origin == "default": suggest_disable = ( " Or build with --without-wasm-sandboxed-libraries." ) die( "Cannot find a wasi sysroot. Please give its location with " "--with-wasi-sysroot." + suggest_disable ) 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 set_config("WASI_SYSROOT", wasi_sysroot) def wasm_compiler_with_flags(compiler, sysroot): if not sysroot: return elif compiler: return ( compiler.wrapper + [compiler.compiler] + compiler.flags + ["--sysroot=%s" % sysroot] ) wasm_cc = compiler("C", wasm, other_compiler=c_compiler) @depends(wasm_cc, wasi_sysroot) def wasm_cc_with_flags(wasm_cc, wasi_sysroot): return wasm_compiler_with_flags(wasm_cc, wasi_sysroot) 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, ) @depends(wasm_cxx, wasi_sysroot) def wasm_cxx_with_flags(wasm_cxx, wasi_sysroot): return wasm_compiler_with_flags(wasm_cxx, wasi_sysroot) set_config("WASM_CXX", wasm_cxx_with_flags) wasm_compile_flags = dependable( ["-fno-exceptions", "-fno-strict-aliasing", "-Qunused-arguments"] ) 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() # new XULStore implementation # ============================================================== @depends(milestone) def new_xulstore(milestone): if milestone.is_nightly: return True set_config("MOZ_NEW_XULSTORE", True, when=new_xulstore) set_define("MOZ_NEW_XULSTORE", True, when=new_xulstore) # 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) # 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, ) check_prog( "PDBSTR", ["pdbstr.exe"], allow_missing=True, bootstrap="pdbstr", when=compile_environment & target_is_windows, ) @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_is_linux): # 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", depends_if("--enable-backgroundtasks")(lambda _: True) ) # 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" and target.os != "Android": return target.cpu in ("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") add_old_configure_assignment("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), ) # 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") pkg_check_modules("MOZ_DBUS_GLIB", "dbus-glib-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) # 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") # 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_is_linux & 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_is_linux & 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_is_linux & 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) # 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_ARC4RANDOM", check_symbol("arc4random")) set_define("HAVE_ARC4RANDOM_BUF", check_symbol("arc4random_buf")) set_define("HAVE_MALLINFO", check_symbol("mallinfo"))