gecko-dev/toolkit/moz.configure

1483 строки
48 KiB
Python

# -*- 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/.
# 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')
elif target.kernel == 'Linux':
return target.cpu in ('x86', 'x86_64', 'mips64', 'arm')
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 Android, in order to dump
# symbols from Android system libraries on the device. For other platforms
# there exist alternatives that don't require bloating up our binary size.
if value and target.os == 'Android':
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)
option('--enable-dmd', env='MOZ_DMD',
help='Enable 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)
imply_option('--enable-replace-malloc', dmd)
# ALSA cubeb backend
# ==============================================================
option('--enable-alsa', env='MOZ_ALSA',
help='Enable ALSA audio backend.')
alsa = pkg_check_modules('MOZ_ALSA', 'alsa', when='--enable-alsa')
set_config('MOZ_ALSA', depends_if(alsa)(lambda _: True))
set_define('MOZ_ALSA', depends_if(alsa)(lambda _: True))
# JACK cubeb backend
# ==============================================================
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))
set_define('MOZ_JACK', depends_if(jack)(lambda _: True))
# PulseAudio cubeb backend
# ==============================================================
@depends(target)
def pulseaudio_default(target):
return target.os not in ('WINNT', 'OSX', 'iOS', 'Android', 'OpenBSD')
option('--enable-pulseaudio', env='MOZ_PULSEAUDIO', default=pulseaudio_default,
help='{Enable|Disable} PulseAudio audio backend.')
pulseaudio = pkg_check_modules('MOZ_PULSEAUDIO', 'libpulse', when='--enable-pulseaudio')
set_config('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
set_define('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
# 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')
@imports(_from='os.path', _import='isdir')
@imports(_from='os.path', _import='expanduser')
@imports(_from='os', _import='environ')
def l10n_base(value):
if value:
path = value[0]
if not isdir(path):
die("Invalid value --with-l10n-base, %s doesn't exist", path)
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
# ==============================================================
# Normally, we'd want to use the `default` field on the option, but that
# requires --target to be resolved at --help time, which requires to run
# config.guess, which we want to avoid. Even better, we could actually set
# `choices` depending on the target, but that doesn't pan out for the same
# reason.
option('--enable-default-toolkit', nargs=1,
choices=('cairo-windows', 'cairo-gtk3', 'cairo-gtk3-wayland',
'cairo-cocoa', 'cairo-uikit', 'cairo-android'),
help='Select default toolkit')
@depends('--enable-default-toolkit', target, '--help')
def full_toolkit(value, target, _):
# Define possible choices for each platform. The default is the first one
# listed when there are several.
if target.os == 'WINNT':
platform_choices = ('cairo-windows',)
elif target.os == 'OSX':
platform_choices = ('cairo-cocoa',)
elif target.os == 'iOS':
platform_choices = ('cairo-uikit',)
elif target.os == 'Android':
platform_choices = ('cairo-android',)
else:
platform_choices = ('cairo-gtk3', 'cairo-gtk3-wayland')
if value:
if value[0] not in platform_choices:
die('`%s` is not a valid value for --enable-default-toolkit on %s\n'
'Valid values: %s', value[0], target.os,
', '.join(platform_choices))
return value[0]
return platform_choices[0]
@depends(full_toolkit)
def toolkit(toolkit):
if toolkit == 'cairo-gtk3-wayland':
widget_toolkit = 'gtk3'
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 == 'gtk3':
toolkit = 'gtk'
if toolkit != 'windows':
return 'MOZ_WIDGET_%s' % toolkit.upper()
set_define(toolkit_define, True)
@depends(toolkit)
def toolkit_gtk(toolkit):
return toolkit == 'gtk3'
set_config('MOZ_X11', True, when=toolkit_gtk)
set_define('MOZ_X11', True, when=toolkit_gtk)
add_old_configure_assignment('MOZ_X11', True, when=toolkit_gtk)
# Wayland support
# ==============================================================
wayland_headers = pkg_check_modules(
'MOZ_WAYLAND', 'gtk+-wayland-3.0 >= 3.10 xkbcommon >= 0.4.1',
allow_missing=depends(full_toolkit)(lambda t: t == 'cairo-gtk3'),
when=depends(full_toolkit)(lambda t: t in ('cairo-gtk3', 'cairo-gtk3-wayland')))
@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', 'gtk3', 'android'):
return True
@depends(pdf_printing)
def pdf_surface_feature(pdf_printing):
if pdf_printing:
return '#define CAIRO_HAS_PDF_SURFACE 1'
else:
# CONFIGURE_SUBST_FILES need explicit empty values.
return ''
set_config('MOZ_PDF_PRINTING', pdf_printing)
set_config('PDF_SURFACE_FEATURE', pdf_surface_feature)
# 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', 'gtk3', '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 == 'gtk3' and
value.origin == 'default'):
return True
add_old_configure_assignment('USE_FC_FREETYPE', fc_freetype)
# Pango
# ==============================================================
pkg_check_modules('MOZ_PANGO',
'pango >= 1.22.0 pangoft2 >= 1.22.0 pangocairo >= 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 >= 6.1.0',
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,
)
add_old_configure_assignment('_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)
add_old_configure_assignment('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')
# Libaom AV1 Video Codec Support
# ==============================================================
option('--enable-av1',
help='Enable libaom for av1 video support')
@depends('--enable-av1', target)
def av1(value, target):
enabled = bool(value)
if value.origin == 'default':
if target.os == 'WINNT' and target.cpu == 'x86':
enabled = False
else:
enabled = True
if enabled:
return True
set_config('MOZ_AV1', av1)
set_define('MOZ_AV1', av1)
# 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
# ==============================================================
# Widevine is enabled by default in desktop browser builds.
@depends(build_project)
def eme_default(build_project):
if build_project == 'browser':
return 'widevine'
option('--enable-eme',
nargs='*',
choices=('widevine',),
default=eme_default,
help='{Enable|Disable} support for Encrypted Media Extensions')
@depends('--enable-eme', target)
def enable_eme(value, target):
# Widevine EME by default enabled on desktop Windows, MacOS and Linux,
# x86 and x64 builds.
if (target.kernel in ('Darwin', 'WINNT', 'Linux') and
target.os not in ('Android', 'iOS') and
target.cpu in ('x86', 'x86_64')):
return value
elif value and value.origin != 'default':
die('%s is not supported on %s' % (value.format('--enable-eme'), target.alias))
# Return the same type of OptionValue (Positive or Negative), with an empty tuple.
return value.__class__(())
@depends(enable_eme, fmp4)
def eme(value, fmp4):
enabled = bool(value)
if value.origin == 'default':
enabled = enabled or fmp4
if enabled and not fmp4:
die('Encrypted Media Extension support requires '
'Fragmented MP4 support')
if enabled:
return True
@depends(enable_eme)
def eme_modules(value):
return value
set_config('MOZ_EME_MODULES', eme_modules)
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)
@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), and necessitates some contortions during
# packaging so that the resources in the omnijar are considered
# as rooted at / and not as rooted at assets/ (which again is
# not the case on desktop: there are omnijars rooted at webrtc/,
# etc). packager.mk handles changing the rooting of the single
# omnijar.
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_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)
option(env='MOZ_ALLOW_LEGACY_EXTENSIONS',
default=milestone.is_nightly,
help='Allow legacy browser extensions')
@depends('MOZ_ALLOW_LEGACY_EXTENSIONS')
def legacy_extensions(value):
if bool(value):
return True
set_config('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
set_define('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
@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.')
# gpsd support
# ==============================================================
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('ZIP', ('zip',))
check_prog('GN', ('gn',), allow_missing=True)
# Key files
# ==============================================================
include('../build/moz.configure/keyfiles.configure')
simple_keyfile('Mozilla API')
simple_keyfile('Google API')
id_and_secret_keyfile('Bing API')
simple_keyfile('Adjust SDK')
id_and_secret_keyfile('Leanplum SDK')
simple_keyfile('Pocket API')
# WebRender integration
# ==============================================================
option('--enable-webrender', nargs='?', choices=('build',),
help='Include WebRender in the build and/or enable it at runtime')
@depends('--enable-webrender')
def webrender(value):
build_webrender = None
enable_webrender = None
if value.origin == 'default':
# if nothing is specified, default to building
build_webrender = True
elif len(value) and value[0] == 'build':
# if explicitly set to 'build', then we build but don't enable
build_webrender = True
elif bool(value):
# if set to true, then build and enable
build_webrender = True
enable_webrender = True
# in all other cases, don't build it or enable it (defaults are fine)
return namespace(
build = build_webrender,
enable = enable_webrender,
)
set_config('MOZ_BUILD_WEBRENDER', webrender.build)
set_define('MOZ_BUILD_WEBRENDER', webrender.build)
set_config('MOZ_ENABLE_WEBRENDER', webrender.enable)
# SIMD acceleration for Rust code (currently just encoding_rs)
# ==============================================================
option('--enable-rust-simd', env='MOZ_RUST_SIMD',
help='Enable explicit SIMD in Rust code.')
@depends('--enable-rust-simd', target)
def rust_simd(value, target):
# As of 2018-06-05, the simd crate only works on aarch64,
# armv7, x86 and x86_64.
if target.cpu in ('aarch64', 'arm', 'x86', 'x86_64') and value:
return True
set_config('MOZ_RUST_SIMD', rust_simd)
set_define('MOZ_RUST_SIMD', rust_simd)
# Printing
# ==============================================================
@depends(target)
def ios_disable_printing(target):
if target.os == 'iOS':
return False
imply_option('--enable-printing', ios_disable_printing, reason='--target')
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 != 'gtk3':
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)
# Enable IPDL's "expensive" unit tests
# ==============================================================
option('--enable-ipdl-tests', help='Enable expensive IPDL tests')
set_config('MOZ_IPDL_TESTS',
depends_if('--enable-ipdl-tests')(lambda _: True))
include('nss.configure')
# Graphics
# ==============================================================
option('--disable-skia', help='Disable use of Skia')
@depends('--disable-skia')
def skia(value):
if not value:
die('--disable-skia is not supported anymore')
else:
return True
set_config('MOZ_ENABLE_SKIA', skia)
set_define('MOZ_ENABLE_SKIA', skia)
set_define('USE_SKIA', skia)
@depends(skia, target)
def skia_android(skia, target):
if skia and target.os == 'Android':
return True
set_define('SK_BUILD_FOR_ANDROID_NDK', skia_android)
option('--disable-skia-gpu', help='Disable use of Skia-GPU')
@depends('--disable-skia-gpu', skia)
def skia_gpu(value, skia):
if value.origin == 'default':
if not skia:
return None
elif value and not skia:
die('Cannot enable Skia-GPU without enabling Skia')
if skia and value:
return True
set_config('MOZ_ENABLE_SKIA_GPU', skia_gpu)
set_define('USE_SKIA_GPU', skia_gpu)
option('--enable-skia-pdf', help='Enable Skia PDF')
@depends('--enable-skia-pdf', skia, target, milestone)
def skia_pdf(value, skia, target, milestone):
if value.origin == 'default':
if not skia:
return None
if milestone.is_nightly and target.os != 'WINNT':
return True
elif value and not skia:
die('Cannot enable Skia PDF without enabling Skia')
if skia and value:
return True
set_config('MOZ_ENABLE_SKIA_PDF', skia_pdf)
set_define('MOZ_ENABLE_SKIA_PDF', skia_pdf)
option('--enable-skia-pdf-sfntly', help='Enable SFNTLY font subsetting in Skia PDF')
@depends('--enable-skia-pdf-sfntly', skia_pdf)
def skia_pdf_sfntly(value, skia_pdf):
if value.origin == 'default':
return skia_pdf
if value and not skia_pdf:
die('Cannot enable SFNTLY subsetting without enabling Skia PDF')
if skia_pdf and value:
return True
set_config('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
set_define('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
@depends(skia_pdf_sfntly)
def sfntly_includes(skia_pdf_sfntly):
includes = []
if skia_pdf_sfntly:
includes += [
'/gfx/sfntly/cpp/src',
]
return includes
set_config('SFNTLY_INCLUDES', sfntly_includes)
@depends(skia)
def skia_includes(skia):
includes = []
if skia:
includes += [
'/gfx/skia',
'/gfx/skia/skia/include/config',
'/gfx/skia/skia/include/core',
'/gfx/skia/skia/include/docs',
'/gfx/skia/skia/include/gpu',
'/gfx/skia/skia/include/utils',
]
return includes
set_config('SKIA_INCLUDES', skia_includes)
option('--with-system-webp',
help='Use system libwebp (located with pkgconfig)')
system_webp = pkg_check_modules('MOZ_WEBP', 'libwebp >= 1.0.1 libwebpdemux >= 1.0.1',
when='--with-system-webp')
set_config('MOZ_SYSTEM_WEBP', depends(when=system_webp)(lambda: True))
# Build Freetype in the tree
# ==============================================================
@depends(target, 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)
add_old_configure_assignment('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, check_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)
add_old_configure_assignment('FT2_LIBS',
ft2_info.libs)
add_old_configure_assignment('FT2_CFLAGS',
ft2_info.cflags)
# Marionette remote protocol
# ==============================================================
#
# Marionette is the Gecko remote protocol used for various remote control,
# automation, and testing purposes throughout Gecko, Firefox, and Fennec.
# Marionette lives in ../testing/marionette.
#
# Marionette is not really a toolkit feature, as much as a Gecko engine
# feature. But it is enabled based on the toolkit (and target), so here
# it lives.
#
# It also backs ../testing/geckodriver, which is Mozilla's WebDriver
# implementation.
#
# For more information, see
# https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette.
@depends(target)
def marionette(target):
"""Enable Marionette by default, except on Android."""
if target.os != 'Android':
return True
imply_option('--enable-marionette', marionette, reason='Not Android')
option('--enable-marionette',
help='Enable Marionette remote protocol')
@depends('--enable-marionette')
def marionette(value):
if value:
return True
set_config('ENABLE_MARIONETTE', marionette)
# 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.
@depends('--enable-tests', target, cross_compiling, hazard_analysis, asan)
def geckodriver_default(enable_tests, target, cross_compile, hazard, asan):
if not enable_tests:
return False
# geckodriver depends on winapi 0.2.8, which doesn't work with AArch64.
if target.os == 'WINNT' and target.cpu == 'aarch64':
return False
if hazard or target.os == 'Android' or (asan and cross_compile):
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('ENABLE_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)
add_old_configure_assignment('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)
option('--enable-hardware-aec-ns', when=webrtc,
help='Enable support for hardware AEC and noise suppression')
set_config('MOZ_WEBRTC_HARDWARE_AEC_NS',
depends_if('--enable-hardware-aec-ns', when=webrtc)(lambda _: True))
set_define('MOZ_WEBRTC_HARDWARE_AEC_NS',
depends_if('--enable-hardware-aec-ns', when=webrtc)(lambda _: True))
# 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))
# 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', 'x86', 'x86_64')
@depends('--enable-release')
def default_elfhack(release):
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(check_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'))
set_config('WEBIDL_ROOT', idl_roots.webidl_root)
set_config('IPDL_ROOT', idl_roots.ipdl_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)
# 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',)
@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)
@depends(c_compiler, target, when=depends(midl, target)(lambda m, t: m and t.kernel == 'WINNT'))
def midl_flags(c_compiler, target):
if c_compiler and c_compiler.type in ('msvc', 'clang-cl'):
env = {
'x86': 'win32',
'x86_64': 'x64',
'aarch64': 'arm64',
}[target.cpu]
return ['-env', env]
# mingw
return {
'x86': ['--win32', '-m32'],
'x86_64': ['--win64', '-m64'],
}[target.cpu]
set_config('MIDL_FLAGS', midl_flags)
# Accessibility
# ==============================================================
option('--disable-accessibility', help='Disable accessibility support')
@depends('--disable-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)
add_old_configure_assignment('ACCESSIBILITY', accessibility)
# Addon 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)
# Launcher process (Windows only)
# ==============================================================
@depends(target, milestone)
def launcher_process_default(target, milestone):
return target.os == 'WINNT' and milestone.is_nightly
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)
# Prio
# ==============================================================
@depends(c_compiler)
def libprio(info):
if info:
# MSVC is not supported by libprio.
if info.type in ('msvc',):
return None
return True
set_config('MOZ_LIBPRIO', libprio)
# Maintenance service (Windows only)
# ==============================================================
option('--enable-maintenance-service',
when=target_is_windows, default=target_is_windows,
help='{Enable|Disable} building of maintenance service')
set_define('MOZ_MAINTENANCE_SERVICE',
depends_if('--enable-maintenance-service',
when=target_is_windows)(lambda _: True))
set_config('MOZ_MAINTENANCE_SERVICE',
depends_if('--enable-maintenance-service',
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'
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))
# Verify MAR signatures
# ==============================================================
option('--enable-verify-mar', help='Enable verifying MAR signatures')
set_define('MOZ_VERIFY_MAR_SIGNATURE',
depends_if('--enable-verify-mar')(lambda _: True))
set_config('MOZ_VERIFY_MAR_SIGNATURE',
depends_if('--enable-verify-mar')(lambda _: True))
# TaskTracer
# ==============================================================
option('--enable-tasktracer', help='Enable TaskTracer')
set_define('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(lambda _: True))
set_config('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(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', depends_if('--enable-layout-debugger')(lambda _: True))
# 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'))
wine = check_prog('WINE', ['wine'], when=depends(target, host)
(lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))
# VPX
# ===
with only_when(compile_environment):
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.5.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, gnu_as)
def in_tree_vpx(system_libvpx, target, gnu_as):
if system_libvpx:
return
use_yasm = (target.cpu in ('x86', 'x86_64')) or None
need_yasm = False
arm_asm = (target.cpu == 'arm' and gnu_as) or None
if use_yasm:
need_yasm = True
if target.kernel == 'WINNT':
need_yasm = Version('1.1')
return namespace(arm_asm=arm_asm, use_yasm=use_yasm, need_yasm=need_yasm)
# 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, softfp, target)
def vpx_as_flags(vpx, 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.use_yasm and target.os != 'WINNT' and target.cpu != 'x86_64':
flags = ['-DPIC']
return flags
set_config('VPX_USE_YASM', in_tree_vpx.use_yasm)
set_config('VPX_ASFLAGS', vpx_as_flags)
add_old_configure_assignment('VPX_ASFLAGS', vpx_as_flags)
# JPEG
# ====
with only_when(compile_environment):
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
''',
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
''',
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(system_jpeg, target):
if system_jpeg:
return
flags = ()
use_yasm = None
need_yasm = False
if target.kernel == 'Darwin':
if target.cpu == 'x86':
flags = ('-DPIC', '-DMACHO')
elif target.cpu == 'x86_64':
flags = ('-D__x86_64__', '-DPIC', '-DMACHO')
elif target.kernel == 'WINNT':
if target.cpu == 'x86':
flags = ('-DPIC', '-DWIN32')
elif target.cpu == 'x86_64':
flags = ('-D__x86_64__', '-DPIC', '-DWIN64', '-DMSVC')
elif target.cpu == 'arm':
flags = ('-march=armv7-a', '-mfpu=neon')
elif target.cpu == 'aarch64':
flags = ('-march=armv8-a',)
elif target.cpu == 'mips32':
flags = ('-mdspr2',)
elif target.cpu == 'x86':
flags = ('-DPIC', '-DELF')
elif target.cpu == 'x86_64':
flags = ('-D__x86_64__', '-DPIC', '-DELF')
if target.cpu in ('x86', 'x86_64'):
use_yasm = True
if target.kernel == 'Linux' and target.os == 'GNU':
need_yasm = Version('1.0.1')
else:
need_yasm = Version('1.1')
return namespace(flags=flags, use_yasm=use_yasm, need_yasm=need_yasm)
set_config('LIBJPEG_TURBO_USE_YASM', in_tree_jpeg.use_yasm)
set_config('LIBJPEG_TURBO_ASFLAGS', in_tree_jpeg.flags)
@depends(yasm_version, in_tree_vpx.need_yasm, in_tree_jpeg.use_yasm)
@imports(_from='__builtin__', _import='sorted')
def valid_yasm_version(yasm_version, for_vpx, for_jpeg):
requires = {
'vpx': for_vpx,
'jpeg': for_jpeg,
}
requires = {k: v for (k, v) in requires.items() if v}
if requires and not yasm_version:
items = sorted(requires.keys())
if len(items) > 1:
what = ' and '.join((', '.join(items[:-1]), items[-1]))
else:
what = items[0]
die('Yasm is required to build with %s, but you do not appear to have '
'Yasm installed.' % what)
versioned = {k: v for (k, v) in requires.items() if v is not True}
by_version = sorted(versioned.items(), key=lambda x: x[1])
if by_version:
what, version = by_version[-1]
if yasm_version < version:
die('Yasm version %s or greater is required to build with %s.'
% (version, what))