1 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
2 # vim: set filetype=python:
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 # Set the MOZ_CONFIGURE_OPTIONS variable with all the options that
8 # were passed somehow (environment, command line, mozconfig)
10 @imports(_from='mozbuild.shellutil', _import='quote')
11 @imports(_from='mozbuild.util', _import='ensure_unicode')
12 @imports(_from='mozbuild.util', _import='system_encoding')
13 @imports(_from='six', _import='itervalues')
14 @imports('__sandbox__')
15 def all_configure_options():
18 for option in itervalues(__sandbox__._options):
19 # __sandbox__._options contains items for both option.name and
20 # option.env. But it's also an OrderedDict, meaning both are
22 # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not
24 if option == previous or option.env in ('OLD_CONFIGURE', 'MOZCONFIG'):
27 value = __sandbox__._value_for(option)
28 # We only want options that were explicitly given on the command
29 # line, the environment, or mozconfig, and that differ from the
31 if (value is not None and value.origin not in ('default', 'implied') and
32 value != option.default):
33 result.append(ensure_unicode(__sandbox__._raw_options[option],
35 # We however always include options that are sent to old configure
36 # because we don't know their actual defaults. (Keep the conditions
37 # separate for ease of understanding and ease of removal)
38 elif (option.help == 'Help missing for old configure options' and
39 option in __sandbox__._raw_options):
40 result.append(ensure_unicode(__sandbox__._raw_options[option],
43 # We shouldn't need this, but currently, quote will return a byte string
44 # if result is empty, and that's not wanted here.
51 set_config('MOZ_CONFIGURE_OPTIONS', all_configure_options)
54 def fold_libs(target):
55 return target.os in ('WINNT', 'OSX', 'Android')
57 set_config('MOZ_FOLD_LIBS', fold_libs)
60 # ==============================================================
61 # Some of the options here imply an option from js/moz.configure,
62 # so, need to be declared before the include.
64 option('--enable-jprof', env='MOZ_JPROF',
65 help='Enable jprof profiling tool (needs mozilla/tools/jprof)')
67 @depends('--enable-jprof')
72 set_config('MOZ_JPROF', jprof)
73 set_define('MOZ_JPROF', jprof)
74 imply_option('--enable-profiling', jprof)
77 def gecko_profiler(target):
78 if target.os == 'Android':
79 return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64')
80 elif target.kernel == 'Linux':
81 return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64', 'mips64')
82 elif target.kernel == 'FreeBSD':
83 return target.cpu in ('aarch64', 'x86_64')
84 return target.os in ('OSX', 'WINNT')
86 @depends(gecko_profiler)
87 def gecko_profiler_define(value):
91 set_config('MOZ_GECKO_PROFILER', gecko_profiler_define)
92 set_define('MOZ_GECKO_PROFILER', gecko_profiler_define)
95 # Whether code to parse ELF binaries should be compiled for the Gecko profiler
96 # (for symbol table dumping).
97 @depends(gecko_profiler, target)
98 def gecko_profiler_parse_elf(value, target):
99 # Currently we only want to build this code on Linux (including Android) and BSD.
100 # For Android, this is in order to dump symbols from Android system, where
101 # on other platforms there exist alternatives that don't require bloating
102 # up our binary size. For Linux more generally, we use this in profile
103 # pre-symbolication support, since MozDescribeCodeAddress doesn't do
104 # anything useful on that platform. (Ideally, we would update
105 # MozDescribeCodeAddress to call into some Rust crates that parse ELF and
106 # DWARF data, but build system issues currently prevent Rust from being
108 if value and (target.kernel == 'Linux' or target.kernel == 'FreeBSD'):
111 set_config('MOZ_GECKO_PROFILER_PARSE_ELF', gecko_profiler_parse_elf)
112 set_define('MOZ_GECKO_PROFILER_PARSE_ELF', gecko_profiler_parse_elf)
114 # enable this by default if the profiler is enabled
115 # Note: also requires jemalloc
116 set_config('MOZ_PROFILER_MEMORY', gecko_profiler_define)
117 set_define('MOZ_PROFILER_MEMORY', gecko_profiler_define)
120 @depends('--enable-debug', milestone, build_project,
121 # Artifact builds are included because the downloaded artifacts can
123 when=artifact_builds | depends(when='--enable-replace-malloc')(lambda: True))
124 def dmd_default(debug, milestone, build_project):
125 return bool(build_project == 'browser' and (debug or milestone.is_nightly))
128 option('--enable-dmd', env='MOZ_DMD', default=dmd_default,
129 help='{Enable|Disable} Dark Matter Detector (heap profiler). '
130 'Also enables jemalloc, replace-malloc and profiling')
133 @depends('--enable-dmd')
139 set_config('MOZ_DMD', dmd)
140 set_define('MOZ_DMD', dmd)
141 add_old_configure_assignment('MOZ_DMD', dmd)
142 imply_option('--enable-profiling', dmd)
143 imply_option('--enable-jemalloc', dmd, when=compile_environment)
144 imply_option('--enable-replace-malloc', dmd, when=compile_environment)
147 # ==============================================================
148 option('--enable-alsa', env='MOZ_ALSA',
149 help='Enable ALSA audio backend.')
151 alsa = pkg_check_modules('MOZ_ALSA', 'alsa', when='--enable-alsa')
153 set_config('MOZ_ALSA', depends_if(alsa)(lambda _: True))
154 set_define('MOZ_ALSA', depends_if(alsa)(lambda _: True))
157 # ==============================================================
158 option('--enable-jack', env='MOZ_JACK',
159 help='Enable JACK audio backend.')
161 jack = pkg_check_modules('MOZ_JACK', 'jack', when='--enable-jack')
163 set_config('MOZ_JACK', depends_if(jack)(lambda _: True))
164 set_define('MOZ_JACK', depends_if(jack)(lambda _: True))
166 # PulseAudio cubeb backend
167 # ==============================================================
169 def pulseaudio_default(target):
170 return target.os not in ('WINNT', 'OSX', 'Android', 'OpenBSD')
172 option('--enable-pulseaudio', env='MOZ_PULSEAUDIO', default=pulseaudio_default,
173 help='{Enable|Disable} PulseAudio audio backend.')
175 pulseaudio = pkg_check_modules('MOZ_PULSEAUDIO', 'libpulse', when='--enable-pulseaudio')
177 set_config('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
178 set_define('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
180 # AudioUnit cubeb Rust backend
181 # ==============================================================
183 def enable_audiounit_rust(target):
184 return target.os == 'OSX' and target.kernel == 'Darwin'
186 set_config('MOZ_AUDIOUNIT_RUST', True, when=enable_audiounit_rust)
187 set_define('MOZ_AUDIOUNIT_RUST', True, when=enable_audiounit_rust)
190 # ==============================================================
191 include('../js/moz.configure')
195 # ==============================================================
196 include('../build/moz.configure/node.configure')
199 # ==============================================================
200 option('--with-l10n-base', nargs=1, env='L10NBASEDIR',
201 help='Path to l10n repositories')
203 @depends('--with-l10n-base', 'MOZ_AUTOMATION', check_build_environment)
204 @imports(_from='os.path', _import='isdir')
205 @imports(_from='os.path', _import='expanduser')
206 @imports(_from='os', _import='environ')
207 def l10n_base(value, automation, build_env):
211 die("Invalid value --with-l10n-base, %s doesn't exist", path)
213 path = os.path.join(build_env.topsrcdir, '../l10n-central')
217 'MOZBUILD_STATE_PATH',
218 expanduser(os.path.join('~', '.mozbuild'))),
220 return os.path.realpath(os.path.abspath(path))
222 set_config('L10NBASEDIR', l10n_base)
226 # ==============================================================
228 def toolkit_choices(target):
229 if target.os == 'WINNT':
230 return ('cairo-windows',)
231 elif target.os == 'OSX':
232 return ('cairo-cocoa',)
233 elif target.os == 'Android':
234 return ('cairo-android',)
236 return ('cairo-gtk3', 'cairo-gtk3-wayland')
238 @depends(toolkit_choices)
239 def toolkit_default(choices):
242 option('--enable-default-toolkit', nargs=1,
243 choices=toolkit_choices, default=toolkit_default,
244 help='Select default toolkit')
246 @depends_if('--enable-default-toolkit')
247 def full_toolkit(value):
250 @depends(full_toolkit)
251 def toolkit(toolkit):
252 if toolkit.startswith('cairo-gtk3'):
253 widget_toolkit = 'gtk'
255 widget_toolkit = toolkit.replace('cairo-', '')
256 return widget_toolkit
258 set_config('MOZ_WIDGET_TOOLKIT', toolkit)
259 add_old_configure_assignment('MOZ_WIDGET_TOOLKIT', toolkit)
262 def toolkit_define(toolkit):
263 if toolkit != 'windows':
264 return 'MOZ_WIDGET_%s' % toolkit.upper()
266 set_define(toolkit_define, True)
269 def toolkit_gtk(toolkit):
270 return toolkit == 'gtk'
272 set_config('MOZ_X11', True, when=toolkit_gtk)
273 set_define('MOZ_X11', True, when=toolkit_gtk)
274 add_old_configure_assignment('MOZ_X11', True, when=toolkit_gtk)
277 # ==============================================================
278 wayland_headers = pkg_check_modules(
279 'MOZ_WAYLAND', 'gtk+-wayland-3.0 >= 3.10 xkbcommon >= 0.4.1 libdrm >= 2.4',
280 allow_missing=depends(full_toolkit)(lambda t: t == 'cairo-gtk3'),
281 when=depends(full_toolkit)(lambda t: t in ('cairo-gtk3', 'cairo-gtk3-wayland')))
284 @depends(wayland_headers, toolkit_gtk, artifact_builds)
285 def wayland_headers(wayland, toolkit_gtk, artifacts):
286 if toolkit_gtk and artifacts:
291 set_config('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True))
292 set_define('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True))
295 # ==============================================================
296 option('--with-gl-provider', nargs=1, help='Set GL provider backend type')
298 @depends('--with-gl-provider')
299 def gl_provider(value):
303 @depends(gl_provider)
304 def gl_provider_define(provider):
306 return 'GLContextProvider%s' % provider
308 set_define('MOZ_GL_PROVIDER', gl_provider_define)
310 @depends(gl_provider, wayland_headers, toolkit_gtk)
311 def gl_default_provider(value, wayland, toolkit_gtk):
319 set_config('MOZ_GL_PROVIDER', gl_provider)
320 set_config('MOZ_GL_DEFAULT_PROVIDER', gl_default_provider)
322 @depends(gl_default_provider)
323 def gl_provider_define(provider):
325 return 'GL_PROVIDER_%s' % provider
327 set_define(gl_provider_define, True)
331 # ==============================================================
333 def pdf_printing(toolkit):
334 if toolkit in ('windows', 'gtk', 'android'):
337 @depends(pdf_printing)
338 def pdf_surface_feature(pdf_printing):
340 return '#define CAIRO_HAS_PDF_SURFACE 1'
342 # CONFIGURE_SUBST_FILES need explicit empty values.
345 set_config('MOZ_PDF_PRINTING', pdf_printing)
346 set_config('PDF_SURFACE_FEATURE', pdf_surface_feature)
349 # Event loop instrumentation
350 # ==============================================================
351 option(env='MOZ_INSTRUMENT_EVENT_LOOP',
352 help='Force-enable event loop instrumentation')
354 @depends('MOZ_INSTRUMENT_EVENT_LOOP', toolkit)
355 def instrument_event_loop(value, toolkit):
356 if value or (toolkit in ('windows', 'gtk', 'cocoa', 'android') and
357 value.origin == 'default'):
360 set_config('MOZ_INSTRUMENT_EVENT_LOOP', instrument_event_loop)
361 set_define('MOZ_INSTRUMENT_EVENT_LOOP', instrument_event_loop)
364 # Fontconfig Freetype
365 # ==============================================================
366 option(env='USE_FC_FREETYPE',
367 help='Force-enable the use of fontconfig freetype')
369 @depends('USE_FC_FREETYPE', toolkit)
370 def fc_freetype(value, toolkit):
371 if value or (toolkit == 'gtk' and
372 value.origin == 'default'):
375 add_old_configure_assignment('USE_FC_FREETYPE', fc_freetype)
378 # ==============================================================
379 pkg_check_modules('MOZ_PANGO',
380 'pango >= 1.22.0 pangoft2 >= 1.22.0 pangocairo >= 1.22.0',
384 # ==============================================================
385 fontconfig_info = pkg_check_modules('_FONTCONFIG', 'fontconfig >= 2.7.0',
388 @depends(fc_freetype)
389 def check_for_freetype2(fc_freetype):
393 # Check for freetype2. Flags are combined with fontconfig flags.
394 freetype2_info = pkg_check_modules('_FT2', 'freetype2 >= 6.1.0',
395 when=check_for_freetype2)
397 @depends(fontconfig_info, freetype2_info)
398 def freetype2_combined_info(fontconfig_info, freetype2_info):
399 if not freetype2_info:
401 if not fontconfig_info:
402 return freetype2_info
404 cflags=freetype2_info.cflags + fontconfig_info.cflags,
405 libs=freetype2_info.libs + fontconfig_info.libs,
408 add_old_configure_assignment('_HAVE_FREETYPE2',
409 depends_if(freetype2_info)(lambda _: True))
411 # Apple platform decoder support
412 # ==============================================================
414 def applemedia(toolkit):
415 if toolkit in ('cocoa', 'uikit'):
418 set_config('MOZ_APPLEMEDIA', applemedia)
419 set_define('MOZ_APPLEMEDIA', applemedia)
420 add_old_configure_assignment('MOZ_APPLEMEDIA', applemedia)
422 # Windows Media Foundation support
423 # ==============================================================
424 option('--disable-wmf',
425 help='Disable support for Windows Media Foundation')
427 @depends('--disable-wmf', target)
428 def wmf(value, target):
429 enabled = bool(value)
430 if value.origin == 'default':
431 # Enable Windows Media Foundation support by default.
432 # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
433 # guaranteed to have a recent-enough SDK to build WMF.
434 enabled = target.os == 'WINNT'
435 if enabled and target.os != 'WINNT':
436 die('Cannot enable Windows Media Foundation support on %s', target.os)
440 set_config('MOZ_WMF', wmf)
441 set_define('MOZ_WMF', wmf)
443 # FFmpeg H264/AAC Decoding Support
444 # ==============================================================
445 option('--disable-ffmpeg',
446 help='Disable FFmpeg for fragmented H264/AAC decoding')
448 @depends('--disable-ffmpeg', target)
449 def ffmpeg(value, target):
450 enabled = bool(value)
451 if value.origin == 'default':
452 enabled = target.os not in ('Android', 'WINNT')
456 set_config('MOZ_FFMPEG', ffmpeg)
457 set_define('MOZ_FFMPEG', ffmpeg)
458 imply_option('--enable-fmp4', ffmpeg, '--enable-ffmpeg')
460 # AV1 Video Codec Support
461 # ==============================================================
462 option('--disable-av1',
463 help='Disable av1 video support')
465 @depends('--enable-av1')
470 @depends(target, nasm_version, when=av1 & compile_environment)
471 def dav1d_asm(target, nasm_version):
472 if target.os != 'Android':
473 if target.cpu == 'aarch64':
475 elif target.cpu in ('x86', 'x86_64'):
476 if nasm_version < '2.14':
477 die('nasm 2.14 or greater is required for AV1 support. '
478 'Either install nasm or add --disable-av1 to your configure options.')
482 set_config('MOZ_DAV1D_ASM', dav1d_asm)
483 set_define('MOZ_DAV1D_ASM', dav1d_asm)
484 set_config('MOZ_AV1', av1)
485 set_define('MOZ_AV1', av1)
487 # Built-in fragmented MP4 support.
488 # ==============================================================
489 option('--disable-fmp4', env='MOZ_FMP4',
490 help='Disable support for in built Fragmented MP4 parsing')
492 @depends('--disable-fmp4', target, wmf, applemedia)
493 def fmp4(value, target, wmf, applemedia):
494 enabled = bool(value)
495 if value.origin == 'default':
496 # target.os == 'Android' includes all B2G versions
497 enabled = wmf or applemedia or target.os == 'Android'
501 set_config('MOZ_FMP4', fmp4)
502 set_define('MOZ_FMP4', fmp4)
503 add_old_configure_assignment('MOZ_FMP4', fmp4)
506 def sample_type_is_s16(target):
507 # Use integers over floats for audio on Android regardless of the CPU
508 # architecture, because audio backends for Android don't support floats.
509 # We also use integers on ARM because it's more efficient.
510 if target.os == 'Android' or target.cpu == 'arm':
513 @depends(sample_type_is_s16)
514 def sample_type_is_float(t):
518 set_config('MOZ_SAMPLE_TYPE_S16', sample_type_is_s16)
519 set_define('MOZ_SAMPLE_TYPE_S16', sample_type_is_s16)
520 set_config('MOZ_SAMPLE_TYPE_FLOAT32', sample_type_is_float)
521 set_define('MOZ_SAMPLE_TYPE_FLOAT32', sample_type_is_float)
523 set_define('MOZ_VORBIS', sample_type_is_float)
524 set_config('MOZ_VORBIS', sample_type_is_float)
525 set_define('MOZ_TREMOR', sample_type_is_s16)
526 set_config('MOZ_TREMOR', sample_type_is_s16)
528 # OpenMAX IL Decoding Support
529 # ==============================================================
530 option('--enable-openmax',
531 help='Enable OpenMAX IL for video/audio decoding')
533 @depends('--enable-openmax')
535 enabled = bool(value)
539 set_config('MOZ_OMX', openmax)
540 set_define('MOZ_OMX', openmax)
543 # ==============================================================
545 def eme_choices(target):
546 if (target.kernel in ('Darwin', 'WINNT', 'Linux') and
547 target.os != 'Android' and
548 target.cpu in ('x86', 'x86_64')):
550 if target.kernel == 'WINNT' and target.cpu == 'aarch64':
554 # Widevine is enabled by default in desktop browser builds, except
555 # on aarch64 Windows.
556 @depends(build_project, eme_choices, target)
557 def eme_default(build_project, choices, target):
558 if build_project == 'browser':
559 if target.kernel != 'WINNT' or target.cpu != 'aarch64':
563 option('--enable-eme',
568 help='{Enable|Disable} support for Encrypted Media Extensions')
571 @depends('--enable-eme', fmp4, when=eme_choices)
572 def eme(enabled, fmp4):
573 if enabled and enabled.origin != 'default' and not fmp4:
574 die('Encrypted Media Extension support requires '
575 'Fragmented MP4 support')
578 @depends('--enable-eme', when=eme_choices)
579 def eme_modules(value):
583 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
585 set_config('MOZ_EME_MODULES', eme_modules | dependable([]))
588 @depends(eme_modules, target, when=eme_modules)
589 def eme_win32_artifact(modules, target):
590 if 'widevine' in modules and target.kernel == 'WINNT' and target.cpu == 'aarch64':
594 set_config('MOZ_EME_WIN32_ARTIFACT', eme_win32_artifact)
596 option(name='--enable-chrome-format',
597 help='Select FORMAT of chrome files during packaging.',
599 choices=('omni', 'jar', 'flat'),
602 @depends('--enable-chrome-format')
603 def packager_format(value):
606 set_config('MOZ_PACKAGER_FORMAT', packager_format)
608 @depends(host, build_project)
609 def jar_maker_format(host, build_project):
610 # Multilocales for mobile/android use the same mergedirs for all locales,
611 # so we can't use symlinks for those builds.
612 if host.os == 'WINNT' or build_project == 'mobile/android':
616 set_config('MOZ_JAR_MAKER_FILE_FORMAT', jar_maker_format)
619 def omnijar_name(toolkit):
620 # Fennec's static resources live in the assets/ folder of the
621 # APK. Adding a path to the name here works because we only
622 # have one omnijar file in the final package (which is not the
624 return 'assets/omni.ja' if toolkit == 'android' else 'omni.ja'
626 set_config('OMNIJAR_NAME', omnijar_name)
628 project_flag('MOZ_PLACES',
629 help='Build Places if required',
632 project_flag('MOZ_SERVICES_HEALTHREPORT',
633 help='Build Firefox Health Reporter Service',
634 set_for_old_configure=True,
637 project_flag('MOZ_NORMANDY',
638 help='Enable Normandy recipe runner',
639 set_for_old_configure=True,
642 project_flag('MOZ_SERVICES_SYNC',
643 help='Build Sync Services if required')
645 project_flag('MOZ_ANDROID_HISTORY',
646 help='Enable Android History instead of Places',
649 project_flag('MOZ_DEDICATED_PROFILES',
650 help='Enable dedicated profiles per install',
653 project_flag('MOZ_BLOCK_PROFILE_DOWNGRADE',
654 help='Block users from starting profiles last used by a newer build',
657 @depends('MOZ_PLACES', 'MOZ_ANDROID_HISTORY')
658 def check_places_and_android_history(places, android_history):
659 if places and android_history:
660 die('Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.')
663 option(env='MOZ_TELEMETRY_REPORTING', default=mozilla_official,
664 help='Enable telemetry reporting')
666 set_define('MOZ_TELEMETRY_REPORTING', True, when='MOZ_TELEMETRY_REPORTING')
667 add_old_configure_assignment(
668 'MOZ_TELEMETRY_REPORTING', True, when='MOZ_TELEMETRY_REPORTING')
671 @depends('MOZ_TELEMETRY_REPORTING', milestone.is_nightly, fennec_nightly)
672 def telemetry_on_by_default(reporting, is_nightly, fennec_nightly):
673 return reporting and (is_nightly or fennec_nightly)
676 set_define('MOZ_TELEMETRY_ON_BY_DEFAULT', True, when=telemetry_on_by_default)
680 # ==============================================================
681 option('--enable-gpsd', env='MOZ_GPSD',
682 help='Enable gpsd support')
684 @depends('--enable-gpsd')
688 system_gpsd = pkg_check_modules('MOZ_GPSD', 'libgps >= 3.11',
691 set_config('MOZ_GPSD', depends_if(system_gpsd)(lambda _: True))
693 # Miscellaneous programs
694 # ==============================================================
696 check_prog('TAR', ('gnutar', 'gtar', 'tar'))
697 check_prog('UNZIP', ('unzip',))
698 check_prog('ZIP', ('zip',))
699 check_prog('GN', ('gn',), allow_missing=True)
702 # ==============================================================
703 include('../build/moz.configure/keyfiles.configure')
705 simple_keyfile('Mozilla API')
707 simple_keyfile('Google Location Service API')
709 simple_keyfile('Google Safebrowsing API')
711 id_and_secret_keyfile('Bing API')
713 simple_keyfile('Adjust SDK')
715 id_and_secret_keyfile('Leanplum SDK')
717 simple_keyfile('Pocket API')
720 # WebRender Debugger integration
721 # ==============================================================
723 option('--enable-webrender-debugger',
724 help='Build the websocket debug server in WebRender')
726 set_config('MOZ_WEBRENDER_DEBUGGER',
727 depends_if('--enable-webrender-debugger')(lambda _: True))
729 # Additional system headers defined at the application level
730 # ==============================================================
732 option('--enable-app-system-headers', env='MOZ_APP_SYSTEM_HEADERS',
733 help='Use additional system headers defined in $MOZ_BUILD_APP/app-system-headers.mozbuild')
735 @depends('--enable-app-system-headers')
736 def app_system_headers(value):
740 set_config('MOZ_APP_SYSTEM_HEADERS', app_system_headers)
741 set_define('MOZ_APP_SYSTEM_HEADERS', app_system_headers)
744 # ==============================================================
745 option('--disable-printing', help='Disable printing support')
747 @depends('--disable-printing')
752 set_config('NS_PRINTING', printing)
753 set_define('NS_PRINTING', printing)
754 set_define('NS_PRINT_PREVIEW', printing)
756 # Speech-dispatcher support
757 # ==============================================================
759 def no_speechd_on_non_gtk(toolkit):
763 imply_option('--enable-synth-speechd', no_speechd_on_non_gtk,
764 reason='--enable-default-toolkit')
766 option('--disable-synth-speechd', help='Disable speech-dispatcher support')
768 set_config('MOZ_SYNTH_SPEECHD',
769 depends_if('--disable-synth-speechd')(lambda _: True))
772 # ==============================================================
773 option('--disable-webspeech', help='Disable support for HTML Speech API')
775 @depends('--disable-webspeech')
776 def webspeech(value):
780 set_config('MOZ_WEBSPEECH', webspeech)
781 set_define('MOZ_WEBSPEECH', webspeech)
782 add_old_configure_assignment('MOZ_WEBSPEECH', webspeech)
784 # Speech API test backend
785 # ==============================================================
786 option('--enable-webspeechtestbackend', default=webspeech,
787 help='{Enable|Disable} support for HTML Speech API Test Backend')
789 @depends_if('--enable-webspeechtestbackend')
790 def webspeech_test_backend(value):
793 set_config('MOZ_WEBSPEECH_TEST_BACKEND', webspeech_test_backend)
794 set_define('MOZ_WEBSPEECH_TEST_BACKEND', webspeech_test_backend)
796 # Enable IPDL's "expensive" unit tests
797 # ==============================================================
798 option('--enable-ipdl-tests', help='Enable expensive IPDL tests')
800 set_config('MOZ_IPDL_TESTS',
801 depends_if('--enable-ipdl-tests')(lambda _: True))
804 # ==============================================================
805 option('--disable-skia', help='Disable use of Skia')
807 @depends('--disable-skia')
810 die('--disable-skia is not supported anymore')
814 set_config('MOZ_ENABLE_SKIA', skia)
815 set_define('MOZ_ENABLE_SKIA', skia)
816 set_define('USE_SKIA', skia)
818 option('--enable-skia-pdf', help='Enable Skia PDF')
820 @depends('--enable-skia-pdf', skia, target, milestone)
821 def skia_pdf(value, skia, target, milestone):
822 if value.origin == 'default':
825 if milestone.is_nightly and target.os != 'WINNT':
827 elif value and not skia:
828 die('Cannot enable Skia PDF without enabling Skia')
832 set_config('MOZ_ENABLE_SKIA_PDF', skia_pdf)
833 set_define('MOZ_ENABLE_SKIA_PDF', skia_pdf)
835 option('--enable-skia-pdf-sfntly', help='Enable SFNTLY font subsetting in Skia PDF')
837 @depends('--enable-skia-pdf-sfntly', skia_pdf)
838 def skia_pdf_sfntly(value, skia_pdf):
839 if value.origin == 'default':
841 if value and not skia_pdf:
842 die('Cannot enable SFNTLY subsetting without enabling Skia PDF')
843 if skia_pdf and value:
846 set_config('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
847 set_define('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
849 @depends(skia_pdf_sfntly)
850 def sfntly_includes(skia_pdf_sfntly):
854 '/gfx/sfntly/cpp/src',
858 set_config('SFNTLY_INCLUDES', sfntly_includes)
861 def skia_includes(skia):
870 set_config('SKIA_INCLUDES', skia_includes)
872 option('--with-system-webp',
873 help='Use system libwebp (located with pkgconfig)')
875 system_webp = pkg_check_modules('MOZ_WEBP', 'libwebp >= 1.0.2 libwebpdemux >= 1.0.2',
876 when='--with-system-webp')
878 set_config('MOZ_SYSTEM_WEBP', depends(when=system_webp)(lambda: True))
880 # Build Freetype in the tree
881 # ==============================================================
882 @depends(target, skia_pdf)
883 def tree_freetype(target, skia_pdf):
884 if target.os == 'Android' or (skia_pdf and target.os == 'WINNT'):
887 set_define('MOZ_TREE_FREETYPE', tree_freetype)
888 set_config('MOZ_TREE_FREETYPE', tree_freetype)
889 add_old_configure_assignment('MOZ_TREE_FREETYPE', tree_freetype)
891 set_define('HAVE_FT_BITMAP_SIZE_Y_PPEM', tree_freetype)
892 set_define('HAVE_FT_GLYPHSLOT_EMBOLDEN', tree_freetype)
893 set_define('HAVE_FT_LOAD_SFNT_TABLE', tree_freetype)
895 @depends(freetype2_combined_info, tree_freetype, check_build_environment)
896 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
898 return namespace(cflags=('-I%s/modules/freetype2/include' % build_env.topsrcdir,),
900 if freetype2_combined_info:
901 return freetype2_combined_info
903 set_config('FT2_LIBS', ft2_info.libs)
904 add_old_configure_assignment('FT2_LIBS',
906 add_old_configure_assignment('FT2_CFLAGS',
911 # (partial implementation of Chromium Remote Debugging Protocol)
912 # ==============================================================
914 # See https://firefox-source-docs.mozilla.org/remote/ for more.
915 # The source code lives under ../remote.
917 @depends(target, build_project, milestone)
918 def remote_default(target, project, milestone):
919 # no support for Android
920 if target.os == 'Android':
923 # enable on Firefox Nightly channel only
924 # TODO(ato): https://bugzil.la/1544393
925 return project == 'browser' and milestone.is_nightly
927 option('--enable-cdp', default=remote_default,
928 help='{Enable|Disable} remote agent')
930 @depends('--enable-cdp')
935 set_config('ENABLE_REMOTE_AGENT', remote)
936 set_define('ENABLE_REMOTE_AGENT', remote)
939 # Marionette remote protocol
940 # ==============================================================
942 # Marionette is the Gecko remote protocol used for various remote control,
943 # automation, and testing purposes throughout Gecko, Firefox, and Fennec.
944 # Marionette lives in ../testing/marionette.
946 # Marionette is not really a toolkit feature, as much as a Gecko
947 # engine feature. But it is enabled based on the toolkit, so here it
950 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
953 # For more information, see
954 # https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette.
956 option('--disable-marionette',
957 help='Disable Marionette remote protocol')
959 @depends('--disable-marionette')
960 def marionette(value):
964 set_config('ENABLE_MARIONETTE', marionette)
967 # geckodriver WebDriver implementation
968 # ==============================================================
970 # Turn off geckodriver for build configs we don't handle yet,
971 # but allow --enable-geckodriver to override when compile environment is available.
972 # --disable-tests implies disabling geckodriver.
973 # Disable building in CI
975 @depends('--enable-tests', target, cross_compiling, hazard_analysis, asan, 'MOZ_AUTOMATION')
976 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan, automation):
979 # geckodriver depends on winapi 0.2.8, which doesn't work with AArch64.
980 if target.os == 'WINNT' and target.cpu == 'aarch64':
982 if hazard or target.os == 'Android' or (asan and cross_compile):
988 option('--enable-geckodriver', default=geckodriver_default,
989 when='--enable-compile-environment',
990 help='{Build|Do not build} geckodriver')
992 @depends('--enable-geckodriver', when='--enable-compile-environment')
993 def geckodriver(enabled):
997 set_config('ENABLE_GECKODRIVER', geckodriver)
1001 # ========================================================
1003 def webrtc_default(target):
1004 # Turn off webrtc for OS's we don't handle yet, but allow
1005 # --enable-webrtc to override.
1007 for os_fragment in ('linux', 'mingw', 'android', 'linuxandroid',
1008 'dragonfly', 'freebsd', 'netbsd', 'openbsd',
1010 if target.raw_os.startswith(os_fragment):
1014 if (target.cpu in ('x86_64', 'arm', 'aarch64', 'x86', 'ia64', 'mips32', 'mips64') or
1015 target.cpu.startswith('ppc')):
1018 if os_match and cpu_match:
1022 option('--disable-webrtc', default=webrtc_default,
1023 help='{Enable|Disable} support for WebRTC')
1025 @depends('--disable-webrtc')
1026 def webrtc(enabled):
1030 set_config('MOZ_WEBRTC', webrtc)
1031 set_define('MOZ_WEBRTC', webrtc)
1032 add_old_configure_assignment('MOZ_WEBRTC', webrtc)
1033 set_config('MOZ_SCTP', webrtc)
1034 set_define('MOZ_SCTP', webrtc)
1035 set_config('MOZ_SRTP', webrtc)
1036 set_define('MOZ_SRTP', webrtc)
1037 set_config('MOZ_WEBRTC_SIGNALING', webrtc)
1038 set_define('MOZ_WEBRTC_SIGNALING', webrtc)
1039 set_config('MOZ_PEERCONNECTION', webrtc)
1040 set_define('MOZ_PEERCONNECTION', webrtc)
1041 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1042 # opt/production builds (via MOZ_CRASH())
1043 set_config('MOZ_WEBRTC_ASSERT_ALWAYS', webrtc)
1044 set_define('MOZ_WEBRTC_ASSERT_ALWAYS', webrtc)
1047 # ==============================================================
1049 @depends(target, webrtc)
1050 def raw_media_default(target, webrtc):
1051 if target.os == 'Android':
1056 option('--enable-raw',
1057 default=raw_media_default,
1058 help='{Enable|Disable} support for RAW media')
1060 set_config('MOZ_RAW', depends_if('--enable-raw')(lambda _: True))
1061 set_define('MOZ_RAW', depends_if('--enable-raw')(lambda _: True))
1063 # ASan Reporter Addon
1064 # ==============================================================
1065 option('--enable-address-sanitizer-reporter',
1066 help='Enable Address Sanitizer Reporter Extension')
1068 @depends('--enable-address-sanitizer-reporter')
1069 def enable_asan_reporter(value):
1073 set_config('MOZ_ASAN_REPORTER', enable_asan_reporter)
1074 set_define('MOZ_ASAN_REPORTER', enable_asan_reporter)
1075 add_old_configure_assignment('MOZ_ASAN_REPORTER', enable_asan_reporter)
1078 # ==============================================================
1079 with only_when('--enable-compile-environment'):
1080 @depends(host, target)
1081 def has_elfhack(host, target):
1082 return target.kernel == 'Linux' and host.kernel == 'Linux' and \
1083 target.cpu in ('arm', 'x86', 'x86_64')
1085 @depends('--enable-release')
1086 def default_elfhack(release):
1087 return bool(release)
1089 with only_when(has_elfhack):
1090 option('--disable-elf-hack', default=default_elfhack,
1091 help='{Enable|Disable} elf hacks')
1093 set_config('USE_ELF_HACK',
1094 depends_if('--enable-elf-hack')(lambda _: True))
1097 @depends(check_build_environment)
1098 def idl_roots(build_env):
1099 return namespace(ipdl_root=os.path.join(build_env.topobjdir, 'ipc', 'ipdl'),
1100 webidl_root=os.path.join(build_env.topobjdir,
1102 xpcom_root=os.path.join(build_env.topobjdir,
1103 'xpcom', 'components'))
1105 set_config('WEBIDL_ROOT', idl_roots.webidl_root)
1106 set_config('IPDL_ROOT', idl_roots.ipdl_root)
1107 set_config('XPCOM_ROOT', idl_roots.xpcom_root)
1109 # Proxy bypass protection
1110 # ==============================================================
1112 option('--enable-proxy-bypass-protection',
1113 help='Prevent suspected or confirmed proxy bypasses')
1115 @depends_if('--enable-proxy-bypass-protection')
1116 def proxy_bypass_protection(_):
1119 set_config('MOZ_PROXY_BYPASS_PROTECTION', proxy_bypass_protection)
1120 set_define('MOZ_PROXY_BYPASS_PROTECTION', proxy_bypass_protection)
1123 # ==============================================================
1125 @depends(c_compiler, toolchain_prefix)
1126 def midl_names(c_compiler, toolchain_prefix):
1127 if c_compiler and c_compiler.type in ['gcc', 'clang']:
1130 if toolchain_prefix:
1131 prefixed = tuple('%s%s' % (p, 'widl') for p in toolchain_prefix)
1132 widl = prefixed + widl
1135 return ('midl.exe',)
1137 @depends(target, '--enable-compile-environment')
1138 def check_for_midl(target, compile_environment):
1139 if target.os != 'WINNT':
1142 if compile_environment:
1146 midl = check_prog('MIDL', midl_names, when=check_for_midl, allow_missing=True,
1149 option(env='MIDL_FLAGS', nargs=1, help='Extra flags to pass to MIDL')
1151 @depends('MIDL_FLAGS', c_compiler, target, host, midl,
1152 when=depends(midl, target)(lambda m, t: m and t.kernel == 'WINNT'))
1153 def midl_flags(flags , c_compiler, target, host, midl):
1155 flags = flags[0].split()
1159 if not midl.endswith('widl'):
1165 flags += ['-env', env]
1167 if host.os == 'WINNT':
1168 return flags + ['-cpp_cmd', c_compiler.compiler]
1170 # If cross-compiling and using midl instead of widl, for now, we'll
1171 # assume we can find the Windows version of clang-cl in the PATH.
1172 # It is required because while Wine is able to spawn Linux
1173 # processes from Windows programs(!), the calling program doesn't
1174 # have access to the process output and can't wait for it to
1175 # finish. Midl runs clang-cl as a preprocessor and expects to read
1177 clang_cl_exe = find_program('clang-cl.exe')
1178 if not clang_cl_exe:
1179 die("Cannot find clang-cl.exe")
1180 return flags + ['-cpp_cmd', clang_cl_exe]
1184 'x86': ['--win32', '-m32'],
1185 'x86_64': ['--win64', '-m64'],
1189 set_config('MIDL_FLAGS', midl_flags)
1192 # ==============================================================
1194 option('--disable-accessibility', help='Disable accessibility support')
1196 @depends('--enable-accessibility', check_for_midl, midl, c_compiler)
1197 def accessibility(value, check_for_midl, midl, c_compiler):
1198 enabled = bool(value)
1203 if check_for_midl and not midl:
1204 if c_compiler and c_compiler.type in ('gcc', 'clang'):
1205 die('You have accessibility enabled, but widl could not be found. '
1206 'Add --disable-accessibility to your mozconfig or install widl. '
1207 'See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details.')
1209 die('MIDL could not be found. '
1210 'Building accessibility without MIDL is not supported.')
1215 set_config('ACCESSIBILITY', accessibility)
1216 set_define('ACCESSIBILITY', accessibility)
1217 add_old_configure_assignment('ACCESSIBILITY', accessibility)
1220 # ==============================================================
1222 option('--with-unsigned-addon-scopes',
1223 nargs='+', choices=('app', 'system'),
1224 help='Addon scopes where signature is not required')
1226 @depends('--with-unsigned-addon-scopes')
1227 def unsigned_addon_scopes(scopes):
1229 app='app' in scopes or None,
1230 system='system' in scopes or None,
1233 set_config('MOZ_UNSIGNED_APP_SCOPE', unsigned_addon_scopes.app)
1234 set_config('MOZ_UNSIGNED_SYSTEM_SCOPE', unsigned_addon_scopes.system)
1237 # ==============================================================
1239 @depends(update_channel)
1240 def addon_sideload_allowed_default(update_channel):
1241 if update_channel == 'esr':
1244 option('--allow-addon-sideload', default=addon_sideload_allowed_default,
1245 help='Addon sideloading is allowed')
1247 @depends('--allow-addon-sideload')
1248 def addon_sideload_allowed(value):
1249 allowed = bool(value)
1253 set_config('MOZ_ALLOW_ADDON_SIDELOAD', addon_sideload_allowed)
1255 # Launcher process (Windows only)
1256 # ==============================================================
1259 def launcher_process_default(target):
1260 return target.os == 'WINNT'
1262 option('--enable-launcher-process', default=launcher_process_default,
1263 help='{Enable|Disable} launcher process by default')
1265 @depends('--enable-launcher-process', target)
1266 def launcher(value, target):
1267 enabled = bool(value)
1268 if enabled and target.os != 'WINNT':
1269 die('Cannot enable launcher process on %s', target.os)
1273 set_config('MOZ_LAUNCHER_PROCESS', launcher)
1274 set_define('MOZ_LAUNCHER_PROCESS', launcher)
1276 # llvm-dlltool (Windows only)
1277 # ==============================================================
1279 @depends(build_project, target, '--enable-compile-environment')
1280 def check_for_llvm_dlltool(build_project, target, compile_environment):
1281 if build_project != 'browser':
1284 if target.os != 'WINNT':
1287 return compile_environment
1289 llvm_dlltool = check_prog('LLVM_DLLTOOL', ('llvm-dlltool',),
1290 what='llvm-dlltool', when=check_for_llvm_dlltool,
1291 paths=toolchain_search_path)
1293 @depends(target, when=llvm_dlltool)
1294 def llvm_dlltool_flags(target):
1297 'x86_64': 'i386:x86-64',
1303 set_config('LLVM_DLLTOOL_FLAGS', llvm_dlltool_flags)
1305 # Maintenance service (Windows only)
1306 # ==============================================================
1308 option('--enable-maintenance-service',
1309 when=target_is_windows, default=target_is_windows,
1310 help='{Enable|Disable} building of maintenance service')
1312 set_define('MOZ_MAINTENANCE_SERVICE',
1313 depends_if('--enable-maintenance-service',
1314 when=target_is_windows)(lambda _: True))
1315 set_config('MOZ_MAINTENANCE_SERVICE',
1316 depends_if('--enable-maintenance-service',
1317 when=target_is_windows)(lambda _: True))
1319 # Update agent (currently Windows only)
1320 # This is an independent task that runs on a schedule to
1321 # check for, download, and install updates.
1322 # ==============================================================
1324 option('--enable-update-agent',
1325 when=target_is_windows, default=False,
1326 help='{Enable|Disable} building update agent')
1328 set_define('MOZ_UPDATE_AGENT',
1329 depends_if('--enable-update-agent',
1330 when=target_is_windows)(lambda _: True))
1332 set_config('MOZ_UPDATE_AGENT',
1333 depends_if('--enable-update-agent',
1334 when=target_is_windows)(lambda _: True))
1336 # BITS download (Windows only)
1337 # ==============================================================
1339 option('--enable-bits-download',
1340 when=target_is_windows, default=target_is_windows,
1341 help='{Enable|Disable} building BITS download support')
1343 set_define('MOZ_BITS_DOWNLOAD',
1344 depends_if('--enable-bits-download',
1345 when=target_is_windows)(lambda _: True))
1346 set_config('MOZ_BITS_DOWNLOAD',
1347 depends_if('--enable-bits-download',
1348 when=target_is_windows)(lambda _: True))
1350 # Bundled fonts on desktop platform
1351 # ==============================================================
1354 def bundled_fonts_default(target):
1355 return target.os == 'WINNT' or target.kernel == 'Linux'
1357 @depends(build_project)
1358 def allow_bundled_fonts(project):
1359 return project == 'browser' or project == 'comm/mail'
1361 option('--enable-bundled-fonts', default=bundled_fonts_default,
1362 when=allow_bundled_fonts,
1363 help='{Enable|Disable} support for bundled fonts on desktop platforms')
1365 set_define('MOZ_BUNDLED_FONTS',
1366 depends_if('--enable-bundled-fonts', when=allow_bundled_fonts)(lambda _: True))
1368 # Verify MAR signatures
1369 # ==============================================================
1371 option('--disable-verify-mar', help='Disable verifying MAR signatures')
1373 set_define('MOZ_VERIFY_MAR_SIGNATURE',
1374 depends_if('--enable-verify-mar')(lambda _: True))
1375 set_config('MOZ_VERIFY_MAR_SIGNATURE',
1376 depends_if('--enable-verify-mar')(lambda _: True))
1379 # ==============================================================
1381 option('--enable-tasktracer', help='Enable TaskTracer')
1383 set_define('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(lambda _: True))
1384 set_config('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(lambda _: True))
1387 # ==============================================================
1390 def reflow_perf(debug):
1394 option('--enable-reflow-perf',
1395 default=reflow_perf,
1396 help='{Enable|Disable} reflow performance tracing')
1398 # The difference in conditions here comes from the initial implementation
1399 # in old-configure, which was unexplained there as well.
1400 set_define('MOZ_REFLOW_PERF', depends_if('--enable-reflow-perf')(lambda _: True))
1401 set_define('MOZ_REFLOW_PERF_DSP', reflow_perf)
1404 # ==============================================================
1407 def layout_debugger(debug):
1411 option('--enable-layout-debugger',
1412 default=layout_debugger,
1413 help='{Enable|Disable} layout debugger')
1415 set_config('MOZ_LAYOUT_DEBUGGER', True, when='--enable-layout-debugger')
1416 set_define('MOZ_LAYOUT_DEBUGGER', True, when='--enable-layout-debugger')
1419 # Shader Compiler for Windows (and MinGW Cross Compile)
1420 # ==============================================================
1422 with only_when(compile_environment):
1423 fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
1424 (lambda t: t.kernel == 'WINNT'),
1431 with only_when(compile_environment):
1432 option('--with-system-libvpx',
1433 help='Use system libvpx (located with pkgconfig)')
1435 with only_when('--with-system-libvpx'):
1436 vpx = pkg_check_modules('MOZ_LIBVPX', 'vpx >= 1.8.0')
1438 check_header('vpx/vpx_decoder.h', flags=vpx.cflags, onerror=lambda: die(
1439 "Couldn't find vpx/vpx_decoder.h, which is required to build "
1440 "with system libvpx. Use --without-system-libvpx to build "
1441 "with in-tree libvpx."))
1443 check_symbol('vpx_codec_dec_init_ver', flags=vpx.libs, onerror=lambda: die(
1444 "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1448 set_config('MOZ_SYSTEM_LIBVPX', True)
1451 @depends('--with-system-libvpx', target, gnu_as)
1452 def in_tree_vpx(system_libvpx, target, gnu_as):
1456 use_yasm = (target.cpu in ('x86', 'x86_64')) or None
1458 arm_asm = (target.cpu == 'arm' and gnu_as) or None
1462 if target.kernel == 'WINNT':
1463 need_yasm = Version('1.1')
1465 return namespace(arm_asm=arm_asm, use_yasm=use_yasm, need_yasm=need_yasm)
1468 # Building with -mfpu=neon requires either the "softfp" or the
1469 # "hardfp" ABI. Depending on the compiler's default target, and the
1470 # CFLAGS, the default ABI might be neither, in which case it is the
1472 # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
1473 # we can safely mix code built with both ABIs. So, if we detect
1474 # that compiling uses the "softfloat" ABI, force the use of the
1475 # "softfp" ABI instead.
1476 # Confusingly, the __SOFTFP__ preprocessor variable indicates the
1477 # "softfloat" ABI, not the "softfp" ABI.
1478 # Note: VPX_ASFLAGS is also used in CFLAGS.
1479 softfp = cxx_compiler.try_compile(body='''
1481 #error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
1482 #endif''', when=in_tree_vpx.arm_asm)
1485 @depends(in_tree_vpx, softfp, target)
1486 def vpx_as_flags(vpx, softfp, target):
1488 if vpx and vpx.arm_asm:
1489 # These flags are a lie; they're just used to enable the requisite
1490 # opcodes; actual arch detection is done at runtime.
1491 flags = ['-march=armv7-a', '-mfpu=neon']
1493 flags.append('-mfloat-abi=softfp')
1494 elif vpx and vpx.use_yasm and target.os != 'WINNT' and target.cpu != 'x86_64':
1499 set_config('VPX_USE_YASM', in_tree_vpx.use_yasm)
1500 set_config('VPX_ASFLAGS', vpx_as_flags)
1506 with only_when(compile_environment):
1507 option('--with-system-jpeg', nargs='?',
1508 help='Use system libjpeg (installed at given prefix)')
1510 @depends_if('--with-system-jpeg')
1511 def jpeg_flags(value):
1514 cflags=('-I%s/include' % value[0],),
1515 ldflags=('-L%s/lib' % value[0], '-ljpeg'),
1518 ldflags=('-ljpeg',),
1521 with only_when('--with-system-jpeg'):
1522 check_symbol('jpeg_destroy_compress', flags=jpeg_flags.ldflags,
1523 onerror=lambda: die('--with-system-jpeg requested but symbol '
1524 'jpeg_destroy_compress not found.'))
1526 c_compiler.try_compile(
1533 #if JPEG_LIB_VERSION < 62
1534 #error Insufficient JPEG library version
1537 flags=jpeg_flags.cflags,
1538 check_msg='for sufficient jpeg library version',
1539 onerror=lambda: die('Insufficient JPEG library version for '
1540 '--with-system-jpeg (62 required)'),
1543 c_compiler.try_compile(
1550 #ifndef JCS_EXTENSIONS
1551 #error libjpeg-turbo JCS_EXTENSIONS required
1554 flags=jpeg_flags.cflags,
1555 check_msg='for sufficient libjpeg-turbo JCS_EXTENSIONS',
1556 onerror=lambda: die('libjpeg-turbo JCS_EXTENSIONS required for '
1557 '--with-system-jpeg'),
1560 set_config('MOZ_JPEG_CFLAGS', jpeg_flags.cflags)
1561 set_config('MOZ_JPEG_LIBS', jpeg_flags.ldflags)
1563 @depends('--with-system-jpeg', target)
1564 def in_tree_jpeg(system_jpeg, target):
1571 if target.kernel == 'Darwin':
1572 if target.cpu == 'x86':
1573 flags = ('-DPIC', '-DMACHO')
1574 elif target.cpu == 'x86_64':
1575 flags = ('-D__x86_64__', '-DPIC', '-DMACHO')
1576 elif target.kernel == 'WINNT':
1577 if target.cpu == 'x86':
1578 flags = ('-DPIC', '-DWIN32')
1579 elif target.cpu == 'x86_64':
1580 flags = ('-D__x86_64__', '-DPIC', '-DWIN64', '-DMSVC')
1581 elif target.cpu == 'arm':
1582 flags = ('-march=armv7-a', '-mfpu=neon')
1583 elif target.cpu == 'aarch64':
1584 flags = ('-march=armv8-a',)
1585 elif target.cpu == 'mips32':
1586 flags = ('-mdspr2',)
1587 elif target.cpu == 'x86':
1588 flags = ('-DPIC', '-DELF')
1589 elif target.cpu == 'x86_64':
1590 flags = ('-D__x86_64__', '-DPIC', '-DELF')
1592 if target.cpu in ('x86', 'x86_64'):
1594 if target.kernel == 'Linux' and target.os == 'GNU':
1595 need_yasm = Version('1.0.1')
1597 need_yasm = Version('1.1')
1599 return namespace(flags=flags, use_yasm=use_yasm, need_yasm=need_yasm)
1601 set_config('LIBJPEG_TURBO_USE_YASM', in_tree_jpeg.use_yasm)
1602 set_config('LIBJPEG_TURBO_ASFLAGS', in_tree_jpeg.flags)
1606 # ==============================================================
1607 with only_when(compile_environment):
1609 def libav_fft(target):
1611 if target.kernel == 'WINNT' and target.cpu == 'x86':
1612 flags = ['-DPIC', '-DWIN32']
1613 elif target.kernel == 'WINNT' and target.cpu == 'aarch64':
1614 flags = ['-DPIC', '-DWIN64']
1615 elif target.cpu == 'x86_64':
1616 if target.kernel == 'Darwin':
1617 flags = ['-D__x86_64__', '-DPIC', '-DMACHO']
1618 elif target.kernel == 'WINNT':
1619 flags = ['-D__x86_64__', '-DPIC', '-DWIN64', '-DMSVC']
1621 flags = ['-D__x86_64__', '-DPIC', '-DELF']
1623 if target.kernel == 'Linux' and target.os == 'GNU':
1624 need_yasm = Version('1.0.1')
1626 need_yasm = Version('1.1')
1627 return namespace(flags=flags, need_yasm=need_yasm)
1630 set_config('MOZ_LIBAV_FFT', depends(when=libav_fft)(lambda: True))
1631 set_define('MOZ_LIBAV_FFT', depends(when=libav_fft)(lambda: True))
1632 set_config('LIBAV_FFT_ASFLAGS', libav_fft.flags)
1635 # FFmpeg's ffvpx configuration
1636 # ==============================================================
1637 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
1638 with only_when(compile_environment | artifact_builds):
1639 @depends_if(yasm_version)
1640 def yasm_has_avx2(yasm_version):
1641 return yasm_version >= '1.2'
1644 set_config('YASM_HAS_AVX2', yasm_has_avx2)
1647 @depends(yasm_has_avx2, libav_fft, vpx_as_flags, target)
1648 def ffvpx(yasm_has_avx2, libav_fft, vpx_as_flags, target):
1649 enable = flac_only = use_yasm = False
1651 if target.cpu in ('x86', 'x86_64') or \
1652 target.cpu == 'aarch64' and target.kernel == 'WINNT':
1654 if libav_fft and libav_fft.flags:
1656 flags.extend(libav_fft.flags)
1657 if target.kernel == 'WINNT':
1658 if target.cpu == 'x86':
1659 # 32-bit windows need to prefix symbols with an underscore.
1660 flags.extend(('-DPREFIX', '-Pconfig_win32.asm'))
1661 elif target.cpu == 'aarch64':
1664 flags.append('-Pconfig_win64.asm')
1665 elif target.kernel == 'Darwin':
1666 # 32/64-bit macosx assemblers need to prefix symbols with an
1668 flags.extend(('-DPREFIX', '-Pconfig_darwin64.asm'))
1671 flags.append('-Pconfig_unix64.asm')
1674 elif target.cpu in ('arm', 'aarch64') and \
1675 target.kernel not in ('WINNT', 'Darwin'):
1676 enable = flac_only = True
1678 flags.extend(vpx_as_flags)
1681 # default disabled components
1682 flags.append('-Pdefaults_disabled.asm')
1683 if not yasm_has_avx2:
1686 '-DHAVE_AVX2_INTERNAL=0',
1687 '-DHAVE_AVX2_EXTERNAL=0',
1693 flac_only=flac_only,
1698 set_config('MOZ_FFVPX', True, when=ffvpx.enable)
1699 set_define('MOZ_FFVPX', True, when=ffvpx.enable)
1700 set_config('MOZ_FFVPX_AUDIOONLY', True, when=ffvpx.flac_only)
1701 set_define('MOZ_FFVPX_AUDIOONLY', True, when=ffvpx.flac_only)
1702 set_config('FFVPX_ASFLAGS', ffvpx.flags)
1703 set_config('FFVPX_USE_YASM', True, when=ffvpx.use_yasm)
1706 @depends(yasm_version, in_tree_vpx.need_yasm, in_tree_jpeg.use_yasm,
1707 libav_fft.need_yasm, ffvpx.use_yasm)
1708 @imports(_from='__builtin__', _import='sorted')
1709 def valid_yasm_version(yasm_version, for_vpx, for_jpeg, for_libav,
1711 # Note: the default for for_ffvpx above only matters for unit tests.
1718 requires = {k: v for (k, v) in requires.items() if v}
1719 if requires and not yasm_version:
1720 items = sorted(requires.keys())
1722 what = ' and '.join((', '.join(items[:-1]), items[-1]))
1725 die('Yasm is required to build with %s, but you do not appear to have '
1726 'Yasm installed.' % what)
1728 versioned = {k: v for (k, v) in requires.items() if v is not True}
1729 by_version = sorted(versioned.items(), key=lambda x: x[1])
1731 what, version = by_version[-1]
1732 if yasm_version < version:
1733 die('Yasm version %s or greater is required to build with %s.'
1737 # ANGLE OpenGL->D3D translator for WebGL
1738 # ==============================================================
1740 with only_when(compile_environment & target_is_windows):
1741 def d3d_compiler_dll_result(value):
1743 return 'provided by the OS'
1746 @depends(target, valid_windows_sdk_dir, fxc)
1747 @checking('for D3D compiler DLL', d3d_compiler_dll_result)
1749 def d3d_compiler_dll(target, windows_sdk_dir, fxc):
1752 }.get(target.cpu, target.cpu)
1754 name = 'd3dcompiler_47.dll'
1756 if target.cpu == 'aarch64':
1757 # AArch64 Windows comes with d3dcompiler_47.dll installed
1758 return namespace(name=name, path=None)
1761 path = os.path.join(windows_sdk_dir.path, 'Redist', 'D3D', suffix, name)
1762 error_extra = 'in Windows SDK at {}'.format(windows_sdk_dir.path)
1764 path = os.path.join(os.path.dirname(fxc), name)
1765 error_extra = 'alongside FXC at {}'.format(fxc)
1767 if os.path.exists(path):
1768 return namespace(name=name, path=path)
1769 die('Could not find {} {}'.format(name, error_extra))
1772 set_config('MOZ_ANGLE_RENDERER', True)
1773 set_config('MOZ_D3DCOMPILER_VISTA_DLL', d3d_compiler_dll.name,
1774 when=d3d_compiler_dll.path)
1775 set_config('MOZ_D3DCOMPILER_VISTA_DLL_PATH', d3d_compiler_dll.path)
1777 # Remoting protocol support
1778 # ==============================================================
1781 def has_remote(toolkit):
1782 if toolkit in ('gtk', 'windows', 'cocoa'):
1785 set_config('MOZ_HAS_REMOTE', has_remote)
1786 set_define('MOZ_HAS_REMOTE', has_remote)
1788 # RLBox Library Sandboxing wasm support
1789 # ==============================================================
1791 def wasm_sandboxing_libraries():
1792 return ('graphite', 'ogg',)
1794 option('--with-wasm-sandboxed-libraries',
1795 env='WASM_SANDBOXED_LIBRARIES',
1796 help='Enable wasm sandboxing for the selected libraries',
1798 choices=dependable(wasm_sandboxing_libraries))
1800 @depends('--with-wasm-sandboxed-libraries')
1801 def requires_wasm_sandboxing(libraries):
1805 set_config('MOZ_USING_WASM_SANDBOXING', requires_wasm_sandboxing)
1806 set_define('MOZ_USING_WASM_SANDBOXING', requires_wasm_sandboxing)
1808 with only_when(requires_wasm_sandboxing & compile_environment):
1809 lucetc = check_prog('LUCETC', ['lucetc'],
1810 paths=toolchain_search_path)
1812 option('--with-wasi-sysroot',
1815 help='Path to wasi sysroot for wasm sandboxing')
1817 @depends('--with-wasi-sysroot', mozbuild_state_path)
1819 def wasi_sysroot(wasi_sysroot, mozbuild_state_path):
1820 if not wasi_sysroot:
1821 sysroot = os.path.join(mozbuild_state_path, 'wasi-sysroot', 'share',
1823 if os.path.isdir(sysroot):
1825 die('Cannot find a wasi sysroot. Install the sysroot at %s or set '
1826 '--with-wasi-sysroot.' % sysroot)
1828 wasi_sysroot = wasi_sysroot[0]
1829 if not os.path.isdir(wasi_sysroot):
1830 die('Argument to --with-wasi-sysroot must be a directory')
1831 if not os.path.isabs(wasi_sysroot):
1832 die('Argument to --with-wasi-sysroot must be an absolute path')
1836 set_config('WASI_SYSROOT', wasi_sysroot)
1839 def wasm_compiler_with_flags(wasm_compiler, provided_wasm_compiler, sysroot,
1843 if provided_wasm_compiler:
1845 list(compiler_wrapper or []) +
1846 provided_wasm_compiler.wrapper + [provided_wasm_compiler.program]
1847 + provided_wasm_compiler.flags + ['--sysroot=%s' % sysroot])
1850 list(compiler_wrapper or []) +
1852 ['--target=wasm32-wasi', '--sysroot=%s' % sysroot])
1854 option(env='WASM_CC', nargs=1, help='Path to the C->WASM compiler')
1855 provided_wasm_cc = provided_program('WASM_CC')
1856 wasm_cc = check_prog('_WASM_CC', ['clang'], input=provided_wasm_cc.program,
1857 paths=toolchain_search_path, allow_missing=True,
1858 what='the C->WASM compiler')
1859 @depends(wasm_cc, provided_wasm_cc, wasi_sysroot, compiler_wrapper)
1860 def wasm_cc_with_flags(wasm_cc, provided_wasm_cc, wasi_sysroot,
1862 return wasm_compiler_with_flags(wasm_cc, provided_wasm_cc, wasi_sysroot,
1864 set_config('WASM_CC', wasm_cc_with_flags)
1866 option(env='WASM_CXX', nargs=1, help='Path to the C++->WASM compiler')
1867 provided_wasm_cxx = provided_program('WASM_CXX')
1868 wasm_cxx = check_prog(
1869 '_WASM_CXX', ['clang++'], input=provided_wasm_cxx.program,
1870 paths=toolchain_search_path, allow_missing=True,
1871 what='the C++->WASM compiler')
1872 @depends(wasm_cxx, provided_wasm_cxx, wasi_sysroot, compiler_wrapper)
1873 def wasm_cxx_with_flags(wasm_cxx, provided_wasm_cxx, wasi_sysroot,
1875 return wasm_compiler_with_flags(wasm_cxx, provided_wasm_cxx, wasi_sysroot,
1878 set_config('WASM_CXX', wasm_cxx_with_flags)
1881 wasm_compile_flags = dependable(['-fno-exceptions', '-fno-strict-aliasing', '-Qunused-arguments'])
1882 option(env='WASM_CFLAGS', nargs=1, help='Options to pass to WASM_CC')
1883 @depends('WASM_CFLAGS', wasm_compile_flags)
1884 def wasm_cflags(value, wasm_compile_flags):
1886 return wasm_compile_flags + value
1888 return wasm_compile_flags
1889 set_config('WASM_CFLAGS', wasm_cflags)
1891 option(env='WASM_CXXFLAGS', nargs=1, help='Options to pass to WASM_CXX')
1892 @depends('WASM_CXXFLAGS', wasm_compile_flags)
1893 def wasm_cxxflags(value, wasm_compile_flags):
1895 return wasm_compile_flags + value
1897 return wasm_compile_flags
1898 set_config('WASM_CXXFLAGS', wasm_cxxflags)
1900 option(env='WASM_LDFLAGS', nargs=1,
1901 help='Options to pass when linking wasm modules')
1902 @depends('WASM_LDFLAGS')
1903 def wasm_ldflags(value):
1906 set_config('WASM_LDFLAGS', wasm_ldflags)
1908 # This function is returning "ldflags" that lucetc will use when invoking
1909 # the linker, but really lucetc is going to be invoking the compiler, since
1910 # the compiler handles lots of details for us (like finding the linker in
1911 # cross-compilation scenarios).
1913 def lucetc_ldflags(target):
1914 if target.kernel == 'Linux':
1920 if target.kernel == 'Darwin':
1924 '-Wl,-export_dynamic',
1925 '-Wl,-undefined,dynamic_lookup',
1929 set_config('LUCETC_LDFLAGS', lucetc_ldflags)
1931 # Re-using the Rust target triple here is not exactly correct, but it is an
1932 # excellent approximation for the platforms we currently support
1933 set_config('LUCETC_TARGET', rust_target_triple)
1936 @depends('--with-wasm-sandboxed-libraries', target)
1937 def wasm_sandboxing(libraries, target):
1941 # Wasm sandboxing is only enabled on specific targets.
1942 if not (target.cpu in ('x86_64',) and \
1943 (target.kernel == 'Linux' and target.os != 'Android') or \
1944 target.kernel == 'Darwin'):
1945 die('wasm sandboxing is only enabled on x86-64 Linux and Mac')
1947 return namespace(**{name: True for name in libraries})
1950 def wasm_sandboxing_config_defines():
1951 for lib in wasm_sandboxing_libraries():
1952 set_config('MOZ_WASM_SANDBOXING_%s' % lib.upper(), getattr(wasm_sandboxing, lib))
1953 set_define('MOZ_WASM_SANDBOXING_%s' % lib.upper(), getattr(wasm_sandboxing, lib))
1955 wasm_sandboxing_config_defines()
1958 # new XULStore implementation
1959 # ==============================================================
1962 def new_xulstore(milestone):
1963 if milestone.is_nightly:
1966 set_config('MOZ_NEW_XULSTORE', True, when=new_xulstore)
1967 set_define('MOZ_NEW_XULSTORE', True, when=new_xulstore)
1970 # new Notification Store implementation
1971 # ==============================================================
1974 def new_notification_store(milestone):
1975 if milestone.is_nightly:
1978 set_config('MOZ_NEW_NOTIFICATION_STORE', True, when=new_notification_store)
1979 set_define('MOZ_NEW_NOTIFICATION_STORE', True, when=new_notification_store)
1982 # Glean SDK Integration Crate
1983 # ==============================================================
1986 def glean(milestone):
1987 if milestone.is_nightly:
1990 set_config('MOZ_GLEAN', True, when=glean)
1991 set_define('MOZ_GLEAN', True, when=glean)
1995 # New Firefox Accounts client implemented in Rust
1996 # ===============================================
1998 @depends(milestone, target)
1999 def rust_fxa_client(milestone, target):
2000 if milestone.is_nightly and target.os != 'Android':
2003 set_config('MOZ_RUST_FXA_CLIENT', True, when=rust_fxa_client)
2004 set_define('MOZ_RUST_FXA_CLIENT', True, when=rust_fxa_client)
2009 # ==============================================================
2011 check_prog('DUMP_SYMS', ['dump_syms'], allow_missing=True, paths=toolchain_search_path,
2012 when=compile_environment & target_is_windows)
2015 check_prog('PDBSTR', ['pdbstr.exe'], allow_missing=True, paths=toolchain_search_path,
2016 when=compile_environment & target_is_windows)
2018 @depends('MOZ_AUTOMATION', c_compiler)
2019 def allow_missing_winchecksec(automation, c_compiler):
2022 if c_compiler and c_compiler.type != 'clang-cl':
2025 check_prog('WINCHECKSEC', ['winchecksec.exe', 'winchecksec'], paths=toolchain_search_path,
2026 allow_missing=allow_missing_winchecksec,
2027 when=compile_environment & target_is_windows)
2030 @depends(target, build_project)
2031 def forkserver_default(target, build_project):
2032 return build_project == 'browser' and \
2033 ((target.os == 'GNU' and target.kernel == 'Linux') or \
2034 target.os == 'FreeBSD')
2036 option('--enable-forkserver', default=forkserver_default,
2037 env='MOZ_ENABLE_FORKSERVER', help='{Enable|Disable} fork server')
2039 @depends('--enable-forkserver', target)
2040 def forkserver_flag(value, target):
2041 if target.os == 'Android' or \
2042 (target.os == 'GNU' and target.kernel == 'Linux') or \
2043 target.os == 'FreeBSD':
2047 set_config('MOZ_ENABLE_FORKSERVER', forkserver_flag)
2048 set_define('MOZ_ENABLE_FORKSERVER', forkserver_flag, forkserver_flag)
2050 # new cert storage implementation
2051 # ==============================================================
2052 option('--disable-new-cert-storage', env='MOZ_NEW_CERT_STORAGE',
2053 help='{Enable|Disable} new certificate storage')
2055 set_config('MOZ_NEW_CERT_STORAGE', True, when='--enable-new-cert-storage')
2056 set_define('MOZ_NEW_CERT_STORAGE', True, when='--enable-new-cert-storage')
2059 # ==============================================================
2061 with only_when(compile_environment & target_is_linux):
2062 # Check if we need to use the breakpad_getcontext fallback.
2063 getcontext = check_symbol('getcontext')
2064 set_config('HAVE_GETCONTEXT', getcontext)
2065 set_define('HAVE_GETCONTEXT', getcontext)
2068 # Enable or disable the default browser agent, which monitors the user's default
2069 # browser setting on Windows.
2070 # ==============================================================================
2073 def default_browser_agent_default(target):
2074 return target.os == 'WINNT'
2076 option('--enable-default-browser-agent', default=default_browser_agent_default,
2077 help='{Enable|Disable} building the default browser agent')
2079 @depends('--enable-default-browser-agent', when=target_is_windows)
2080 def default_agent_flag(enabled):
2084 set_config('MOZ_DEFAULT_BROWSER_AGENT', default_agent_flag)
2088 option('--with-system-nss', help='Use system NSS')
2090 imply_option('--with-system-nspr', True, when='--with-system-nss')
2092 nss_pkg = pkg_check_modules('NSS', 'nss >= 3.53', when='--with-system-nss', config=False)
2094 set_config('MOZ_SYSTEM_NSS', True, when='--with-system-nss')
2096 @depends(nss_pkg, check_build_environment)
2097 def nss_config(nss_pkg, build_env):
2098 cflags = ['-I%s' % os.path.join(build_env.dist, 'include', 'nss')]
2101 cflags = list(nss_pkg.cflags) + cflags
2103 return namespace(cflags=cflags, libs=libs)
2105 set_config('NSS_CFLAGS', nss_config.cflags)
2106 set_config('NSS_LIBS', nss_config.libs)
2107 add_old_configure_assignment('NSS_CFLAGS', nss_config.cflags)