Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  moz.configure   Sprache: unbekannt

 
# -*- 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/.

# App-specific project settings


project_flag(
    env="MOZ_APP_ID",
    nargs=1,
    help='Used for application.ini\'s "ID" field, and crash reporter server url',
)


@depends("MOZ_APP_ID", build_project)
def check_moz_app_id(moz_app_id, build_project):
    if not moz_app_id:
        die(f"No value for MOZ_APP_ID in project '{build_project}'")


project_flag(
    env="MOZ_APP_VENDOR",
    nargs=1,
    help='Used for application.ini\'s "Vendor" field, which also impacts profile location and user-visible fields',
)

project_flag(
    env="MOZ_APP_UA_NAME",
    default="",
    nargs=1,
    help="Application name in the User Agent string",
)

project_flag(
    env="MOZ_DEVTOOLS",
    default="server",
    choices=("all", "server"),
    nargs=1,
    help="Which devtools version should be built",
)


option(
    env="MOZ_STUB_INSTALLER",
    help="Produce a stub installer",
)
set_config("MOZ_STUB_INSTALLER", True, when="MOZ_STUB_INSTALLER")


project_flag(
    env="MOZ_PROFILE_MIGRATOR",
    help="Enable profile migrator",
)

project_flag(
    env="BROWSER_CHROME_URL",
    default="",
    nargs=1,
    set_as_define=True,
    help="Markup for a single browser window",
)
set_define(
    "BROWSER_CHROME_URL_QUOTED",
    depends("BROWSER_CHROME_URL")(lambda v: f'"{v[0]}"' if v else ""),
)

# External builds (specifically Ubuntu) may drop the hg repo information, so we allow to
# explicitly set the repository and changeset information in.
option(env="MOZ_SOURCE_REPO", nargs=1, help="Project source repository")
set_config("MOZ_SOURCE_REPO", depends_if("MOZ_SOURCE_REPO")(lambda src: src[0]))
option(env="MOZ_SOURCE_CHANGESET", nargs=1, help="Source changeset")
set_config("MOZ_SOURCE_CHANGESET", depends_if("MOZ_SOURCE_CHANGESET")(lambda v: v[0]))

option(
    env="MOZ_INCLUDE_SOURCE_INFO",
    # Build revisions should always be present in official builds
    default=mozilla_official,
    help="Include build repository informations",
)
set_config("MOZ_INCLUDE_SOURCE_INFO", True, when="MOZ_INCLUDE_SOURCE_INFO")

option(
    "--with-distribution-id",
    nargs=1,
    default="org.mozilla",
    help="Set distribution-specific id",
)
set_config("MOZ_DISTRIBUTION_ID", depends("--with-distribution-id")(lambda v: v[0]))
add_old_configure_assignment(
    "MOZ_DISTRIBUTION_ID", depends("--with-distribution-id")(lambda v: v[0])
)


@depends("MOZ_APP_VENDOR", build_project)
def check_moz_app_vendor(moz_app_vendor, build_project):
    if not moz_app_vendor:
        die(f"No value for MOZ_APP_VENDOR in project '{build_project}'")


# 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", "iOS", "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("--disable-gecko-profiler", help="Disable the Gecko profiler")


@depends("--disable-gecko-profiler", target)
def gecko_profiler(enable_gecko_profiler, target):
    if not enable_gecko_profiler:
        return False

    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.kernel in ("Darwin", "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)


# Enable perfetto on Android if gecko profiling is enabled and only for
# nightly builds. Linux support requires at least linux-headers-3.18 for <linux/vm_sockets.h>
set_config(
    "MOZ_PERFETTO", gecko_profiler_define, when=target_is_android & milestone.is_nightly
)
set_define(
    "MOZ_PERFETTO", gecko_profiler_define, when=target_is_android & milestone.is_nightly
)


# 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)

# 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.kernel == "Darwin":
        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.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 in ("Android", "OSX", "iOS", "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 in ("Android", "OSX", "iOS", "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 in ("Android", "OSX", "iOS", "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", when=use_pkg_config
)

set_config("MOZ_AUDIOUNIT_RUST", imply_audiounit, when="--enable-audio-backends")

imply_option(
    "--enable-jack", imply_jack, reason="--enable-audio-backends", when=use_pkg_config
)

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",
    when=use_pkg_config,
)

imply_option(
    "--enable-sndio", imply_sndio, reason="--enable-audio-backends", when=use_pkg_config
)

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",
    when=use_pkg_config,
)


@depends("--enable-alsa", when=use_pkg_config)
def enable_alsa_option(enable_alsa):
    return enable_alsa


@depends(enable_alsa_option, 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",
    when=use_pkg_config,
)

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",
    when=use_pkg_config,
)

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",
    when=use_pkg_config,
)

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 == "iOS":
        return ("cairo-uikit",)
    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)


@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)

# 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


option("--with-system-av1", help="Use system av1 (located with pkg-config)")

pkg_check_modules("MOZ_SYSTEM_LIBAOM", "aom >= 3.0.0", when="--with-system-av1")
pkg_check_modules("MOZ_SYSTEM_LIBDAV1D", "dav1d >= 1.2.1", when="--with-system-av1")


@depends(target, "--with-system-av1", when=av1 & compile_environment)
def dav1d_asm(target, system_av1):
    if not system_av1 and target.cpu in ("arm", "aarch64", "x86", "x86_64"):
        return True


@depends(target, "--with-system-av1", when=av1 & compile_environment)
def dav1d_nasm(target, system_av1):
    if not system_av1 and 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)
set_config("MOZ_SYSTEM_AV1", True, when="--with-system-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_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_GECKOVIEW_HISTORY",
    help="Enable Geckoview History instead of Places",
    set_as_define=True,
)


# Child Process Name for IPC
# ==============================================================
@depends(toolkit, bin_suffix(target))
def moz_child_process_name(toolkit, bin_suffix):
    if toolkit != "android":
        return f"plugin-container{bin_suffix}"
    else:
        # We want to let Android unpack the file at install time, but it only
        # does so if the file is named libsomething.so. The lib/ path is also
        # required because the unpacked file will be under the lib/ subdirectory
        # and will need to be executed from that path.
        return "libplugin-container.so"


set_config("MOZ_CHILD_PROCESS_NAME", moz_child_process_name)

with only_when(target_is_osx):
    set_config("MOZ_CHILD_PROCESS_BUNDLE", "plugin-container.app/Contents/MacOS/")
    set_config(
        "MOZ_CHILD_PROCESS_BUNDLEID",
        depends("--with-distribution-id")(lambda v: f"{v[0]}.plugincontainer"),
    )
    set_config("MOZ_CHILD_PROCESS_BUNDLENAME", "plugin-container.app")

# Profile Management
# ==============================================================
# Selectable profiles are enabled by default.

set_define("MOZ_SELECTABLE_PROFILES", True)
set_config("MOZ_SELECTABLE_PROFILES", 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_GECKOVIEW_HISTORY")
def check_places_and_geckoview_history(places, geckoview_history):
    if places and geckoview_history:
        die("Cannot use MOZ_GECKOVIEW_HISTORY alongside MOZ_PLACES.")
    if not places and not geckoview_history:
        die("One of MOZ_GECKOVIEW_HISTORY or MOZ_PLACES must be set.")


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)

# 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)


# Printing
# ==============================================================
@depends(target)
def printing_default(target):
    return target.os != "iOS"


option(
    "--disable-printing",
    default=printing_default,
    help="{Enable|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)",
    when=use_pkg_config,
)

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_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_config("MOZ_SRTP", webrtc)
set_config("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_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 = pkg_check_modules(
    "MOZ_X11",
    x11_libs,
    allow_missing=toolkit_gtk_x11_optional,
    when=toolkit_gtk_x11,
    config=False,  # set after the OpenBSD hook below
)


@depends(x11, target_is_openbsd)
def moz_x11_libs(x11, target_is_openbsd):
    if not x11:
        return []
    if target_is_openbsd:
        rpath = tuple(
            f"-Wl,-rpath-link,{flag[2:]}" for flag in x11.libs if flag.startswith("-L")
        )
    else:
        rpath = ()
    return x11.libs + rpath


set_config("MOZ_X11_CFLAGS", x11.cflags)
set_config("MOZ_X11_LIBS", moz_x11_libs)
set_config("MOZ_X11", True, when=x11)
set_define("MOZ_X11", True, when=x11)

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("textwrap")
    def has_pack_relative_relocs(
        c_compiler,
        extra_toolchain_flags,
        linker_ldflags,
        readelf,
    ):
        with create_temporary_file(suffix=".out") as path:
            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

    @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

    @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)",
        when=use_pkg_config,
    )

    @depends("--with-system-libvpx", when=use_pkg_config)
    def with_system_libvpx_option(with_system_libvpx):
        return with_system_libvpx

    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 "
--> --------------------

--> maximum size reached

--> --------------------

[ Verzeichnis aufwärts0.52unsichere Verbindung  Übersetzung europäischer Sprachen durch Browser  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge