Bug 1564761 [wpt PR 17620] - Document::CheckComplete should be nop when called from...
[gecko.git] / toolkit / moz.configure
blob1637dd8575e8157d2822bc3efd5f42bd289a38a8
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)
9 @dependable
10 @imports(_from='mozbuild.shellutil', _import='quote')
11 @imports('__sandbox__')
12 def all_configure_options():
13     result = []
14     previous = None
15     for option in __sandbox__._options.itervalues():
16         # __sandbox__._options contains items for both option.name and
17         # option.env. But it's also an OrderedDict, meaning both are
18         # consecutive.
19         # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not
20         # interesting.
21         if option == previous or option.env in ('OLD_CONFIGURE', 'MOZCONFIG'):
22             continue
23         previous = option
24         value = __sandbox__._value_for(option)
25         # We only want options that were explicitly given on the command
26         # line, the environment, or mozconfig, and that differ from the
27         # defaults.
28         if (value is not None and value.origin not in ('default', 'implied') and
29                 value != option.default):
30             result.append(__sandbox__._raw_options[option])
31         # We however always include options that are sent to old configure
32         # because we don't know their actual defaults. (Keep the conditions
33         # separate for ease of understanding and ease of removal)
34         elif (option.help == 'Help missing for old configure options' and
35                 option in __sandbox__._raw_options):
36             result.append(__sandbox__._raw_options[option])
38     return quote(*result)
41 set_config('MOZ_CONFIGURE_OPTIONS', all_configure_options)
43 # Profiling
44 # ==============================================================
45 # Some of the options here imply an option from js/moz.configure,
46 # so, need to be declared before the include.
48 option('--enable-jprof', env='MOZ_JPROF',
49        help='Enable jprof profiling tool (needs mozilla/tools/jprof)')
51 @depends('--enable-jprof')
52 def jprof(value):
53     if value:
54         return True
56 set_config('MOZ_JPROF', jprof)
57 set_define('MOZ_JPROF', jprof)
58 imply_option('--enable-profiling', jprof)
60 @depends(target)
61 def gecko_profiler(target):
62     if target.os == 'Android':
63         return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64')
64     elif target.kernel == 'Linux':
65         return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64', 'mips64')
66     return target.os in ('OSX', 'WINNT')
68 @depends(gecko_profiler)
69 def gecko_profiler_define(value):
70     if value:
71         return True
73 set_config('MOZ_GECKO_PROFILER', gecko_profiler_define)
74 set_define('MOZ_GECKO_PROFILER', gecko_profiler_define)
77 # Whether code to parse ELF binaries should be compiled for the Gecko profiler
78 # (for symbol table dumping).
79 @depends(gecko_profiler, target)
80 def gecko_profiler_parse_elf(value, target):
81     # Currently we only want to build this code on Android, in order to dump
82     # symbols from Android system libraries on the device. For other platforms
83     # there exist alternatives that don't require bloating up our binary size.
84     if value and target.os == 'Android':
85         return True
87 set_config('MOZ_GECKO_PROFILER_PARSE_ELF', gecko_profiler_parse_elf)
88 set_define('MOZ_GECKO_PROFILER_PARSE_ELF', gecko_profiler_parse_elf)
90 # enable this by default if the profiler is enabled
91 # Note: also requires jemalloc
92 set_config('MOZ_PROFILER_MEMORY', gecko_profiler_define)
93 set_define('MOZ_PROFILER_MEMORY', gecko_profiler_define)
96 @depends('--enable-debug', milestone, build_project,
97          # Artifact builds are included because the downloaded artifacts can
98          # have DMD enabled.
99          when=artifact_builds | depends(when='--enable-replace-malloc')(lambda: True))
100 def dmd_default(debug, milestone, build_project):
101     return bool(build_project == 'browser' and (debug or milestone.is_nightly))
104 option('--enable-dmd', env='MOZ_DMD', default=dmd_default,
105        help='{Enable|Disable} Dark Matter Detector (heap profiler). '
106             'Also enables jemalloc, replace-malloc and profiling')
109 @depends('--enable-dmd')
110 def dmd(value):
111     if value:
112         return True
115 set_config('MOZ_DMD', dmd)
116 set_define('MOZ_DMD', dmd)
117 add_old_configure_assignment('MOZ_DMD', dmd)
118 imply_option('--enable-profiling', dmd)
119 imply_option('--enable-jemalloc', dmd, when=compile_environment)
120 imply_option('--enable-replace-malloc', dmd, when=compile_environment)
122 # ALSA cubeb backend
123 # ==============================================================
124 option('--enable-alsa', env='MOZ_ALSA',
125        help='Enable ALSA audio backend.')
127 alsa = pkg_check_modules('MOZ_ALSA', 'alsa', when='--enable-alsa')
129 set_config('MOZ_ALSA', depends_if(alsa)(lambda _: True))
130 set_define('MOZ_ALSA', depends_if(alsa)(lambda _: True))
132 # JACK cubeb backend
133 # ==============================================================
134 option('--enable-jack', env='MOZ_JACK',
135        help='Enable JACK audio backend.')
137 jack = pkg_check_modules('MOZ_JACK', 'jack', when='--enable-jack')
139 set_config('MOZ_JACK', depends_if(jack)(lambda _: True))
140 set_define('MOZ_JACK', depends_if(jack)(lambda _: True))
142 # PulseAudio cubeb backend
143 # ==============================================================
144 @depends(target)
145 def pulseaudio_default(target):
146     return target.os not in ('WINNT', 'OSX', 'iOS', 'Android', 'OpenBSD')
148 option('--enable-pulseaudio', env='MOZ_PULSEAUDIO', default=pulseaudio_default,
149        help='{Enable|Disable} PulseAudio audio backend.')
151 pulseaudio = pkg_check_modules('MOZ_PULSEAUDIO', 'libpulse', when='--enable-pulseaudio')
153 set_config('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
154 set_define('MOZ_PULSEAUDIO', depends_if(pulseaudio)(lambda _: True))
156 # AudioUnit cubeb Rust backend
157 # ==============================================================
158 @depends(target)
159 def enable_audiounit_rust(target):
160     return target.os == 'OSX' and target.kernel == 'Darwin'
162 set_config('MOZ_AUDIOUNIT_RUST', True, when=enable_audiounit_rust)
163 set_define('MOZ_AUDIOUNIT_RUST', True, when=enable_audiounit_rust)
165 # Javascript engine
166 # ==============================================================
167 include('../js/moz.configure')
170 # NodeJS
171 # ==============================================================
172 include('../build/moz.configure/node.configure')
174 # L10N
175 # ==============================================================
176 option('--with-l10n-base', nargs=1, env='L10NBASEDIR',
177        help='Path to l10n repositories')
179 @depends('--with-l10n-base', 'MOZ_AUTOMATION', target, check_build_environment)
180 @imports(_from='os.path', _import='isdir')
181 @imports(_from='os.path', _import='expanduser')
182 @imports(_from='os', _import='environ')
183 def l10n_base(value, automation, target, build_env):
184     if value:
185         path = value[0]
186         if not isdir(path):
187             die("Invalid value --with-l10n-base, %s doesn't exist", path)
188     elif automation:
189         if target.os == 'Android':
190             path = os.path.join(build_env.topobjdir, '..', '..', 'l10n-central')
191         else:
192             path = os.path.join(build_env.topobjdir, '..', '..', 'l10n')
193     else:
194         path = os.path.join(
195             environ.get(
196                 'MOZBUILD_STATE_PATH',
197                 expanduser(os.path.join('~', '.mozbuild'))),
198             'l10n-central')
199     return os.path.realpath(os.path.abspath(path))
201 set_config('L10NBASEDIR', l10n_base)
204 # Default toolkit
205 # ==============================================================
206 @depends(target)
207 def toolkit_choices(target):
208     if target.os == 'WINNT':
209         return ('cairo-windows',)
210     elif target.os == 'OSX':
211         return ('cairo-cocoa',)
212     elif target.os == 'iOS':
213         return ('cairo-uikit',)
214     elif target.os == 'Android':
215         return ('cairo-android',)
216     else:
217         return ('cairo-gtk3', 'cairo-gtk3-wayland')
219 @depends(toolkit_choices)
220 def toolkit_default(choices):
221     return choices[0]
223 option('--enable-default-toolkit', nargs=1,
224        choices=toolkit_choices, default=toolkit_default,
225        help='Select default toolkit')
227 @depends_if('--enable-default-toolkit')
228 def full_toolkit(value):
229     return value[0]
231 @depends(full_toolkit)
232 def toolkit(toolkit):
233     if toolkit == 'cairo-gtk3-wayland':
234         widget_toolkit = 'gtk3'
235     else:
236         widget_toolkit = toolkit.replace('cairo-', '')
237     return widget_toolkit
239 set_config('MOZ_WIDGET_TOOLKIT', toolkit)
240 add_old_configure_assignment('MOZ_WIDGET_TOOLKIT', toolkit)
242 @depends(toolkit)
243 def toolkit_define(toolkit):
244     if toolkit == 'gtk3':
245         toolkit = 'gtk'
246     if toolkit != 'windows':
247         return 'MOZ_WIDGET_%s' % toolkit.upper()
249 set_define(toolkit_define, True)
251 @depends(toolkit)
252 def toolkit_gtk(toolkit):
253     return toolkit == 'gtk3'
255 set_config('MOZ_X11', True, when=toolkit_gtk)
256 set_define('MOZ_X11', True, when=toolkit_gtk)
257 add_old_configure_assignment('MOZ_X11', True, when=toolkit_gtk)
259 # Wayland support
260 # ==============================================================
261 wayland_headers = pkg_check_modules(
262     'MOZ_WAYLAND', 'gtk+-wayland-3.0 >= 3.10 xkbcommon >= 0.4.1 libdrm >= 2.4',
263     allow_missing=depends(full_toolkit)(lambda t: t == 'cairo-gtk3'),
264     when=depends(full_toolkit)(lambda t: t in ('cairo-gtk3', 'cairo-gtk3-wayland')))
267 @depends(wayland_headers, toolkit_gtk, artifact_builds)
268 def wayland_headers(wayland, toolkit_gtk, artifacts):
269     if toolkit_gtk and artifacts:
270         return True
271     return wayland
274 set_config('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True))
275 set_define('MOZ_WAYLAND', depends_if(wayland_headers)(lambda _: True))
277 # GL Provider
278 # ==============================================================
279 option('--with-gl-provider', nargs=1, help='Set GL provider backend type')
281 @depends('--with-gl-provider')
282 def gl_provider(value):
283     if value:
284         return value[0]
286 @depends(gl_provider)
287 def gl_provider_define(provider):
288     if provider:
289         return 'GLContextProvider%s' % provider
291 set_define('MOZ_GL_PROVIDER', gl_provider_define)
293 @depends(gl_provider, wayland_headers, toolkit_gtk)
294 def gl_default_provider(value, wayland, toolkit_gtk):
295     if value:
296         return value
297     elif wayland:
298         return 'EGL'
299     elif toolkit_gtk:
300         return 'GLX'
302 set_config('MOZ_GL_PROVIDER', gl_provider)
303 set_config('MOZ_GL_DEFAULT_PROVIDER', gl_default_provider)
305 @depends(gl_default_provider)
306 def gl_provider_define(provider):
307     if provider:
308         return 'GL_PROVIDER_%s' % provider
310 set_define(gl_provider_define, True)
313 # PDF printing
314 # ==============================================================
315 @depends(toolkit)
316 def pdf_printing(toolkit):
317     if toolkit in ('windows', 'gtk3', 'android'):
318         return True
320 @depends(pdf_printing)
321 def pdf_surface_feature(pdf_printing):
322     if pdf_printing:
323         return '#define CAIRO_HAS_PDF_SURFACE 1'
324     else:
325         # CONFIGURE_SUBST_FILES need explicit empty values.
326         return ''
328 set_config('MOZ_PDF_PRINTING', pdf_printing)
329 set_config('PDF_SURFACE_FEATURE', pdf_surface_feature)
332 # Event loop instrumentation
333 # ==============================================================
334 option(env='MOZ_INSTRUMENT_EVENT_LOOP',
335        help='Force-enable event loop instrumentation')
337 @depends('MOZ_INSTRUMENT_EVENT_LOOP', toolkit)
338 def instrument_event_loop(value, toolkit):
339     if value or (toolkit in ('windows', 'gtk3', 'cocoa', 'android') and
340                  value.origin == 'default'):
341         return True
343 set_config('MOZ_INSTRUMENT_EVENT_LOOP', instrument_event_loop)
344 set_define('MOZ_INSTRUMENT_EVENT_LOOP', instrument_event_loop)
347 # Fontconfig Freetype
348 # ==============================================================
349 option(env='USE_FC_FREETYPE',
350        help='Force-enable the use of fontconfig freetype')
352 @depends('USE_FC_FREETYPE', toolkit)
353 def fc_freetype(value, toolkit):
354     if value or (toolkit == 'gtk3' and
355                  value.origin == 'default'):
356         return True
358 add_old_configure_assignment('USE_FC_FREETYPE', fc_freetype)
360 # Pango
361 # ==============================================================
362 pkg_check_modules('MOZ_PANGO',
363                   'pango >= 1.22.0 pangoft2 >= 1.22.0 pangocairo >= 1.22.0',
364                   when=toolkit_gtk)
366 # Fontconfig
367 # ==============================================================
368 fontconfig_info = pkg_check_modules('_FONTCONFIG', 'fontconfig >= 2.7.0',
369                                     when=fc_freetype)
371 @depends(fc_freetype)
372 def check_for_freetype2(fc_freetype):
373     if fc_freetype:
374         return True
376 # Check for freetype2. Flags are combined with fontconfig flags.
377 freetype2_info = pkg_check_modules('_FT2', 'freetype2 >= 6.1.0',
378                                    when=check_for_freetype2)
380 @depends(fontconfig_info, freetype2_info)
381 def freetype2_combined_info(fontconfig_info, freetype2_info):
382     if not freetype2_info:
383         return
384     if not fontconfig_info:
385         return freetype2_info
386     return namespace(
387         cflags=freetype2_info.cflags + fontconfig_info.cflags,
388         libs=freetype2_info.libs + fontconfig_info.libs,
389     )
391 add_old_configure_assignment('_HAVE_FREETYPE2',
392                              depends_if(freetype2_info)(lambda _: True))
394 # Apple platform decoder support
395 # ==============================================================
396 @depends(toolkit)
397 def applemedia(toolkit):
398     if toolkit in ('cocoa', 'uikit'):
399         return True
401 set_config('MOZ_APPLEMEDIA', applemedia)
402 set_define('MOZ_APPLEMEDIA', applemedia)
403 add_old_configure_assignment('MOZ_APPLEMEDIA', applemedia)
405 # Windows Media Foundation support
406 # ==============================================================
407 option('--disable-wmf',
408        help='Disable support for Windows Media Foundation')
410 @depends('--disable-wmf', target)
411 def wmf(value, target):
412     enabled = bool(value)
413     if value.origin == 'default':
414         # Enable Windows Media Foundation support by default.
415         # Note our minimum SDK version is Windows 7 SDK, so we are (currently)
416         # guaranteed to have a recent-enough SDK to build WMF.
417         enabled = target.os == 'WINNT'
418     if enabled and target.os != 'WINNT':
419         die('Cannot enable Windows Media Foundation support on %s', target.os)
420     if enabled:
421         return True
423 set_config('MOZ_WMF', wmf)
424 set_define('MOZ_WMF', wmf)
426 # FFmpeg H264/AAC Decoding Support
427 # ==============================================================
428 option('--disable-ffmpeg',
429        help='Disable FFmpeg for fragmented H264/AAC decoding')
431 @depends('--disable-ffmpeg', target)
432 def ffmpeg(value, target):
433     enabled = bool(value)
434     if value.origin == 'default':
435         enabled = target.os not in ('Android', 'WINNT')
436     if enabled:
437         return True
439 set_config('MOZ_FFMPEG', ffmpeg)
440 set_define('MOZ_FFMPEG', ffmpeg)
441 imply_option('--enable-fmp4', ffmpeg, '--enable-ffmpeg')
443 # AV1 Video Codec Support
444 # ==============================================================
445 option('--disable-av1',
446         help='Disable av1 video support')
448 @depends('--enable-av1')
449 def av1(value):
450     if value:
451         return True
453 @depends(target, nasm_version, when=av1 & compile_environment)
454 def dav1d_asm(target, nasm_version):
455     if target.os != 'Android':
456         if target.cpu == 'aarch64':
457             return True
458         elif target.cpu in ('x86', 'x86_64'):
459             if nasm_version < '2.13':
460                 die('nasm 2.13 or greater is required for AV1 support. '
461                     'Either install nasm or add --disable-av1 to your configure options.')
462             return True
465 set_config('MOZ_DAV1D_ASM', dav1d_asm)
466 set_define('MOZ_DAV1D_ASM', dav1d_asm)
467 set_config('MOZ_AV1', av1)
468 set_define('MOZ_AV1', av1)
470 # Built-in fragmented MP4 support.
471 # ==============================================================
472 option('--disable-fmp4', env='MOZ_FMP4',
473        help='Disable support for in built Fragmented MP4 parsing')
475 @depends('--disable-fmp4', target, wmf, applemedia)
476 def fmp4(value, target, wmf, applemedia):
477     enabled = bool(value)
478     if value.origin == 'default':
479         # target.os == 'Android' includes all B2G versions
480         enabled = wmf or applemedia or target.os == 'Android'
481     if enabled:
482         return True
484 set_config('MOZ_FMP4', fmp4)
485 set_define('MOZ_FMP4', fmp4)
486 add_old_configure_assignment('MOZ_FMP4', fmp4)
488 @depends(target)
489 def sample_type_is_s16(target):
490     # Use integers over floats for audio on Android regardless of the CPU
491     # architecture, because audio backends for Android don't support floats.
492     # We also use integers on ARM because it's more efficient.
493     if target.os == 'Android' or target.cpu == 'arm':
494         return True
496 @depends(sample_type_is_s16)
497 def sample_type_is_float(t):
498     if not t:
499         return True
501 set_config('MOZ_SAMPLE_TYPE_S16', sample_type_is_s16)
502 set_define('MOZ_SAMPLE_TYPE_S16', sample_type_is_s16)
503 set_config('MOZ_SAMPLE_TYPE_FLOAT32', sample_type_is_float)
504 set_define('MOZ_SAMPLE_TYPE_FLOAT32', sample_type_is_float)
506 set_define('MOZ_VORBIS', sample_type_is_float)
507 set_config('MOZ_VORBIS', sample_type_is_float)
508 set_define('MOZ_TREMOR', sample_type_is_s16)
509 set_config('MOZ_TREMOR', sample_type_is_s16)
511 # OpenMAX IL Decoding Support
512 # ==============================================================
513 option('--enable-openmax',
514        help='Enable OpenMAX IL for video/audio decoding')
516 @depends('--enable-openmax')
517 def openmax(value):
518     enabled = bool(value)
519     if enabled:
520         return True
522 set_config('MOZ_OMX', openmax)
523 set_define('MOZ_OMX', openmax)
525 # EME Support
526 # ==============================================================
527 @depends(target)
528 def eme_choices(target):
529     if (target.kernel in ('Darwin', 'WINNT', 'Linux') and
530         target.os not in ('Android', 'iOS') and
531         target.cpu in ('x86', 'x86_64')):
532         return ('widevine',)
533     if target.kernel == 'WINNT' and target.cpu == 'aarch64':
534         return ('widevine',)
537 # Widevine is enabled by default in desktop browser builds, except
538 # on aarch64 Windows.
539 @depends(build_project, eme_choices, target)
540 def eme_default(build_project, choices, target):
541     if build_project == 'browser':
542         if target.kernel != 'WINNT' or target.cpu != 'aarch64':
543             return choices
546 option('--enable-eme',
547        nargs='+',
548        choices=eme_choices,
549        default=eme_default,
550        when=eme_choices,
551        help='{Enable|Disable} support for Encrypted Media Extensions')
554 @depends('--enable-eme', fmp4, when=eme_choices)
555 def eme(enabled, fmp4):
556     if enabled and enabled.origin != 'default' and not fmp4:
557         die('Encrypted Media Extension support requires '
558             'Fragmented MP4 support')
561 @depends('--enable-eme', when=eme_choices)
562 def eme_modules(value):
563     return value
566 # Fallback to an empty list when eme_choices is empty, setting eme_modules to
567 # None.
568 set_config('MOZ_EME_MODULES', eme_modules | dependable([]))
571 @depends(eme_modules, target, when=eme_modules)
572 def eme_win32_artifact(modules, target):
573     if 'widevine' in modules and target.kernel == 'WINNT' and target.cpu == 'aarch64':
574         return True
577 set_config('MOZ_EME_WIN32_ARTIFACT', eme_win32_artifact)
579 option(name='--enable-chrome-format',
580        help='Select FORMAT of chrome files during packaging.',
581        nargs=1,
582        choices=('omni', 'jar', 'flat'),
583        default='omni')
585 @depends('--enable-chrome-format')
586 def packager_format(value):
587     return value[0]
589 set_config('MOZ_PACKAGER_FORMAT', packager_format)
591 @depends(host, build_project)
592 def jar_maker_format(host, build_project):
593     # Multilocales for mobile/android use the same mergedirs for all locales,
594     # so we can't use symlinks for those builds.
595     if host.os == 'WINNT' or build_project == 'mobile/android':
596         return 'flat'
597     return 'symlink'
599 set_config('MOZ_JAR_MAKER_FILE_FORMAT', jar_maker_format)
601 @depends(toolkit)
602 def omnijar_name(toolkit):
603     # Fennec's static resources live in the assets/ folder of the
604     # APK.  Adding a path to the name here works because we only
605     # have one omnijar file in the final package (which is not the
606     # case on desktop).
607     return 'assets/omni.ja' if toolkit == 'android' else 'omni.ja'
609 set_config('OMNIJAR_NAME', omnijar_name)
611 project_flag('MOZ_PLACES',
612              help='Build Places if required',
613              set_as_define=True)
615 project_flag('MOZ_SERVICES_HEALTHREPORT',
616              help='Build Firefox Health Reporter Service',
617              set_for_old_configure=True,
618              set_as_define=True)
620 project_flag('MOZ_SERVICES_SYNC',
621              help='Build Sync Services if required')
623 project_flag('MOZ_ANDROID_HISTORY',
624              help='Enable Android History instead of Places',
625              set_as_define=True)
627 project_flag('MOZ_DEDICATED_PROFILES',
628              help='Enable dedicated profiles per install',
629              set_as_define=True)
631 project_flag('MOZ_BLOCK_PROFILE_DOWNGRADE',
632              help='Block users from starting profiles last used by a newer build',
633              set_as_define=True)
635 option(env='MOZ_ALLOW_LEGACY_EXTENSIONS',
636        default=milestone.is_nightly,
637        help='Allow legacy browser extensions')
639 @depends('MOZ_ALLOW_LEGACY_EXTENSIONS')
640 def legacy_extensions(value):
641     if bool(value):
642         return True
644 set_config('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
645 set_define('MOZ_ALLOW_LEGACY_EXTENSIONS', legacy_extensions)
647 @depends('MOZ_PLACES', 'MOZ_ANDROID_HISTORY')
648 def check_places_and_android_history(places, android_history):
649     if places and android_history:
650         die('Cannot use MOZ_ANDROID_HISTORY alongside MOZ_PLACES.')
653 option(env='MOZ_TELEMETRY_REPORTING', default=mozilla_official,
654        help='Enable telemetry reporting')
656 set_define('MOZ_TELEMETRY_REPORTING', True, when='MOZ_TELEMETRY_REPORTING')
657 add_old_configure_assignment(
658     'MOZ_TELEMETRY_REPORTING', True, when='MOZ_TELEMETRY_REPORTING')
661 @depends('MOZ_TELEMETRY_REPORTING', milestone.is_nightly, fennec_nightly)
662 def telemetry_on_by_default(reporting, is_nightly, fennec_nightly):
663     return reporting and (is_nightly or fennec_nightly)
666 set_define('MOZ_TELEMETRY_ON_BY_DEFAULT', True, when=telemetry_on_by_default)
669 # gpsd support
670 # ==============================================================
671 option('--enable-gpsd', env='MOZ_GPSD',
672        help='Enable gpsd support')
674 @depends('--enable-gpsd')
675 def gpsd(value):
676     return bool(value)
678 system_gpsd = pkg_check_modules('MOZ_GPSD', 'libgps >= 3.11',
679                                 when=gpsd)
681 set_config('MOZ_GPSD', depends_if(system_gpsd)(lambda _: True))
683 # Miscellaneous programs
684 # ==============================================================
686 check_prog('TAR', ('gnutar', 'gtar', 'tar'))
687 check_prog('UNZIP', ('unzip',))
688 check_prog('ZIP', ('zip',))
689 check_prog('GN', ('gn',), allow_missing=True)
691 # Key files
692 # ==============================================================
693 include('../build/moz.configure/keyfiles.configure')
695 simple_keyfile('Mozilla API')
697 simple_keyfile('Google Location Service API')
699 simple_keyfile('Google Safebrowsing API')
701 id_and_secret_keyfile('Bing API')
703 simple_keyfile('Adjust SDK')
705 id_and_secret_keyfile('Leanplum SDK')
707 simple_keyfile('Pocket API')
710 # WebRender Debugger integration
711 # ==============================================================
713 option('--enable-webrender-debugger',
714        help='Build the websocket debug server in WebRender')
716 set_config('MOZ_WEBRENDER_DEBUGGER',
717            depends_if('--enable-webrender-debugger')(lambda _: True))
719 # SIMD acceleration for Rust code (currently just encoding_rs)
720 # ==============================================================
722 option('--enable-rust-simd', env='MOZ_RUST_SIMD',
723        help='Enable explicit SIMD in Rust code.')
725 @depends('--enable-rust-simd', target)
726 def rust_simd(value, target):
727     # As of 2019-03-04, the simd-accel feature of encoding_rs has not
728     # been properly set up outside aarch64, armv7, x86 and x86_64.
729     if target.cpu in ('aarch64', 'arm', 'x86', 'x86_64') and value:
730         return True
732 set_config('MOZ_RUST_SIMD', rust_simd)
733 set_define('MOZ_RUST_SIMD', rust_simd)
735 # Printing
736 # ==============================================================
737 @depends(target)
738 def ios_disable_printing(target):
739     if target.os == 'iOS':
740         return False
742 imply_option('--enable-printing', ios_disable_printing, reason='--target')
744 option('--disable-printing', help='Disable printing support')
746 @depends('--disable-printing')
747 def printing(value):
748     if value:
749         return True
751 set_config('NS_PRINTING', printing)
752 set_define('NS_PRINTING', printing)
753 set_define('NS_PRINT_PREVIEW', printing)
755 # Speech-dispatcher support
756 # ==============================================================
757 @depends(toolkit)
758 def no_speechd_on_non_gtk(toolkit):
759     if toolkit != 'gtk3':
760         return False
762 imply_option('--enable-synth-speechd', no_speechd_on_non_gtk,
763              reason='--enable-default-toolkit')
765 option('--disable-synth-speechd', help='Disable speech-dispatcher support')
767 set_config('MOZ_SYNTH_SPEECHD',
768            depends_if('--disable-synth-speechd')(lambda _: True))
770 # Speech API
771 # ==============================================================
772 option('--disable-webspeech', help='Disable support for HTML Speech API')
774 @depends('--disable-webspeech')
775 def webspeech(value):
776     if value:
777         return True
779 set_config('MOZ_WEBSPEECH', webspeech)
780 set_define('MOZ_WEBSPEECH', webspeech)
781 add_old_configure_assignment('MOZ_WEBSPEECH', webspeech)
783 # Speech API test backend
784 # ==============================================================
785 option('--enable-webspeechtestbackend', default=webspeech,
786        help='{Enable|Disable} support for HTML Speech API Test Backend')
788 @depends_if('--enable-webspeechtestbackend')
789 def webspeech_test_backend(value):
790     return True
792 set_config('MOZ_WEBSPEECH_TEST_BACKEND', webspeech_test_backend)
793 set_define('MOZ_WEBSPEECH_TEST_BACKEND', webspeech_test_backend)
795 # Enable IPDL's "expensive" unit tests
796 # ==============================================================
797 option('--enable-ipdl-tests', help='Enable expensive IPDL tests')
799 set_config('MOZ_IPDL_TESTS',
800            depends_if('--enable-ipdl-tests')(lambda _: True))
802 include('nss.configure')
804 # Graphics
805 # ==============================================================
806 option('--disable-skia', help='Disable use of Skia')
808 @depends('--disable-skia')
809 def skia(value):
810     if not value:
811         die('--disable-skia is not supported anymore')
812     else:
813         return True
815 set_config('MOZ_ENABLE_SKIA', skia)
816 set_define('MOZ_ENABLE_SKIA', skia)
817 set_define('USE_SKIA', skia)
819 @depends(skia, target)
820 def skia_android(skia, target):
821     if skia and target.os == 'Android':
822         return True
824 set_define('SK_BUILD_FOR_ANDROID_NDK', skia_android)
826 option('--enable-skia-pdf', help='Enable Skia PDF')
828 @depends('--enable-skia-pdf', skia, target, milestone)
829 def skia_pdf(value, skia, target, milestone):
830     if value.origin == 'default':
831         if not skia:
832             return None
833         if milestone.is_nightly and target.os != 'WINNT':
834             return True
835     elif value and not skia:
836         die('Cannot enable Skia PDF without enabling Skia')
837     if skia and value:
838         return True
840 set_config('MOZ_ENABLE_SKIA_PDF', skia_pdf)
841 set_define('MOZ_ENABLE_SKIA_PDF', skia_pdf)
843 option('--enable-skia-pdf-sfntly', help='Enable SFNTLY font subsetting in Skia PDF')
845 @depends('--enable-skia-pdf-sfntly', skia_pdf)
846 def skia_pdf_sfntly(value, skia_pdf):
847     if value.origin == 'default':
848         return skia_pdf
849     if value and not skia_pdf:
850         die('Cannot enable SFNTLY subsetting without enabling Skia PDF')
851     if skia_pdf and value:
852         return True
854 set_config('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
855 set_define('MOZ_ENABLE_SKIA_PDF_SFNTLY', skia_pdf_sfntly)
857 @depends(skia_pdf_sfntly)
858 def sfntly_includes(skia_pdf_sfntly):
859     includes = []
860     if skia_pdf_sfntly:
861         includes += [
862             '/gfx/sfntly/cpp/src',
863         ]
864     return includes
866 set_config('SFNTLY_INCLUDES', sfntly_includes)
868 @depends(skia)
869 def skia_includes(skia):
870     includes = []
871     if skia:
872         includes += [
873             '/gfx/skia',
874             '/gfx/skia/skia/include/config',
875             '/gfx/skia/skia/include/core',
876             '/gfx/skia/skia/include/docs',
877             '/gfx/skia/skia/include/gpu',
878             '/gfx/skia/skia/include/utils',
879         ]
880     return includes
882 set_config('SKIA_INCLUDES', skia_includes)
884 option('--with-system-webp',
885        help='Use system libwebp (located with pkgconfig)')
887 system_webp = pkg_check_modules('MOZ_WEBP', 'libwebp >= 1.0.2 libwebpdemux >= 1.0.2',
888                                 when='--with-system-webp')
890 set_config('MOZ_SYSTEM_WEBP', depends(when=system_webp)(lambda: True))
892 # Build Freetype in the tree
893 # ==============================================================
894 @depends(target, skia_pdf)
895 def tree_freetype(target, skia_pdf):
896     if target.os == 'Android' or (skia_pdf and target.os == 'WINNT'):
897         return True
899 set_define('MOZ_TREE_FREETYPE', tree_freetype)
900 set_config('MOZ_TREE_FREETYPE', tree_freetype)
901 add_old_configure_assignment('MOZ_TREE_FREETYPE', tree_freetype)
903 set_define('HAVE_FT_BITMAP_SIZE_Y_PPEM', tree_freetype)
904 set_define('HAVE_FT_GLYPHSLOT_EMBOLDEN', tree_freetype)
905 set_define('HAVE_FT_LOAD_SFNT_TABLE', tree_freetype)
907 @depends(freetype2_combined_info, tree_freetype, check_build_environment)
908 def ft2_info(freetype2_combined_info, tree_freetype, build_env):
909     if tree_freetype:
910         return namespace(cflags=('-I%s/modules/freetype2/include' % build_env.topsrcdir,),
911                          libs=())
912     if freetype2_combined_info:
913         return freetype2_combined_info
915 set_config('FT2_LIBS', ft2_info.libs)
916 add_old_configure_assignment('FT2_LIBS',
917                              ft2_info.libs)
918 add_old_configure_assignment('FT2_CFLAGS',
919                              ft2_info.cflags)
922 # Remote agent (part of CDP based remote protocol)
923 # ==============================================================
925 # See https://firefox-source-docs.mozilla.org/remote/ for more.
926 # The source code lives under ../remote.
928 @depends(target, milestone)
929 def remote_default(target, milestone):
930     return target.os != 'Android' and milestone.is_nightly
932 option('--disable-cdp', default=remote_default,
933        help='{Enable|Disable} remote agent')
935 @depends('--disable-cdp')
936 def remote(value):
937     if value:
938         return True
940 set_config('ENABLE_REMOTE_AGENT', remote)
941 set_define('ENABLE_REMOTE_AGENT', remote)
944 # Marionette remote protocol
945 # ==============================================================
947 # Marionette is the Gecko remote protocol used for various remote control,
948 # automation, and testing purposes throughout Gecko, Firefox, and Fennec.
949 # Marionette lives in ../testing/marionette.
951 # Marionette is not really a toolkit feature, as much as a Gecko
952 # engine feature.  But it is enabled based on the toolkit, so here it
953 # lives.
955 # It also backs ../testing/geckodriver, which is Mozilla's WebDriver
956 # implementation.
958 # For more information, see
959 # https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette.
961 option('--disable-marionette',
962        help='Disable Marionette remote protocol')
964 @depends('--disable-marionette')
965 def marionette(value):
966     if value:
967         return True
969 set_config('ENABLE_MARIONETTE', marionette)
972 # geckodriver WebDriver implementation
973 # ==============================================================
975 # Turn off geckodriver for build configs we don't handle yet,
976 # but allow --enable-geckodriver to override when compile environment is available.
977 # --disable-tests implies disabling geckodriver.
979 @depends('--enable-tests', target, cross_compiling, hazard_analysis, asan)
980 def geckodriver_default(enable_tests, target, cross_compile, hazard, asan):
981     if not enable_tests:
982         return False
983     # geckodriver depends on winapi 0.2.8, which doesn't work with AArch64.
984     if target.os == 'WINNT' and target.cpu == 'aarch64':
985         return False
986     if hazard or target.os == 'Android' or (asan and cross_compile):
987         return False
988     return True
990 option('--enable-geckodriver', default=geckodriver_default,
991        when='--enable-compile-environment',
992        help='{Build|Do not build} geckodriver')
994 @depends('--enable-geckodriver', when='--enable-compile-environment')
995 def geckodriver(enabled):
996     if enabled:
997         return True
999 set_config('ENABLE_GECKODRIVER', geckodriver)
1002 # WebRTC
1003 # ========================================================
1004 @depends(target)
1005 def webrtc_default(target):
1006     # Turn off webrtc for OS's we don't handle yet, but allow
1007     # --enable-webrtc to override.
1008     os_match = False
1009     for os_fragment in ('linux', 'mingw', 'android', 'linuxandroid',
1010                         'dragonfly', 'freebsd', 'netbsd', 'openbsd',
1011                         'darwin'):
1012         if target.raw_os.startswith(os_fragment):
1013             os_match = True
1015     cpu_match = False
1016     if (target.cpu in ('x86_64', 'arm', 'aarch64', 'x86', 'ia64', 'mips32', 'mips64') or
1017         target.cpu.startswith('ppc')):
1018         cpu_match = True
1020     if os_match and cpu_match:
1021         return True
1022     return False
1024 option('--disable-webrtc', default=webrtc_default,
1025        help='{Enable|Disable} support for WebRTC')
1027 @depends('--disable-webrtc')
1028 def webrtc(enabled):
1029     if enabled:
1030         return True
1032 set_config('MOZ_WEBRTC', webrtc)
1033 set_define('MOZ_WEBRTC', webrtc)
1034 add_old_configure_assignment('MOZ_WEBRTC', webrtc)
1035 set_config('MOZ_SCTP', webrtc)
1036 set_define('MOZ_SCTP', webrtc)
1037 set_config('MOZ_SRTP', webrtc)
1038 set_define('MOZ_SRTP', webrtc)
1039 set_config('MOZ_WEBRTC_SIGNALING', webrtc)
1040 set_define('MOZ_WEBRTC_SIGNALING', webrtc)
1041 set_config('MOZ_PEERCONNECTION', webrtc)
1042 set_define('MOZ_PEERCONNECTION', webrtc)
1043 # MOZ_WEBRTC_ASSERT_ALWAYS turns on a number of safety asserts in
1044 # opt/production builds (via MOZ_CRASH())
1045 set_config('MOZ_WEBRTC_ASSERT_ALWAYS', webrtc)
1046 set_define('MOZ_WEBRTC_ASSERT_ALWAYS', webrtc)
1048 option('--enable-hardware-aec-ns', when=webrtc,
1049        help='Enable support for hardware AEC and noise suppression')
1051 set_config('MOZ_WEBRTC_HARDWARE_AEC_NS',
1052            depends_if('--enable-hardware-aec-ns', when=webrtc)(lambda _: True))
1053 set_define('MOZ_WEBRTC_HARDWARE_AEC_NS',
1054            depends_if('--enable-hardware-aec-ns', when=webrtc)(lambda _: True))
1056 # RAW media
1057 # ==============================================================
1059 @depends(target, webrtc)
1060 def raw_media_default(target, webrtc):
1061     if target.os == 'Android':
1062         return True
1063     if webrtc:
1064         return True
1066 option('--enable-raw',
1067        default=raw_media_default,
1068        help='{Enable|Disable} support for RAW media')
1070 set_config('MOZ_RAW', depends_if('--enable-raw')(lambda _: True))
1071 set_define('MOZ_RAW', depends_if('--enable-raw')(lambda _: True))
1073 # ASan Reporter Addon
1074 # ==============================================================
1075 option('--enable-address-sanitizer-reporter',
1076        help='Enable Address Sanitizer Reporter Extension')
1078 @depends('--enable-address-sanitizer-reporter')
1079 def enable_asan_reporter(value):
1080     if value:
1081         return True
1083 set_config('MOZ_ASAN_REPORTER', enable_asan_reporter)
1084 set_define('MOZ_ASAN_REPORTER', enable_asan_reporter)
1085 add_old_configure_assignment('MOZ_ASAN_REPORTER', enable_asan_reporter)
1087 # Elfhack
1088 # ==============================================================
1089 with only_when('--enable-compile-environment'):
1090     @depends(host, target)
1091     def has_elfhack(host, target):
1092         return target.kernel == 'Linux' and host.kernel == 'Linux' and \
1093                target.cpu in ('arm', 'x86', 'x86_64')
1095     @depends('--enable-release')
1096     def default_elfhack(release):
1097         return bool(release)
1099     with only_when(has_elfhack):
1100         option('--disable-elf-hack', default=default_elfhack,
1101                help='{Enable|Disable} elf hacks')
1103         set_config('USE_ELF_HACK',
1104                    depends_if('--enable-elf-hack')(lambda _: True))
1107 @depends(check_build_environment)
1108 def idl_roots(build_env):
1109     return namespace(ipdl_root=os.path.join(build_env.topobjdir, 'ipc', 'ipdl'),
1110                      webidl_root=os.path.join(build_env.topobjdir,
1111                                               'dom', 'bindings'),
1112                      xpcom_root=os.path.join(build_env.topobjdir,
1113                                              'xpcom', 'components'))
1115 set_config('WEBIDL_ROOT', idl_roots.webidl_root)
1116 set_config('IPDL_ROOT', idl_roots.ipdl_root)
1117 set_config('XPCOM_ROOT', idl_roots.xpcom_root)
1119 # Proxy bypass protection
1120 # ==============================================================
1122 option('--enable-proxy-bypass-protection',
1123        help='Prevent suspected or confirmed proxy bypasses')
1125 @depends_if('--enable-proxy-bypass-protection')
1126 def proxy_bypass_protection(_):
1127     return True
1129 set_config('MOZ_PROXY_BYPASS_PROTECTION', proxy_bypass_protection)
1130 set_define('MOZ_PROXY_BYPASS_PROTECTION', proxy_bypass_protection)
1132 # MIDL
1133 # ==============================================================
1135 @depends(c_compiler, toolchain_prefix)
1136 def midl_names(c_compiler, toolchain_prefix):
1137     if c_compiler and c_compiler.type in ['gcc', 'clang']:
1138         # mingw
1139         widl = ('widl', )
1140         if toolchain_prefix:
1141             prefixed = tuple('%s%s' % (p, 'widl') for p in toolchain_prefix)
1142             widl = prefixed + widl
1143         return widl
1145     return ('midl',)
1147 @depends(target, '--enable-compile-environment')
1148 def check_for_midl(target, compile_environment):
1149     if target.os != 'WINNT':
1150         return
1152     if compile_environment:
1153         return True
1156 midl = check_prog('MIDL', midl_names, when=check_for_midl, allow_missing=True,
1157                   paths=sdk_bin_path)
1160 @depends(c_compiler, target, toolchain_search_path,
1161          when=depends(midl, target)(lambda m, t: m and t.kernel == 'WINNT'))
1162 @imports(_from='mozbuild.shellutil', _import='quote')
1163 def midl_flags(c_compiler, target, toolchain_search_path):
1164     if c_compiler and c_compiler.type == 'clang-cl':
1165         env = {
1166             'x86': 'win32',
1167             'x86_64': 'x64',
1168             'aarch64': 'arm64',
1169         }[target.cpu]
1170         flags = ['-env', env]
1172         if c_compiler.version >= '8':
1173             return flags + ['-cpp_cmd', c_compiler.compiler]
1175         # clang-cl didn't work as a preprocessor for midl before version 8
1176         # so we need to find cl if we use an older version.
1177         # find cl. https://bugs.llvm.org/show_bug.cgi?id=40140
1178         cl = find_program('cl', paths=toolchain_search_path)
1179         if not cl:
1180             die('Could not find Microsoft Visual C/C++ compiler for MIDL')
1181         flags += ['-cpp_cmd', cl]
1182         return flags
1184     # mingw
1185     return {
1186         'x86': ['--win32', '-m32'],
1187         'x86_64': ['--win64', '-m64'],
1188     }[target.cpu]
1191 set_config('MIDL_FLAGS', midl_flags)
1193 # Accessibility
1194 # ==============================================================
1196 option('--disable-accessibility', help='Disable accessibility support')
1198 @depends('--enable-accessibility', check_for_midl, midl, c_compiler)
1199 def accessibility(value, check_for_midl, midl, c_compiler):
1200     enabled = bool(value)
1202     if not enabled:
1203         return
1205     if check_for_midl and not midl:
1206         if c_compiler and c_compiler.type in ('gcc', 'clang'):
1207             die('You have accessibility enabled, but widl could not be found. '
1208                 'Add --disable-accessibility to your mozconfig or install widl. '
1209                 'See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details.')
1210         else:
1211             die('MIDL could not be found. '
1212                 'Building accessibility without MIDL is not supported.')
1214     return enabled
1217 set_config('ACCESSIBILITY', accessibility)
1218 set_define('ACCESSIBILITY', accessibility)
1219 add_old_configure_assignment('ACCESSIBILITY', accessibility)
1221 # Addon signing
1222 # ==============================================================
1224 option('--with-unsigned-addon-scopes',
1225        nargs='+', choices=('app', 'system'),
1226        help='Addon scopes where signature is not required')
1228 @depends('--with-unsigned-addon-scopes')
1229 def unsigned_addon_scopes(scopes):
1230     return namespace(
1231         app='app' in scopes or None,
1232         system='system' in scopes or None,
1233     )
1235 set_config('MOZ_UNSIGNED_APP_SCOPE', unsigned_addon_scopes.app)
1236 set_config('MOZ_UNSIGNED_SYSTEM_SCOPE', unsigned_addon_scopes.system)
1238 # Launcher process (Windows only)
1239 # ==============================================================
1241 @depends(target)
1242 def launcher_process_default(target):
1243     return target.os == 'WINNT'
1245 option('--enable-launcher-process', default=launcher_process_default,
1246        help='{Enable|Disable} launcher process by default')
1248 @depends('--enable-launcher-process', target)
1249 def launcher(value, target):
1250     enabled = bool(value)
1251     if enabled and target.os != 'WINNT':
1252         die('Cannot enable launcher process on %s', target.os)
1253     if enabled:
1254         return True
1256 set_config('MOZ_LAUNCHER_PROCESS', launcher)
1257 set_define('MOZ_LAUNCHER_PROCESS', launcher)
1259 # Maintenance service (Windows only)
1260 # ==============================================================
1262 option('--enable-maintenance-service',
1263        when=target_is_windows, default=target_is_windows,
1264        help='{Enable|Disable} building of maintenance service')
1266 set_define('MOZ_MAINTENANCE_SERVICE',
1267            depends_if('--enable-maintenance-service',
1268                       when=target_is_windows)(lambda _: True))
1269 set_config('MOZ_MAINTENANCE_SERVICE',
1270            depends_if('--enable-maintenance-service',
1271                       when=target_is_windows)(lambda _: True))
1273 # BITS download (Windows only)
1274 # ==============================================================
1276 option('--enable-bits-download',
1277        when=target_is_windows, default=target_is_windows,
1278        help='{Enable|Disable} building BITS download support')
1280 set_define('MOZ_BITS_DOWNLOAD',
1281            depends_if('--enable-bits-download',
1282                       when=target_is_windows)(lambda _: True))
1283 set_config('MOZ_BITS_DOWNLOAD',
1284            depends_if('--enable-bits-download',
1285                       when=target_is_windows)(lambda _: True))
1287 # Bundled fonts on desktop platform
1288 # ==============================================================
1290 @depends(target)
1291 def bundled_fonts_default(target):
1292     return target.os == 'WINNT' or target.kernel == 'Linux'
1294 @depends(build_project)
1295 def allow_bundled_fonts(project):
1296     return project == 'browser' or project == 'comm/mail'
1298 option('--enable-bundled-fonts', default=bundled_fonts_default,
1299        when=allow_bundled_fonts,
1300        help='{Enable|Disable} support for bundled fonts on desktop platforms')
1302 set_define('MOZ_BUNDLED_FONTS',
1303            depends_if('--enable-bundled-fonts', when=allow_bundled_fonts)(lambda _: True))
1305 # Verify MAR signatures
1306 # ==============================================================
1308 option('--disable-verify-mar', help='Disable verifying MAR signatures')
1310 set_define('MOZ_VERIFY_MAR_SIGNATURE',
1311            depends_if('--enable-verify-mar')(lambda _: True))
1312 set_config('MOZ_VERIFY_MAR_SIGNATURE',
1313            depends_if('--enable-verify-mar')(lambda _: True))
1315 # TaskTracer
1316 # ==============================================================
1318 option('--enable-tasktracer', help='Enable TaskTracer')
1320 set_define('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(lambda _: True))
1321 set_config('MOZ_TASK_TRACER', depends_if('--enable-tasktracer')(lambda _: True))
1323 # Reflow counting
1324 # ==============================================================
1326 @depends(moz_debug)
1327 def reflow_perf(debug):
1328     if debug:
1329         return True
1331 option('--enable-reflow-perf',
1332        default=reflow_perf,
1333        help='{Enable|Disable} reflow performance tracing')
1335 # The difference in conditions here comes from the initial implementation
1336 # in old-configure, which was unexplained there as well.
1337 set_define('MOZ_REFLOW_PERF', depends_if('--enable-reflow-perf')(lambda _: True))
1338 set_define('MOZ_REFLOW_PERF_DSP', reflow_perf)
1340 # Layout debugger
1341 # ==============================================================
1343 @depends(moz_debug)
1344 def layout_debugger(debug):
1345     if debug:
1346         return True
1348 option('--enable-layout-debugger',
1349        default=layout_debugger,
1350        help='{Enable|Disable} layout debugger')
1352 set_config('MOZ_LAYOUT_DEBUGGER', depends_if('--enable-layout-debugger')(lambda _: True))
1355 # Shader Compiler for Windows (and MinGW Cross Compile)
1356 # ==============================================================
1358 with only_when(compile_environment):
1359     fxc = check_prog('FXC', ('fxc.exe', 'fxc2.exe'), when=depends(target)
1360                      (lambda t: t.kernel == 'WINNT'),
1361                      paths=sdk_bin_path)
1362     wine = check_prog('WINE', ['wine'], when=depends(target, host)
1363                       (lambda t, h: t.kernel == 'WINNT' and h.kernel == 'Linux'))
1366 # VPX
1367 # ===
1369 with only_when(compile_environment):
1370     option('--with-system-libvpx',
1371            help='Use system libvpx (located with pkgconfig)')
1373     with only_when('--with-system-libvpx'):
1374         vpx = pkg_check_modules('MOZ_LIBVPX', 'vpx >= 1.7.0')
1376         check_header('vpx/vpx_decoder.h', flags=vpx.cflags, onerror=lambda: die(
1377             "Couldn't find vpx/vpx_decoder.h, which is required to build "
1378             "with system libvpx. Use --without-system-libvpx to build "
1379             "with in-tree libvpx."))
1381         check_symbol('vpx_codec_dec_init_ver', flags=vpx.libs, onerror=lambda: die(
1382             "--with-system-libvpx requested but symbol vpx_codec_dec_init_ver "
1383             "not found"
1384         ))
1386         set_config('MOZ_SYSTEM_LIBVPX', True)
1389     @depends('--with-system-libvpx', target, gnu_as)
1390     def in_tree_vpx(system_libvpx, target, gnu_as):
1391         if system_libvpx:
1392             return
1394         use_yasm = (target.cpu in ('x86', 'x86_64')) or None
1395         need_yasm = False
1396         arm_asm = (target.cpu == 'arm' and gnu_as) or None
1398         if use_yasm:
1399             need_yasm = True
1400             if target.kernel == 'WINNT':
1401                 need_yasm = Version('1.1')
1403         return namespace(arm_asm=arm_asm, use_yasm=use_yasm, need_yasm=need_yasm)
1406     # Building with -mfpu=neon requires either the "softfp" or the
1407     # "hardfp" ABI. Depending on the compiler's default target, and the
1408     # CFLAGS, the default ABI might be neither, in which case it is the
1409     # "softfloat" ABI.
1410     # The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
1411     # we can safely mix code built with both ABIs. So, if we detect
1412     # that compiling uses the "softfloat" ABI, force the use of the
1413     # "softfp" ABI instead.
1414     # Confusingly, the __SOFTFP__ preprocessor variable indicates the
1415     # "softfloat" ABI, not the "softfp" ABI.
1416     # Note: VPX_ASFLAGS is also used in CFLAGS.
1417     softfp = cxx_compiler.try_compile(body='''
1418         #ifndef __SOFTFP__
1419         #error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
1420         #endif''', when=in_tree_vpx.arm_asm)
1423     @depends(in_tree_vpx, softfp, target)
1424     def vpx_as_flags(vpx, softfp, target):
1425         flags = []
1426         if vpx and vpx.arm_asm:
1427             # These flags are a lie; they're just used to enable the requisite
1428             # opcodes; actual arch detection is done at runtime.
1429             flags = ['-march=armv7-a', '-mfpu=neon']
1430             if softfp:
1431                 flags.append('-mfloat-abi=softfp')
1432         elif vpx and vpx.use_yasm and target.os != 'WINNT' and target.cpu != 'x86_64':
1433             flags = ['-DPIC']
1434         return flags
1437     set_config('VPX_USE_YASM', in_tree_vpx.use_yasm)
1438     set_config('VPX_ASFLAGS', vpx_as_flags)
1441 # JPEG
1442 # ====
1444 with only_when(compile_environment):
1445     option('--with-system-jpeg', nargs='?',
1446            help='Use system libjpeg (installed at given prefix)')
1448     @depends_if('--with-system-jpeg')
1449     def jpeg_flags(value):
1450         if len(value):
1451             return namespace(
1452                 cflags=('-I%s/include' % value[0],),
1453                 ldflags=('-L%s/lib' % value[0], '-ljpeg'),
1454             )
1455         return namespace(
1456             ldflags=('-ljpeg',),
1457         )
1459     with only_when('--with-system-jpeg'):
1460         check_symbol('jpeg_destroy_compress', flags=jpeg_flags.ldflags,
1461                      onerror=lambda: die('--with-system-jpeg requested but symbol '
1462                                          'jpeg_destroy_compress not found.'))
1464         c_compiler.try_compile(
1465             includes=[
1466                 'stdio.h',
1467                 'sys/types.h',
1468                 'jpeglib.h',
1469             ],
1470             body='''
1471                 #if JPEG_LIB_VERSION < 62
1472                 #error Insufficient JPEG library version
1473                 #endif
1474             ''',
1475             flags=jpeg_flags.cflags,
1476             check_msg='for sufficient jpeg library version',
1477             onerror=lambda: die('Insufficient JPEG library version for '
1478                                 '--with-system-jpeg (62 required)'),
1479         )
1481         c_compiler.try_compile(
1482             includes=[
1483                 'stdio.h',
1484                 'sys/types.h',
1485                 'jpeglib.h',
1486             ],
1487             body='''
1488                 #ifndef JCS_EXTENSIONS
1489                 #error libjpeg-turbo JCS_EXTENSIONS required
1490                 #endif
1491             ''',
1492             flags=jpeg_flags.cflags,
1493             check_msg='for sufficient libjpeg-turbo JCS_EXTENSIONS',
1494             onerror=lambda: die('libjpeg-turbo JCS_EXTENSIONS required for '
1495                                  '--with-system-jpeg'),
1496         )
1498         set_config('MOZ_JPEG_CFLAGS', jpeg_flags.cflags)
1499         set_config('MOZ_JPEG_LIBS', jpeg_flags.ldflags)
1501     @depends('--with-system-jpeg', target)
1502     def in_tree_jpeg(system_jpeg, target):
1503         if system_jpeg:
1504             return
1506         flags = ()
1507         use_yasm = None
1508         need_yasm = False
1509         if target.kernel == 'Darwin':
1510             if target.cpu == 'x86':
1511                 flags = ('-DPIC', '-DMACHO')
1512             elif target.cpu == 'x86_64':
1513                 flags = ('-D__x86_64__', '-DPIC', '-DMACHO')
1514         elif target.kernel == 'WINNT':
1515             if target.cpu == 'x86':
1516                 flags = ('-DPIC', '-DWIN32')
1517             elif target.cpu == 'x86_64':
1518                 flags = ('-D__x86_64__', '-DPIC', '-DWIN64', '-DMSVC')
1519         elif target.cpu == 'arm':
1520             flags = ('-march=armv7-a', '-mfpu=neon')
1521         elif target.cpu == 'aarch64':
1522             flags = ('-march=armv8-a',)
1523         elif target.cpu == 'mips32':
1524             flags = ('-mdspr2',)
1525         elif target.cpu == 'x86':
1526             flags = ('-DPIC', '-DELF')
1527         elif target.cpu == 'x86_64':
1528             flags = ('-D__x86_64__', '-DPIC', '-DELF')
1530         if target.cpu in ('x86', 'x86_64'):
1531             use_yasm = True
1532             if target.kernel == 'Linux' and target.os == 'GNU':
1533                 need_yasm = Version('1.0.1')
1534             else:
1535                 need_yasm = Version('1.1')
1537         return namespace(flags=flags, use_yasm=use_yasm, need_yasm=need_yasm)
1539     set_config('LIBJPEG_TURBO_USE_YASM', in_tree_jpeg.use_yasm)
1540     set_config('LIBJPEG_TURBO_ASFLAGS', in_tree_jpeg.flags)
1543 # Libav-fft Support
1544 # ==============================================================
1545 with only_when(compile_environment):
1546     @depends(target)
1547     def libav_fft(target):
1548         flags = None
1549         if target.kernel == 'WINNT' and target.cpu == 'x86':
1550             flags = ['-DPIC', '-DWIN32']
1551         elif target.kernel == 'WINNT' and target.cpu == 'aarch64':
1552             flags = ['-DPIC', '-DWIN64']
1553         elif target.cpu == 'x86_64':
1554             if target.kernel == 'Darwin':
1555                 flags = ['-D__x86_64__', '-DPIC', '-DMACHO']
1556             elif target.kernel == 'WINNT':
1557                 flags = ['-D__x86_64__', '-DPIC', '-DWIN64', '-DMSVC']
1558             else:
1559                 flags = ['-D__x86_64__', '-DPIC', '-DELF']
1560         if flags:
1561             if target.kernel == 'Linux' and target.os == 'GNU':
1562                 need_yasm = Version('1.0.1')
1563             else:
1564                 need_yasm = Version('1.1')
1565             return namespace(flags=flags, need_yasm=need_yasm)
1568     set_config('MOZ_LIBAV_FFT', depends(when=libav_fft)(lambda: True))
1569     set_define('MOZ_LIBAV_FFT', depends(when=libav_fft)(lambda: True))
1570     set_config('LIBAV_FFT_ASFLAGS', libav_fft.flags)
1573 # FFmpeg's ffvpx configuration
1574 # ==============================================================
1575 # Artifact builds need MOZ_FFVPX defined as if compilation happened.
1576 with only_when(compile_environment | artifact_builds):
1577     @depends_if(yasm_version)
1578     def yasm_has_avx2(yasm_version):
1579         return yasm_version >= '1.2'
1582     set_config('YASM_HAS_AVX2', yasm_has_avx2)
1585     @depends(yasm_has_avx2, libav_fft, vpx_as_flags, target)
1586     def ffvpx(yasm_has_avx2, libav_fft, vpx_as_flags, target):
1587         enable = flac_only = use_yasm = False
1588         flags = []
1589         if target.cpu in ('x86', 'x86_64') or \
1590                 target.cpu == 'aarch64' and target.kernel == 'WINNT':
1591             enable = True
1592             if libav_fft and libav_fft.flags:
1593                 use_yasm = True
1594                 flags.extend(libav_fft.flags)
1595                 if target.kernel == 'WINNT':
1596                     if target.cpu == 'x86':
1597                         # 32-bit windows need to prefix symbols with an underscore.
1598                         flags.extend(('-DPREFIX', '-Pconfig_win32.asm'))
1599                     elif target.cpu == 'aarch64':
1600                         use_yasm = False
1601                     else:
1602                         flags.append('-Pconfig_win64.asm')
1603                 elif target.kernel == 'Darwin':
1604                     # 32/64-bit macosx assemblers need to prefix symbols with an
1605                     # underscore.
1606                     flags.extend(('-DPREFIX', '-Pconfig_darwin64.asm'))
1607                 else:
1608                     # Default to unix.
1609                     flags.append('-Pconfig_unix64.asm')
1610             else:
1611                 flac_only = True
1612         elif target.cpu in ('arm', 'aarch64') and \
1613                 target.kernel not in ('WINNT', 'Darwin'):
1614             enable = flac_only = True
1615             if vpx_as_flags:
1616                 flags.extend(vpx_as_flags)
1618         if use_yasm:
1619             # default disabled components
1620             flags.append('-Pdefaults_disabled.asm')
1621             if not yasm_has_avx2:
1622                 flags.extend((
1623                     '-DHAVE_AVX2=0',
1624                     '-DHAVE_AVX2_INTERNAL=0',
1625                     '-DHAVE_AVX2_EXTERNAL=0',
1626                 ))
1628         return namespace(
1629             enable=enable,
1630             use_yasm=use_yasm,
1631             flac_only=flac_only,
1632             flags=flags,
1633         )
1636     set_config('MOZ_FFVPX', True, when=ffvpx.enable)
1637     set_define('MOZ_FFVPX', True, when=ffvpx.enable)
1638     set_config('MOZ_FFVPX_FLACONLY', True, when=ffvpx.flac_only)
1639     set_define('MOZ_FFVPX_FLACONLY', True, when=ffvpx.flac_only)
1640     set_config('FFVPX_ASFLAGS', ffvpx.flags)
1641     set_config('FFVPX_USE_YASM', True, when=ffvpx.use_yasm)
1644 @depends(yasm_version, in_tree_vpx.need_yasm, in_tree_jpeg.use_yasm,
1645          libav_fft.need_yasm, ffvpx.use_yasm)
1646 @imports(_from='__builtin__', _import='sorted')
1647 def valid_yasm_version(yasm_version, for_vpx, for_jpeg, for_libav,
1648                        for_ffvpx=False):
1649     # Note: the default for for_ffvpx above only matters for unit tests.
1650     requires = {
1651         'vpx': for_vpx,
1652         'jpeg': for_jpeg,
1653         'libav': for_libav,
1654         'ffvpx': for_ffvpx,
1655     }
1656     requires = {k: v for (k, v) in requires.items() if v}
1657     if requires and not yasm_version:
1658         items = sorted(requires.keys())
1659         if len(items) > 1:
1660             what = ' and '.join((', '.join(items[:-1]), items[-1]))
1661         else:
1662             what = items[0]
1663         die('Yasm is required to build with %s, but you do not appear to have '
1664             'Yasm installed.' % what)
1666     versioned = {k: v for (k, v) in requires.items() if v is not True}
1667     by_version = sorted(versioned.items(), key=lambda x: x[1])
1668     if by_version:
1669         what, version = by_version[-1]
1670         if yasm_version < version:
1671             die('Yasm version %s or greater is required to build with %s.'
1672                 % (version, what))
1675 # ANGLE OpenGL->D3D translator for WebGL
1676 # ==============================================================
1678 with only_when(compile_environment & target_is_windows):
1679     def d3d_compiler_dll_result(value):
1680         if not value.path:
1681             return 'provided by the OS'
1682         return value.path
1684     @depends(target, valid_windows_sdk_dir, fxc)
1685     @checking('for D3D compiler DLL', d3d_compiler_dll_result)
1686     @imports('os.path')
1687     def d3d_compiler_dll(target, windows_sdk_dir, fxc):
1688         suffix = {
1689             'x86_64': 'x64',
1690         }.get(target.cpu, target.cpu)
1692         name = 'd3dcompiler_47.dll'
1694         if target.cpu == 'aarch64':
1695             # AArch64 Windows comes with d3dcompiler_47.dll installed
1696             return namespace(name=name, path=None)
1698         if windows_sdk_dir:
1699             path = os.path.join(windows_sdk_dir.path, 'Redist', 'D3D', suffix, name)
1700             error_extra = 'in Windows SDK at {}'.format(windows_sdk_dir.path)
1701         else:
1702             path = os.path.join(os.path.dirname(fxc), name)
1703             error_extra = 'alongside FXC at {}'.format(fxc)
1705         if os.path.exists(path):
1706             return namespace(name=name, path=path)
1707         die('Could not find {} {}'.format(name, error_extra))
1710     set_config('MOZ_ANGLE_RENDERER', True)
1711     set_config('MOZ_D3DCOMPILER_VISTA_DLL', d3d_compiler_dll.name,
1712                when=d3d_compiler_dll.path)
1713     set_config('MOZ_D3DCOMPILER_VISTA_DLL_PATH', d3d_compiler_dll.path)
1715 # Remoting protocol support
1716 # ==============================================================
1718 @depends(toolkit)
1719 def has_remote(toolkit):
1720     if 'gtk' in toolkit or toolkit == 'windows':
1721         return True
1723 set_config('MOZ_HAS_REMOTE', has_remote)
1724 set_define('MOZ_HAS_REMOTE', has_remote)
1727 # new XULStore implementation
1728 # ==============================================================
1730 @depends(milestone)
1731 def new_xulstore(milestone):
1732     if milestone.is_nightly:
1733         return True
1735 set_config('MOZ_NEW_XULSTORE', True, when=new_xulstore)
1736 set_define('MOZ_NEW_XULSTORE', True, when=new_xulstore)
1739 # new Notification Store implementation
1740 # ==============================================================
1742 @depends(milestone)
1743 def new_notification_store(milestone):
1744     if milestone.is_nightly:
1745         return True
1747 set_config('MOZ_NEW_NOTIFICATION_STORE', True, when=new_notification_store)
1748 set_define('MOZ_NEW_NOTIFICATION_STORE', True, when=new_notification_store)
1751 # new Cert Storage implementation
1752 # ==============================================================
1754 @depends(milestone)
1755 def new_cert_storage(milestone):
1756     if milestone.is_nightly:
1757         return True
1759 set_config('MOZ_NEW_CERT_STORAGE', True, when=new_cert_storage)
1760 set_define('MOZ_NEW_CERT_STORAGE', True, when=new_cert_storage)