Bug 1500160 [wpt PR 13600] - Add tests for simple dialog newline normalization, a...
[gecko.git] / moz.configure
bloba99d38f7f38e2e2d0baae0580ee1bde35a6252b8
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 @depends(enable_tests)
73 def gtest_has_rtti(value):
74     if value:
75         return '0'
77 set_define('GTEST_HAS_RTTI', gtest_has_rtti)
79 @depends(target, enable_tests)
80 def linux_gtest_defines(target, enable_tests):
81     if enable_tests and target.os == 'Android':
82         return namespace(os_linux_android=True,
83                          use_own_tr1_tuple=True,
84                          has_clone='0')
86 set_define('GTEST_OS_LINUX_ANDROID',
87            linux_gtest_defines.os_linux_android)
88 set_define('GTEST_USE_OWN_TR1_TUPLE',
89            linux_gtest_defines.use_own_tr1_tuple)
90 set_define('GTEST_HAS_CLONE',
91            linux_gtest_defines.has_clone)
93 js_option('--enable-debug',
94           nargs='?',
95           help='Enable building with developer debug info '
96                '(using the given compiler flags).')
98 @depends('--enable-debug')
99 def moz_debug(debug):
100     if debug:
101         return bool(debug)
103 set_config('MOZ_DEBUG', moz_debug)
104 set_define('MOZ_DEBUG', moz_debug)
105 # Override any value MOZ_DEBUG may have from the environment when passing it
106 # down to old-configure.
107 add_old_configure_assignment('MOZ_DEBUG',
108                              depends('--enable-debug')(lambda x: bool(x)))
110 js_option('--enable-rust-debug',
111           default=depends(when='--enable-debug')(lambda: True),
112           help='{Build|Do not build} Rust code with debug assertions turned '
113                'on.')
115 @depends(when='--enable-rust-debug')
116 def debug_rust():
117     return True
119 set_config('MOZ_DEBUG_RUST', debug_rust)
120 set_define('MOZ_DEBUG_RUST', debug_rust)
122 include('build/moz.configure/pkg.configure')
123 # Make this assignment here rather than in pkg.configure to avoid
124 # requiring this file in unit tests.
125 add_old_configure_assignment('PKG_CONFIG', pkg_config)
127 include('build/moz.configure/toolchain.configure',
128         when='--enable-compile-environment')
129 include('build/moz.configure/memory.configure',
130         when='--enable-compile-environment')
131 include('build/moz.configure/headers.configure',
132         when='--enable-compile-environment')
133 include('build/moz.configure/warnings.configure',
134         when='--enable-compile-environment')
135 include('build/moz.configure/flags.configure',
136         when='--enable-compile-environment')
137 # rust.configure is included by js/moz.configure.
139 js_option('--enable-valgrind',
140           help='Enable Valgrind integration hooks')
142 valgrind_h = check_header('valgrind/valgrind.h', when='--enable-valgrind')
144 @depends('--enable-valgrind', valgrind_h)
145 def check_valgrind(valgrind, valgrind_h):
146     if valgrind:
147         if not valgrind_h:
148             die('--enable-valgrind specified but Valgrind is not installed')
149         return True
151 set_define('MOZ_VALGRIND', check_valgrind)
152 set_config('MOZ_VALGRIND', check_valgrind)
154 @depends(target, host)
155 def is_openbsd(target, host):
156     return target.kernel == 'OpenBSD' or host.kernel == 'OpenBSD'
158 option(env='SO_VERSION', nargs=1, default='1.0', when=is_openbsd,
159        help='Shared library version for OpenBSD systems')
161 @depends('SO_VERSION', when=is_openbsd)
162 def so_version(value):
163     return value
165 @template
166 def library_name_info_template(host_or_target):
167     assert host_or_target in {host, target}
168     compiler = {
169         host: host_c_compiler,
170         target: c_compiler,
171     }[host_or_target]
173     @depends(host_or_target, compiler, so_version)
174     def library_name_info_impl(host_or_target, compiler, so_version):
175         if host_or_target.kernel == 'WINNT':
176             # There aren't artifacts for mingw builds, so it's OK that the
177             # results are inaccurate in that case.
178             if compiler and compiler.type not in ('msvc', 'clang-cl'):
179                 return namespace(
180                     dll=namespace(prefix='', suffix='.dll'),
181                     lib=namespace(prefix='lib', suffix='a'),
182                     import_lib=namespace(prefix='lib', suffix='a'),
183                     rust_lib=namespace(prefix='', suffix='lib'),
184                     obj=namespace(prefix='', suffix='o'),
185                 )
187             return namespace(
188                 dll=namespace(prefix='', suffix='.dll'),
189                 lib=namespace(prefix='', suffix='lib'),
190                 import_lib=namespace(prefix='', suffix='lib'),
191                 rust_lib=namespace(prefix='', suffix='lib'),
192                 obj=namespace(prefix='', suffix='obj'),
193             )
195         elif host_or_target.kernel == 'Darwin':
196             return namespace(
197                 dll=namespace(prefix='lib', suffix='.dylib'),
198                 lib=namespace(prefix='lib', suffix='a'),
199                 import_lib=namespace(prefix=None, suffix=''),
200                 rust_lib=namespace(prefix='lib', suffix='a'),
201                 obj=namespace(prefix='', suffix='o'),
202             )
203         elif so_version:
204             so = '.so.%s' % so_version
205         else:
206             so = '.so'
208         return namespace(
209             dll=namespace(prefix='lib', suffix=so),
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         )
216     return library_name_info_impl
218 host_library_name_info = library_name_info_template(host)
219 library_name_info = library_name_info_template(target)
221 set_config('DLL_PREFIX', library_name_info.dll.prefix)
222 set_config('DLL_SUFFIX', library_name_info.dll.suffix)
223 set_config('HOST_DLL_PREFIX', host_library_name_info.dll.prefix)
224 set_config('HOST_DLL_SUFFIX', host_library_name_info.dll.suffix)
225 set_config('LIB_PREFIX', library_name_info.lib.prefix)
226 set_config('LIB_SUFFIX', library_name_info.lib.suffix)
227 set_config('RUST_LIB_PREFIX', library_name_info.rust_lib.prefix)
228 set_config('RUST_LIB_SUFFIX', library_name_info.rust_lib.suffix)
229 set_config('OBJ_SUFFIX', library_name_info.obj.suffix)
230 # Lots of compilation tests depend on this variable being present.
231 add_old_configure_assignment('OBJ_SUFFIX', library_name_info.obj.suffix)
232 set_config('IMPORT_LIB_SUFFIX', library_name_info.import_lib.suffix)
233 set_define('MOZ_DLL_PREFIX', depends(library_name_info.dll.prefix)(lambda s: '"%s"' % s))
234 set_define('MOZ_DLL_SUFFIX', depends(library_name_info.dll.suffix)(lambda s: '"%s"' % s))
236 # Depends on host_library_name_info, so needs to go here.
237 include('build/moz.configure/bindgen.configure',
238         when='--enable-compile-environment')
239 include(include_project_configure)
241 @depends('--help')
242 @imports(_from='mozbuild.backend', _import='backends')
243 def build_backends_choices(_):
244     return tuple(backends)
247 @deprecated_option('--enable-build-backend', nargs='+',
248                    choices=build_backends_choices)
249 def build_backend(backends):
250     if backends:
251         return tuple('+%s' % b for b in backends)
253 imply_option('--build-backends', build_backend)
256 @depends('--enable-artifact-builds', '--disable-compile-environment',
257          '--enable-build-backend', '--help')
258 @imports('sys')
259 def build_backend_defaults(artifact_builds, compile_environment, requested_backends,
260                            _):
261     if 'Tup' in requested_backends:
262         # As a special case, if Tup was requested, do not combine it with any
263         # Make based backend by default.
264         all_backends = []
265     elif artifact_builds:
266         all_backends = ['FasterMake+RecursiveMake']
267     else:
268         all_backends = ['RecursiveMake', 'FasterMake']
269     # Normally, we'd use target.os == 'WINNT', but a dependency on target
270     # would require target to depend on --help, as well as host and shell,
271     # and this is not a can of worms we can open at the moment.
272     if sys.platform == 'win32' and compile_environment:
273         all_backends.append('VisualStudio')
274     return tuple(all_backends) or None
276 option('--build-backends', nargs='+', default=build_backend_defaults,
277        choices=build_backends_choices, help='Build backends to generate')
279 @depends('--build-backends')
280 def build_backends(backends):
281     return backends
283 set_config('BUILD_BACKENDS', build_backends)
286 @depends(check_build_environment, build_backends)
287 @imports('glob')
288 def check_objdir_backend_reuse(build_env, backends):
289     # "Make based" might be RecursiveMake or a hybrid backend, so "Make" is
290     # intentionally vague for use with the substring match below.
291     incompatible_backends = (
292         ('Tup', 'Make'),
293         ('Make', 'Tup')
294     )
295     for backend_file in glob.iglob(os.path.join(build_env.topobjdir,
296                                                 'backend.*Backend')):
297         for prev, curr in incompatible_backends:
298             if prev in backend_file and any(curr in b for b in backends):
299                 die("The active objdir, %s, was previously "
300                     "used to build with a %s based backend. "
301                     "Change objdirs (by setting MOZ_OBJDIR in "
302                     "your mozconfig) or clobber to continue.\n",
303                     build_env.topobjdir, prev)
306 option('--disable-gtest-in-build',
307        help='Force disable building the gtest libxul during the build.',
308        when='--enable-compile-environment')
310 # Determine whether to build the gtest xul. This happens in automation
311 # on Desktop platforms with the exception of Windows PGO, where linking
312 # xul-gtest.dll takes too long.
313 @depends('MOZ_PGO', build_project, target, 'MOZ_AUTOMATION', '--disable-gtest-in-build',
314          enable_tests, when='--enable-compile-environment')
315 def build_gtest(pgo, build_project, target, automation, enabled, enable_tests):
316     if not enable_tests or not enabled:
317         return None
318     if (automation and build_project == 'browser' and
319         not (pgo and target.os == 'WINNT')):
320         return True
322 set_config('LINK_GTEST_DURING_COMPILE', build_gtest)
324 # Localization
325 # ==============================================================
326 option('--enable-ui-locale', default='en-US',
327        help='Select the user interface locale (default: en-US)')
329 set_config('MOZ_UI_LOCALE', depends('--enable-ui-locale')(lambda x: x))
331 # clang-plugin location
332 # ==============================================================
333 @depends(host_library_name_info, check_build_environment,
334          when='--enable-clang-plugin')
335 def clang_plugin_path(library_name_info, build_env):
336     topobjdir = build_env.topobjdir
337     if topobjdir.endswith('/js/src'):
338         topobjdir = topobjdir[:-7]
339     return os.path.abspath(
340         os.path.join(topobjdir, 'build', 'clang-plugin',
341                      '%sclang-plugin%s' % (library_name_info.dll.prefix,
342                                            library_name_info.dll.suffix))
343     )
345 add_old_configure_assignment('CLANG_PLUGIN', clang_plugin_path)
348 # Awk detection
349 # ==============================================================
350 awk = check_prog('AWK', ('gawk', 'mawk', 'nawk', 'awk'))
352 # Until the AWK variable is not necessary in old-configure
353 @depends(awk)
354 def awk_for_old_configure(value):
355     return value
357 add_old_configure_assignment('AWK', awk_for_old_configure)
360 # Perl detection
361 # ==============================================================
362 perl = check_prog('PERL', ('perl5', 'perl'))
364 # Until the PERL variable is not necessary in old-configure
365 @depends(perl)
366 def perl_for_old_configure(value):
367     return value
369 add_old_configure_assignment('PERL', perl_for_old_configure)
371 @template
372 def perl_version_check(min_version):
373     @depends(perl)
374     @checking('for minimum required perl version >= %s' % min_version)
375     def get_perl_version(perl):
376         return Version(check_cmd_output(
377             perl, '-e', 'print $]',
378             onerror=lambda: die('Failed to get perl version.')
379         ))
381     @depends(get_perl_version)
382     def check_perl_version(version):
383         if version < min_version:
384             die('Perl %s or higher is required.', min_version)
386     @depends(perl)
387     @checking('for full perl installation')
388     @imports('subprocess')
389     def has_full_perl_installation(perl):
390         ret = subprocess.call(
391             [perl, '-e', 'use Config; exit(!-d $Config{archlib})'])
392         return ret == 0
394     @depends(has_full_perl_installation)
395     def require_full_perl_installation(has_full_perl_installation):
396         if not has_full_perl_installation:
397             die('Cannot find Config.pm or $Config{archlib}. '
398                 'A full perl installation is required.')
400 perl_version_check('5.006')
403 # GNU make detection
404 # ==============================================================
405 option(env='MAKE', nargs=1, help='Path to GNU make')
407 @depends('MAKE', host)
408 def possible_makes(make, host):
409     candidates = []
410     if host.kernel == 'WINNT':
411         candidates.append('mingw32-make')
412     if make:
413         candidates.append(make[0])
414     if host.kernel == 'WINNT':
415         candidates.extend(('make', 'gmake'))
416     else:
417         candidates.extend(('gmake', 'make'))
418     return candidates
420 check_prog('GMAKE', possible_makes)
422 @depends(build_backends, build_project)
423 def tup_include(build_backends, build_project):
424     # We need to check the rustc version when building with tup, but
425     # rustc_info isn't available when configuring js (and build_backends isn't
426     # available from project-specific configure), so as a workaround we only
427     # include the file when we know we'll need it. This can be removed when
428     # we globally require a rustc recent enough to build with tup.
429     if build_project not in ('browser', 'mobile/android'):
430         return None
431     for backend in build_backends:
432         if 'Tup' in backend:
433             return 'build/moz.configure/tup.configure'
435 include(tup_include)
437 # watchman detection
438 # ==============================================================
440 option(env='WATCHMAN', nargs=1, help='Path to the watchman program')
442 @depends('WATCHMAN')
443 @checking('for watchman', callback=lambda w: w.path if w else 'not found')
444 def watchman(prog):
445     if not prog:
446         prog = find_program('watchman')
448     if not prog:
449         return
451     # `watchman version` will talk to the Watchman daemon service.
452     # This can hang due to permissions problems. e.g.
453     # https://github.com/facebook/watchman/issues/376. So use
454     # `watchman --version` to prevent a class of failures.
455     out = check_cmd_output(prog, '--version', onerror=lambda: None)
456     if out is None:
457         return
459     return namespace(path=prog, version=Version(out.strip()))
461 @depends_if(watchman)
462 @checking('for watchman version')
463 def watchman_version(w):
464     return w.version
466 set_config('WATCHMAN', watchman.path)
468 @depends_all(hg_version, hg_config, watchman)
469 @checking('for watchman Mercurial integration')
470 @imports('os')
471 def watchman_hg(hg_version, hg_config, watchman):
472     if hg_version < Version('3.8'):
473         return 'no (Mercurial 3.8+ required)'
475     ext_enabled = False
476     mode_disabled = False
478     for k in ('extensions.fsmonitor', 'extensions.hgext.fsmonitor'):
479         if k in hg_config and hg_config[k] != '!':
480             ext_enabled = True
482     mode_disabled = hg_config.get('fsmonitor.mode') == 'off'
484     if not ext_enabled:
485         return 'no (fsmonitor extension not enabled)'
486     if mode_disabled:
487         return 'no (fsmonitor.mode=off disables fsmonitor)'
489     return True
491 # Miscellaneous programs
492 # ==============================================================
493 check_prog('XARGS', ('xargs',))
495 @depends(target)
496 def extra_programs(target):
497     if target.kernel == 'Darwin':
498         return namespace(
499             DSYMUTIL=('dsymutil', 'llvm-dsymutil'),
500             MKFSHFS=('newfs_hfs', 'mkfs.hfsplus'),
501             HFS_TOOL=('hfsplus',)
502         )
503     if target.os == 'GNU' and target.kernel == 'Linux':
504         return namespace(RPMBUILD=('rpmbuild',))
506 check_prog('DSYMUTIL', extra_programs.DSYMUTIL,
507            allow_missing=True)
508 check_prog('MKFSHFS', extra_programs.MKFSHFS,
509            allow_missing=True)
510 check_prog('HFS_TOOL', extra_programs.HFS_TOOL,
511            allow_missing=True)
512 check_prog('RPMBUILD', extra_programs.RPMBUILD,
513            allow_missing=True)
516 @depends(target)
517 @imports('os')
518 def makensis_progs(target):
519     if target.kernel != 'WINNT':
520         return
522     candidates = [
523         'makensis-3.01',
524         'makensis-3.0b3',
525         'makensis-3.0b1',
526         'makensis',
527     ]
529     # Look for nsis installed by msys environment. But only the 32-bit version.
530     # We use an absolute path and insert as the first entry so it is preferred
531     # over a 64-bit exe that may be in PATH.
532     if 'MSYSTEM_PREFIX' in os.environ:
533         prefix = os.path.dirname(os.environ['MSYSTEM_PREFIX'])
534         candidates.insert(0, os.path.join(prefix, 'mingw32', 'bin', 'makensis.exe'))
536     return tuple(candidates)
538 nsis = check_prog('MAKENSISU', makensis_progs, allow_missing=True)
540 # Make sure the version of makensis is up to date.
541 @depends_if(nsis)
542 @checking('for NSIS version')
543 @imports('re')
544 def nsis_version(nsis):
545     nsis_min_version = '3.0b1'
546     out = check_cmd_output(nsis, '-version',
547                            onerror=lambda: die('Failed to get nsis version.'))
548     m = re.search(r'(?<=v)[0-9]+\.[0-9]+((a|b|rc)[0-9]+)?', out)
550     if not m:
551         raise FatalCheckError('Unknown version of makensis')
552     ver = Version(m.group(0))
554     # Versions comparisons don't quite work well with beta versions, so ensure
555     # it works for the non-beta version.
556     if ver < nsis_min_version and (ver >= '3.0a' or ver < '3'):
557         raise FatalCheckError('To build the installer you must have NSIS'
558                               ' version %s or greater in your path'
559                               % nsis_min_version)
561     return ver
563 # And that makensis is 32-bit (but only on Windows).
564 @depends_if(nsis, when=depends(host)(lambda h: h.kernel == 'WINNT'))
565 @checking('for 32-bit NSIS')
566 def nsis_binary_type(nsis):
567     bin_type = windows_binary_type(nsis)
568     if bin_type != 'win32':
569         raise FatalCheckError('%s is not a 32-bit Windows application' % nsis)
571     return 'yes'
573 # And any flags we have to give to makensis
574 @depends(host)
575 def nsis_flags(host):
576     if host.kernel != 'WINNT':
577         return '-nocd'
578     return ''
580 set_config('MAKENSISU_FLAGS', nsis_flags)
582 check_prog('7Z', ('7z', '7za'), allow_missing=True, when=target_is_windows)
584 # Fallthrough to autoconf-based configure
585 include('build/moz.configure/old.configure')
587 @depends(check_build_environment, build_project)
588 @imports('__sandbox__')
589 @imports('glob')
590 def config_status_deps(build_env, build_project):
592     topsrcdir = build_env.topsrcdir
593     topobjdir = build_env.topobjdir
595     if not build_env.topobjdir.endswith('js/src'):
596         extra_deps = [
597             os.path.join(topsrcdir, build_project, 'confvars.sh'),
598             os.path.join(topobjdir, '.mozconfig.json'),
599         ]
600     else:
601         # mozconfig changes may impact js configure.
602         extra_deps = [os.path.join(topobjdir[:-7], '.mozconfig.json')]
604     return list(__sandbox__._all_paths) + extra_deps + [
605         os.path.join(topsrcdir, 'CLOBBER'),
606         os.path.join(topsrcdir, 'configure'),
607         os.path.join(topsrcdir, 'js', 'src', 'configure'),
608         os.path.join(topsrcdir, 'configure.in'),
609         os.path.join(topsrcdir, 'js', 'src', 'configure.in'),
610         os.path.join(topsrcdir, 'nsprpub', 'configure'),
611         os.path.join(topsrcdir, 'config', 'milestone.txt'),
612         os.path.join(topsrcdir, 'browser', 'config', 'version.txt'),
613         os.path.join(topsrcdir, 'browser', 'config', 'version_display.txt'),
614         os.path.join(topsrcdir, 'build', 'virtualenv_packages.txt'),
615         os.path.join(topsrcdir, 'python', 'mozbuild', 'mozbuild', 'virtualenv.py'),
616         os.path.join(topsrcdir, 'testing', 'mozbase', 'packages.txt'),
617         os.path.join(topsrcdir, 'aclocal.m4'),
618         os.path.join(topsrcdir, 'old-configure.in'),
619         os.path.join(topsrcdir, 'js', 'src', 'aclocal.m4'),
620         os.path.join(topsrcdir, 'js', 'src', 'old-configure.in'),
621     ] + glob.glob(os.path.join(topsrcdir, 'build', 'autoconf', '*.m4'))
623 set_config('CONFIG_STATUS_DEPS', config_status_deps)
624 # Please do not add anything after setting config_dep_paths.