Bug 1498467 [wpt PR 13478] - Remove the "W3C WebSocket API" prefix from websockets...
[gecko.git] / moz.configure
blobbaeb4e757716d93c46c3b6673e1440e599809b4d
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 include('build/moz.configure/init.configure')
9 # Note:
10 # - Gecko-specific options and rules should go in toolkit/moz.configure.
11 # - Firefox-specific options and rules should go in browser/moz.configure.
12 # - Fennec-specific options and rules should go in
13 #   mobile/android/moz.configure.
14 # - Spidermonkey-specific options and rules should go in js/moz.configure.
15 # - etc.
17 option('--enable-artifact-builds', env='MOZ_ARTIFACT_BUILDS',
18        help='Download and use prebuilt binary artifacts.')
20 @depends('--enable-artifact-builds')
21 def artifact_builds(value):
22     if value:
23         return True
25 set_config('MOZ_ARTIFACT_BUILDS', artifact_builds)
27 imply_option('--enable-artifact-build-symbols',
28              depends(artifact_builds)(lambda v: False if v is None else None),
29              reason='--disable-artifact-builds')
31 option('--enable-artifact-build-symbols',
32        help='Download symbols when artifact builds are enabled.')
34 set_config('MOZ_ARTIFACT_BUILD_SYMBOLS',
35            depends_if('--enable-artifact-build-symbols')(lambda _: True))
37 @depends('--enable-artifact-builds')
38 def imply_disable_compile_environment(value):
39     if value:
40         return False
42 option(env='MOZ_COPY_PDBS',
43     help='For builds that do not support symbols in the normal fashion,'
44          ' generate and copy them into the resulting build archive.')
46 set_config('MOZ_COPY_PDBS', depends_if('MOZ_COPY_PDBS')(lambda _: True))
48 imply_option('--enable-compile-environment', imply_disable_compile_environment)
50 option('--disable-compile-environment',
51        help='Disable compiler/library checks')
53 @depends('--disable-compile-environment')
54 def compile_environment(compile_env):
55     if compile_env:
56         return True
58 set_config('COMPILE_ENVIRONMENT', compile_environment)
59 add_old_configure_assignment('COMPILE_ENVIRONMENT', compile_environment)
61 js_option('--disable-tests',
62           help='Do not build test libraries & programs')
64 @depends('--disable-tests')
65 def enable_tests(value):
66     if value:
67         return True
69 set_config('ENABLE_TESTS', enable_tests)
70 set_define('ENABLE_TESTS', enable_tests)
72 js_option(env='MOZILLA_OFFICIAL',
73           help='Build an official release')
75 @depends('MOZILLA_OFFICIAL')
76 def mozilla_official(official):
77     if official:
78         return True
80 set_config('MOZILLA_OFFICIAL', mozilla_official)
81 set_define('MOZILLA_OFFICIAL', mozilla_official)
82 add_old_configure_assignment('MOZILLA_OFFICIAL', mozilla_official)
84 @depends(enable_tests)
85 def gtest_has_rtti(value):
86     if value:
87         return '0'
89 set_define('GTEST_HAS_RTTI', gtest_has_rtti)
91 @depends(target, enable_tests)
92 def linux_gtest_defines(target, enable_tests):
93     if enable_tests and target.os == 'Android':
94         return namespace(os_linux_android=True,
95                          use_own_tr1_tuple=True,
96                          has_clone='0')
98 set_define('GTEST_OS_LINUX_ANDROID',
99            linux_gtest_defines.os_linux_android)
100 set_define('GTEST_USE_OWN_TR1_TUPLE',
101            linux_gtest_defines.use_own_tr1_tuple)
102 set_define('GTEST_HAS_CLONE',
103            linux_gtest_defines.has_clone)
105 js_option('--enable-debug',
106           nargs='?',
107           help='Enable building with developer debug info '
108                '(using the given compiler flags).')
110 @depends('--enable-debug')
111 def moz_debug(debug):
112     if debug:
113         return bool(debug)
115 set_config('MOZ_DEBUG', moz_debug)
116 set_define('MOZ_DEBUG', moz_debug)
117 # Override any value MOZ_DEBUG may have from the environment when passing it
118 # down to old-configure.
119 add_old_configure_assignment('MOZ_DEBUG',
120                              depends('--enable-debug')(lambda x: bool(x)))
122 js_option('--enable-rust-debug',
123           default=depends(when='--enable-debug')(lambda: True),
124           help='{Build|Do not build} Rust code with debug assertions turned '
125                'on.')
127 @depends(when='--enable-rust-debug')
128 def debug_rust():
129     return True
131 set_config('MOZ_DEBUG_RUST', debug_rust)
132 set_define('MOZ_DEBUG_RUST', debug_rust)
134 include('build/moz.configure/pkg.configure')
135 # Make this assignment here rather than in pkg.configure to avoid
136 # requiring this file in unit tests.
137 add_old_configure_assignment('PKG_CONFIG', pkg_config)
139 include('build/moz.configure/toolchain.configure',
140         when='--enable-compile-environment')
141 include('build/moz.configure/memory.configure',
142         when='--enable-compile-environment')
143 include('build/moz.configure/headers.configure',
144         when='--enable-compile-environment')
145 include('build/moz.configure/warnings.configure',
146         when='--enable-compile-environment')
147 include('build/moz.configure/flags.configure',
148         when='--enable-compile-environment')
149 # rust.configure is included by js/moz.configure.
151 js_option('--enable-valgrind',
152           help='Enable Valgrind integration hooks')
154 valgrind_h = check_header('valgrind/valgrind.h', when='--enable-valgrind')
156 @depends('--enable-valgrind', valgrind_h)
157 def check_valgrind(valgrind, valgrind_h):
158     if valgrind:
159         if not valgrind_h:
160             die('--enable-valgrind specified but Valgrind is not installed')
161         return True
163 set_define('MOZ_VALGRIND', check_valgrind)
164 set_config('MOZ_VALGRIND', check_valgrind)
166 @depends(target, host)
167 def is_openbsd(target, host):
168     return target.kernel == 'OpenBSD' or host.kernel == 'OpenBSD'
170 option(env='SO_VERSION', nargs=1, default='1.0', when=is_openbsd,
171        help='Shared library version for OpenBSD systems')
173 @depends('SO_VERSION', when=is_openbsd)
174 def so_version(value):
175     return value
177 @template
178 def library_name_info_template(host_or_target):
179     assert host_or_target in {host, target}
180     compiler = {
181         host: host_c_compiler,
182         target: c_compiler,
183     }[host_or_target]
185     @depends(host_or_target, compiler, so_version)
186     def library_name_info_impl(host_or_target, compiler, so_version):
187         if host_or_target.kernel == 'WINNT':
188             # There aren't artifacts for mingw builds, so it's OK that the
189             # results are inaccurate in that case.
190             if compiler and compiler.type not in ('msvc', 'clang-cl'):
191                 return namespace(
192                     dll=namespace(prefix='', suffix='.dll'),
193                     lib=namespace(prefix='lib', suffix='a'),
194                     import_lib=namespace(prefix='lib', suffix='a'),
195                     rust_lib=namespace(prefix='', suffix='lib'),
196                     obj=namespace(prefix='', suffix='o'),
197                 )
199             return namespace(
200                 dll=namespace(prefix='', suffix='.dll'),
201                 lib=namespace(prefix='', suffix='lib'),
202                 import_lib=namespace(prefix='', suffix='lib'),
203                 rust_lib=namespace(prefix='', suffix='lib'),
204                 obj=namespace(prefix='', suffix='obj'),
205             )
207         elif host_or_target.kernel == 'Darwin':
208             return namespace(
209                 dll=namespace(prefix='lib', suffix='.dylib'),
210                 lib=namespace(prefix='lib', suffix='a'),
211                 import_lib=namespace(prefix=None, suffix=''),
212                 rust_lib=namespace(prefix='lib', suffix='a'),
213                 obj=namespace(prefix='', suffix='o'),
214             )
215         elif so_version:
216             so = '.so.%s' % so_version
217         else:
218             so = '.so'
220         return namespace(
221             dll=namespace(prefix='lib', suffix=so),
222             lib=namespace(prefix='lib', suffix='a'),
223             import_lib=namespace(prefix=None, suffix=''),
224             rust_lib=namespace(prefix='lib', suffix='a'),
225             obj=namespace(prefix='', suffix='o'),
226         )
228     return library_name_info_impl
230 host_library_name_info = library_name_info_template(host)
231 library_name_info = library_name_info_template(target)
233 set_config('DLL_PREFIX', library_name_info.dll.prefix)
234 set_config('DLL_SUFFIX', library_name_info.dll.suffix)
235 set_config('HOST_DLL_PREFIX', host_library_name_info.dll.prefix)
236 set_config('HOST_DLL_SUFFIX', host_library_name_info.dll.suffix)
237 set_config('LIB_PREFIX', library_name_info.lib.prefix)
238 set_config('LIB_SUFFIX', library_name_info.lib.suffix)
239 set_config('RUST_LIB_PREFIX', library_name_info.rust_lib.prefix)
240 set_config('RUST_LIB_SUFFIX', library_name_info.rust_lib.suffix)
241 set_config('OBJ_SUFFIX', library_name_info.obj.suffix)
242 # Lots of compilation tests depend on this variable being present.
243 add_old_configure_assignment('OBJ_SUFFIX', library_name_info.obj.suffix)
244 set_config('IMPORT_LIB_SUFFIX', library_name_info.import_lib.suffix)
245 set_define('MOZ_DLL_PREFIX', depends(library_name_info.dll.prefix)(lambda s: '"%s"' % s))
246 set_define('MOZ_DLL_SUFFIX', depends(library_name_info.dll.suffix)(lambda s: '"%s"' % s))
248 # Depends on host_library_name_info, so needs to go here.
249 include('build/moz.configure/bindgen.configure',
250         when='--enable-compile-environment')
251 include(include_project_configure)
253 @depends('--help')
254 @imports(_from='mozbuild.backend', _import='backends')
255 def build_backends_choices(_):
256     return tuple(backends)
259 @deprecated_option('--enable-build-backend', nargs='+',
260                    choices=build_backends_choices)
261 def build_backend(backends):
262     if backends:
263         return tuple('+%s' % b for b in backends)
265 imply_option('--build-backends', build_backend)
268 @depends('--enable-artifact-builds', '--disable-compile-environment',
269          '--enable-build-backend', '--help')
270 @imports('sys')
271 def build_backend_defaults(artifact_builds, compile_environment, requested_backends,
272                            _):
273     if 'Tup' in requested_backends:
274         # As a special case, if Tup was requested, do not combine it with any
275         # Make based backend by default.
276         all_backends = []
277     elif artifact_builds:
278         all_backends = ['FasterMake+RecursiveMake']
279     else:
280         all_backends = ['RecursiveMake', 'FasterMake']
281     # Normally, we'd use target.os == 'WINNT', but a dependency on target
282     # would require target to depend on --help, as well as host and shell,
283     # and this is not a can of worms we can open at the moment.
284     if sys.platform == 'win32' and compile_environment:
285         all_backends.append('VisualStudio')
286     return tuple(all_backends) or None
288 option('--build-backends', nargs='+', default=build_backend_defaults,
289        choices=build_backends_choices, help='Build backends to generate')
291 @depends('--build-backends')
292 def build_backends(backends):
293     return backends
295 set_config('BUILD_BACKENDS', build_backends)
298 @depends(check_build_environment, build_backends)
299 @imports('glob')
300 def check_objdir_backend_reuse(build_env, backends):
301     # "Make based" might be RecursiveMake or a hybrid backend, so "Make" is
302     # intentionally vague for use with the substring match below.
303     incompatible_backends = (
304         ('Tup', 'Make'),
305         ('Make', 'Tup')
306     )
307     for backend_file in glob.iglob(os.path.join(build_env.topobjdir,
308                                                 'backend.*Backend')):
309         for prev, curr in incompatible_backends:
310             if prev in backend_file and any(curr in b for b in backends):
311                 die("The active objdir, %s, was previously "
312                     "used to build with a %s based backend. "
313                     "Change objdirs (by setting MOZ_OBJDIR in "
314                     "your mozconfig) or clobber to continue.\n",
315                     build_env.topobjdir, prev)
318 option('--disable-gtest-in-build',
319        help='Force disable building the gtest libxul during the build.',
320        when='--enable-compile-environment')
322 # Determine whether to build the gtest xul. This happens in automation
323 # on Desktop platforms with the exception of Windows PGO, where linking
324 # xul-gtest.dll takes too long.
325 @depends('MOZ_PGO', build_project, target, 'MOZ_AUTOMATION', '--disable-gtest-in-build',
326          enable_tests, when='--enable-compile-environment')
327 def build_gtest(pgo, build_project, target, automation, enabled, enable_tests):
328     if not enable_tests or not enabled:
329         return None
330     if (automation and build_project == 'browser' and
331         not (pgo and target.os == 'WINNT')):
332         return True
334 set_config('LINK_GTEST_DURING_COMPILE', build_gtest)
336 # Localization
337 # ==============================================================
338 option('--enable-ui-locale', default='en-US',
339        help='Select the user interface locale (default: en-US)')
341 set_config('MOZ_UI_LOCALE', depends('--enable-ui-locale')(lambda x: x))
343 # clang-plugin location
344 # ==============================================================
345 @depends(host_library_name_info, check_build_environment,
346          when='--enable-clang-plugin')
347 def clang_plugin_path(library_name_info, build_env):
348     topobjdir = build_env.topobjdir
349     if topobjdir.endswith('/js/src'):
350         topobjdir = topobjdir[:-7]
351     return os.path.abspath(
352         os.path.join(topobjdir, 'build', 'clang-plugin',
353                      '%sclang-plugin%s' % (library_name_info.dll.prefix,
354                                            library_name_info.dll.suffix))
355     )
357 add_old_configure_assignment('CLANG_PLUGIN', clang_plugin_path)
360 # Awk detection
361 # ==============================================================
362 awk = check_prog('AWK', ('gawk', 'mawk', 'nawk', 'awk'))
364 # Until the AWK variable is not necessary in old-configure
365 @depends(awk)
366 def awk_for_old_configure(value):
367     return value
369 add_old_configure_assignment('AWK', awk_for_old_configure)
372 # Perl detection
373 # ==============================================================
374 perl = check_prog('PERL', ('perl5', 'perl'))
376 # Until the PERL variable is not necessary in old-configure
377 @depends(perl)
378 def perl_for_old_configure(value):
379     return value
381 add_old_configure_assignment('PERL', perl_for_old_configure)
383 @template
384 def perl_version_check(min_version):
385     @depends(perl)
386     @checking('for minimum required perl version >= %s' % min_version)
387     def get_perl_version(perl):
388         return Version(check_cmd_output(
389             perl, '-e', 'print $]',
390             onerror=lambda: die('Failed to get perl version.')
391         ))
393     @depends(get_perl_version)
394     def check_perl_version(version):
395         if version < min_version:
396             die('Perl %s or higher is required.', min_version)
398     @depends(perl)
399     @checking('for full perl installation')
400     @imports('subprocess')
401     def has_full_perl_installation(perl):
402         ret = subprocess.call(
403             [perl, '-e', 'use Config; exit(!-d $Config{archlib})'])
404         return ret == 0
406     @depends(has_full_perl_installation)
407     def require_full_perl_installation(has_full_perl_installation):
408         if not has_full_perl_installation:
409             die('Cannot find Config.pm or $Config{archlib}. '
410                 'A full perl installation is required.')
412 perl_version_check('5.006')
415 # GNU make detection
416 # ==============================================================
417 option(env='MAKE', nargs=1, help='Path to GNU make')
419 @depends('MAKE', host)
420 def possible_makes(make, host):
421     candidates = []
422     if host.kernel == 'WINNT':
423         candidates.append('mingw32-make')
424     if make:
425         candidates.append(make[0])
426     if host.kernel == 'WINNT':
427         candidates.extend(('make', 'gmake'))
428     else:
429         candidates.extend(('gmake', 'make'))
430     return candidates
432 check_prog('GMAKE', possible_makes)
434 @depends(build_backends, build_project)
435 def tup_include(build_backends, build_project):
436     # We need to check the rustc version when building with tup, but
437     # rustc_info isn't available when configuring js (and build_backends isn't
438     # available from project-specific configure), so as a workaround we only
439     # include the file when we know we'll need it. This can be removed when
440     # we globally require a rustc recent enough to build with tup.
441     if build_project not in ('browser', 'mobile/android'):
442         return None
443     for backend in build_backends:
444         if 'Tup' in backend:
445             return 'build/moz.configure/tup.configure'
447 include(tup_include)
449 # watchman detection
450 # ==============================================================
452 option(env='WATCHMAN', nargs=1, help='Path to the watchman program')
454 @depends('WATCHMAN')
455 @checking('for watchman', callback=lambda w: w.path if w else 'not found')
456 def watchman(prog):
457     if not prog:
458         prog = find_program('watchman')
460     if not prog:
461         return
463     # `watchman version` will talk to the Watchman daemon service.
464     # This can hang due to permissions problems. e.g.
465     # https://github.com/facebook/watchman/issues/376. So use
466     # `watchman --version` to prevent a class of failures.
467     out = check_cmd_output(prog, '--version', onerror=lambda: None)
468     if out is None:
469         return
471     return namespace(path=prog, version=Version(out.strip()))
473 @depends_if(watchman)
474 @checking('for watchman version')
475 def watchman_version(w):
476     return w.version
478 set_config('WATCHMAN', watchman.path)
480 @depends_all(hg_version, hg_config, watchman)
481 @checking('for watchman Mercurial integration')
482 @imports('os')
483 def watchman_hg(hg_version, hg_config, watchman):
484     if hg_version < Version('3.8'):
485         return 'no (Mercurial 3.8+ required)'
487     ext_enabled = False
488     mode_disabled = False
490     for k in ('extensions.fsmonitor', 'extensions.hgext.fsmonitor'):
491         if k in hg_config and hg_config[k] != '!':
492             ext_enabled = True
494     mode_disabled = hg_config.get('fsmonitor.mode') == 'off'
496     if not ext_enabled:
497         return 'no (fsmonitor extension not enabled)'
498     if mode_disabled:
499         return 'no (fsmonitor.mode=off disables fsmonitor)'
501     return True
503 # Miscellaneous programs
504 # ==============================================================
505 check_prog('XARGS', ('xargs',))
507 @depends(target)
508 def extra_programs(target):
509     if target.kernel == 'Darwin':
510         return namespace(
511             DSYMUTIL=('dsymutil', 'llvm-dsymutil'),
512             MKFSHFS=('newfs_hfs', 'mkfs.hfsplus'),
513             HFS_TOOL=('hfsplus',)
514         )
515     if target.os == 'GNU' and target.kernel == 'Linux':
516         return namespace(RPMBUILD=('rpmbuild',))
518 check_prog('DSYMUTIL', extra_programs.DSYMUTIL,
519            allow_missing=True)
520 check_prog('MKFSHFS', extra_programs.MKFSHFS,
521            allow_missing=True)
522 check_prog('HFS_TOOL', extra_programs.HFS_TOOL,
523            allow_missing=True)
524 check_prog('RPMBUILD', extra_programs.RPMBUILD,
525            allow_missing=True)
528 @depends(target)
529 @imports('os')
530 def makensis_progs(target):
531     if target.kernel != 'WINNT':
532         return
534     candidates = [
535         'makensis-3.01',
536         'makensis-3.0b3',
537         'makensis-3.0b1',
538         'makensis',
539     ]
541     # Look for nsis installed by msys environment. But only the 32-bit version.
542     # We use an absolute path and insert as the first entry so it is preferred
543     # over a 64-bit exe that may be in PATH.
544     if 'MSYSTEM_PREFIX' in os.environ:
545         prefix = os.path.dirname(os.environ['MSYSTEM_PREFIX'])
546         candidates.insert(0, os.path.join(prefix, 'mingw32', 'bin', 'makensis.exe'))
548     return tuple(candidates)
550 nsis = check_prog('MAKENSISU', makensis_progs, allow_missing=True)
552 # Make sure the version of makensis is up to date.
553 @depends_if(nsis)
554 @checking('for NSIS version')
555 @imports('re')
556 def nsis_version(nsis):
557     nsis_min_version = '3.0b1'
558     out = check_cmd_output(nsis, '-version',
559                            onerror=lambda: die('Failed to get nsis version.'))
560     m = re.search(r'(?<=v)[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?', out)
562     if not m:
563         raise FatalCheckError('Unknown version of makensis')
564     ver = Version(m.group(0))
566     # Versions comparisons don't quite work well with beta versions, so ensure
567     # it works for the non-beta version.
568     if ver < nsis_min_version and (ver >= '3.0a' or ver < '3'):
569         raise FatalCheckError('To build the installer you must have NSIS'
570                               ' version %s or greater in your path'
571                               % nsis_min_version)
573     return ver
575 # And that makensis is 32-bit (but only on Windows).
576 @depends_if(nsis, when=depends(host)(lambda h: h.kernel == 'WINNT'))
577 @checking('for 32-bit NSIS')
578 def nsis_binary_type(nsis):
579     bin_type = windows_binary_type(nsis)
580     if bin_type != 'win32':
581         raise FatalCheckError('%s is not a 32-bit Windows application' % nsis)
583     return 'yes'
585 # And any flags we have to give to makensis
586 @depends(host)
587 def nsis_flags(host):
588     if host.kernel != 'WINNT':
589         return '-nocd'
590     return ''
592 set_config('MAKENSISU_FLAGS', nsis_flags)
594 check_prog('7Z', ('7z', '7za'), allow_missing=True, when=target_is_windows)
596 # Fallthrough to autoconf-based configure
597 include('build/moz.configure/old.configure')
599 @depends(check_build_environment, build_project)
600 @imports('__sandbox__')
601 @imports('glob')
602 def config_status_deps(build_env, build_project):
604     topsrcdir = build_env.topsrcdir
605     topobjdir = build_env.topobjdir
607     if not build_env.topobjdir.endswith('js/src'):
608         extra_deps = [
609             os.path.join(topsrcdir, build_project, 'confvars.sh'),
610             os.path.join(topobjdir, '.mozconfig.json'),
611         ]
612     else:
613         # mozconfig changes may impact js configure.
614         extra_deps = [os.path.join(topobjdir[:-7], '.mozconfig.json')]
616     return list(__sandbox__._all_paths) + extra_deps + [
617         os.path.join(topsrcdir, 'CLOBBER'),
618         os.path.join(topsrcdir, 'configure'),
619         os.path.join(topsrcdir, 'js', 'src', 'configure'),
620         os.path.join(topsrcdir, 'configure.in'),
621         os.path.join(topsrcdir, 'js', 'src', 'configure.in'),
622         os.path.join(topsrcdir, 'nsprpub', 'configure'),
623         os.path.join(topsrcdir, 'config', 'milestone.txt'),
624         os.path.join(topsrcdir, 'browser', 'config', 'version.txt'),
625         os.path.join(topsrcdir, 'browser', 'config', 'version_display.txt'),
626         os.path.join(topsrcdir, 'build', 'virtualenv_packages.txt'),
627         os.path.join(topsrcdir, 'python', 'mozbuild', 'mozbuild', 'virtualenv.py'),
628         os.path.join(topsrcdir, 'testing', 'mozbase', 'packages.txt'),
629         os.path.join(topsrcdir, 'aclocal.m4'),
630         os.path.join(topsrcdir, 'old-configure.in'),
631         os.path.join(topsrcdir, 'js', 'src', 'aclocal.m4'),
632         os.path.join(topsrcdir, 'js', 'src', 'old-configure.in'),
633     ] + glob.glob(os.path.join(topsrcdir, 'build', 'autoconf', '*.m4'))
635 set_config('CONFIG_STATUS_DEPS', config_status_deps)
636 # Please do not add anything after setting config_dep_paths.