diff options
Diffstat (limited to 'build/moz.configure/init.configure')
-rw-r--r-- | build/moz.configure/init.configure | 780 |
1 files changed, 780 insertions, 0 deletions
diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure new file mode 100644 index 000000000..2123bebc9 --- /dev/null +++ b/build/moz.configure/init.configure @@ -0,0 +1,780 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +include('util.configure') +include('checks.configure') + +option(env='DIST', nargs=1, help='DIST directory') + +# Do not allow objdir == srcdir builds. +# ============================================================== +@depends('--help', 'DIST') +@imports(_from='os.path', _import='exists') +def check_build_environment(help, dist): + topobjdir = os.path.realpath(os.path.abspath('.')) + topsrcdir = os.path.realpath(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..', '..'))) + + if dist: + dist = normsep(dist[0]) + else: + dist = os.path.join(topobjdir, 'dist') + + result = namespace( + topsrcdir=topsrcdir, + topobjdir=topobjdir, + dist=dist, + ) + + if help: + return result + + if topsrcdir == topobjdir: + die(' ***\n' + ' * Building directly in the main source directory is not allowed.\n' + ' *\n' + ' * To build, you must run configure from a separate directory\n' + ' * (referred to as an object directory).\n' + ' *\n' + ' * If you are building with a mozconfig, you will need to change your\n' + ' * mozconfig to point to a different object directory.\n' + ' ***' + ) + + # Check for a couple representative files in the source tree + conflict_files = [ + '* %s' % f for f in ('Makefile', 'config/autoconf.mk') + if exists(os.path.join(topsrcdir, f)) + ] + if conflict_files: + die(' ***\n' + ' * Your source tree contains these files:\n' + ' %s\n' + ' * This indicates that you previously built in the source tree.\n' + ' * A source tree build can confuse the separate objdir build.\n' + ' *\n' + ' * To clean up the source tree:\n' + ' * 1. cd %s\n' + ' * 2. gmake distclean\n' + ' ***' + % ('\n '.join(conflict_files), topsrcdir) + ) + + return result + +set_config('TOPSRCDIR', delayed_getattr(check_build_environment, 'topsrcdir')) +set_config('TOPOBJDIR', delayed_getattr(check_build_environment, 'topobjdir')) +set_config('MOZ_BUILD_ROOT', delayed_getattr(check_build_environment, + 'topobjdir')) +set_config('DIST', delayed_getattr(check_build_environment, 'dist')) + + +option(env='MOZ_AUTOMATION', help='Enable options for automated builds') +set_config('MOZ_AUTOMATION', depends_if('MOZ_AUTOMATION')(lambda x: True)) + + +option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script') + +option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project') +option(env='MOZCONFIG', nargs=1, help='Mozconfig location') + +# Read user mozconfig +# ============================================================== +# Note: the dependency on --help is only there to always read the mozconfig, +# even when --help is passed. Without this dependency, the function wouldn't +# be called when --help is passed, and the mozconfig wouldn't be read. +@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', 'OLD_CONFIGURE', + check_build_environment, '--help') +@imports(_from='mozbuild.mozconfig', _import='MozconfigLoader') +def mozconfig(current_project, mozconfig, old_configure, build_env, help): + if not old_configure: + die('The OLD_CONFIGURE environment variable must be set') + + # Don't read the mozconfig for the js configure (yay backwards + # compatibility) + # While the long term goal is that js and top-level use the same configure + # and the same overall setup, including the possibility to use mozconfigs, + # figuring out what we want to do wrt mozconfig vs. command line and + # environment variable is not a clear-cut case, and it's more important to + # fix the immediate problem mozconfig causes to js developers by + # "temporarily" returning to the previous behavior of not loading the + # mozconfig for the js configure. + # Separately to the immediate problem for js developers, there is also the + # need to not load a mozconfig when running js configure as a subconfigure. + # Unfortunately, there is no direct way to tell whether the running + # configure is the js configure. The indirect way is to look at the + # OLD_CONFIGURE path, which points to js/src/old-configure. + # I expect we'll have figured things out for mozconfigs well before + # old-configure dies. + if os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'): + return {'path': None} + + loader = MozconfigLoader(build_env.topsrcdir) + current_project = current_project[0] if current_project else None + mozconfig = mozconfig[0] if mozconfig else None + mozconfig = loader.find_mozconfig(env={'MOZCONFIG': mozconfig}) + mozconfig = loader.read_mozconfig(mozconfig, moz_build_app=current_project) + + return mozconfig + +set_config('MOZCONFIG', depends(mozconfig)(lambda m: m['path'])) + + +option(env='PYTHON', nargs=1, help='Python interpreter') + +# Setup python virtualenv +# ============================================================== +@depends('PYTHON', check_build_environment, mozconfig, '--help') +@imports('os') +@imports('sys') +@imports('subprocess') +@imports(_from='mozbuild.configure.util', _import='LineIO') +@imports(_from='mozbuild.virtualenv', _import='VirtualenvManager') +@imports(_from='mozbuild.virtualenv', _import='verify_python_version') +@imports('distutils.sysconfig') +def virtualenv_python(env_python, build_env, mozconfig, help): + if help: + return + + python = env_python[0] if env_python else None + + # Ideally we'd rely on the mozconfig injection from mozconfig_options, + # but we'd rather avoid the verbosity when we need to reexecute with + # a different python. + if mozconfig['path']: + if 'PYTHON' in mozconfig['env']['added']: + python = mozconfig['env']['added']['PYTHON'] + elif 'PYTHON' in mozconfig['env']['modified']: + python = mozconfig['env']['modified']['PYTHON'][1] + elif 'PYTHON' in mozconfig['vars']['added']: + python = mozconfig['vars']['added']['PYTHON'] + elif 'PYTHON' in mozconfig['vars']['modified']: + python = mozconfig['vars']['modified']['PYTHON'][1] + + with LineIO(lambda l: log.error(l)) as out: + verify_python_version(out) + topsrcdir, topobjdir = build_env.topsrcdir, build_env.topobjdir + if topobjdir.endswith('/js/src'): + topobjdir = topobjdir[:-7] + + with LineIO(lambda l: log.info(l)) as out: + manager = VirtualenvManager( + topsrcdir, topobjdir, + os.path.join(topobjdir, '_virtualenv'), out, + os.path.join(topsrcdir, 'build', 'virtualenv_packages.txt')) + + if python: + # If we're not in the virtualenv, we need the which module for + # find_program. + if normsep(sys.executable) != normsep(manager.python_path): + sys.path.append(os.path.join(topsrcdir, 'python', 'which')) + found_python = find_program(python) + if not found_python: + die('The PYTHON environment variable does not contain ' + 'a valid path. Cannot find %s', python) + python = found_python + else: + python = sys.executable + + if not manager.up_to_date(python): + log.info('Creating Python environment') + manager.build(python) + + python = normsep(manager.python_path) + + if python != normsep(sys.executable): + log.info('Reexecuting in the virtualenv') + if env_python: + del os.environ['PYTHON'] + # One would prefer to use os.execl, but that's completely borked on + # Windows. + sys.exit(subprocess.call([python] + sys.argv)) + + # We are now in the virtualenv + if not distutils.sysconfig.get_python_lib(): + die('Could not determine python site packages directory') + + return python + +set_config('PYTHON', virtualenv_python) +add_old_configure_assignment('PYTHON', virtualenv_python) + +# Inject mozconfig options +# ============================================================== +# All options defined above this point can't be injected in mozconfig_options +# below, so collect them. +@template +def early_options(): + @dependable + @imports('__sandbox__') + def early_options(): + return set( + option.env + for option in __sandbox__._options.itervalues() + if option.env + ) + return early_options + +early_options = early_options() + +@depends(mozconfig, '--help') +# This gives access to the sandbox. Don't copy this blindly. +@imports('__sandbox__') +@imports('os') +def mozconfig_options(mozconfig, help): + if mozconfig['path']: + helper = __sandbox__._helper + log.info('Adding configure options from %s' % mozconfig['path']) + for arg in mozconfig['configure_args']: + log.info(' %s' % arg) + # We could be using imply_option() here, but it has other + # contraints that don't really apply to the command-line + # emulation that mozconfig provides. + helper.add(arg, origin='mozconfig', args=helper._args) + + def add(key, value): + if key.isupper(): + arg = '%s=%s' % (key, value) + log.info(' %s' % arg) + helper.add(arg, origin='mozconfig', args=helper._args) + + for key, value in mozconfig['env']['added'].iteritems(): + add(key, value) + os.environ[key] = value + for key, (_, value) in mozconfig['env']['modified'].iteritems(): + add(key, value) + os.environ[key] = value + for key, value in mozconfig['vars']['added'].iteritems(): + # mozconfig_loader adds _IS_SET variables that are irrelevant + if not key.endswith('_IS_SET'): + add(key, value) + for key, (_, value) in mozconfig['vars']['modified'].iteritems(): + add(key, value) + + +# Mozilla-Build +# ============================================================== +option(env='MOZILLABUILD', nargs=1, + help='Path to Mozilla Build (Windows-only)') + +option(env='CONFIG_SHELL', nargs=1, help='Path to a POSIX shell') + +# It feels dirty replicating this from python/mozbuild/mozbuild/mozconfig.py, +# but the end goal being that the configure script would go away... +@depends('CONFIG_SHELL', 'MOZILLABUILD') +@checking('for a shell') +@imports('sys') +def shell(value, mozillabuild): + if value: + return find_program(value[0]) + shell = 'sh' + if mozillabuild: + shell = mozillabuild[0] + '/msys/bin/sh' + if sys.platform == 'win32': + shell = shell + '.exe' + return find_program(shell) + + +# Host and target systems +# ============================================================== +option('--host', nargs=1, help='Define the system type performing the build') + +option('--target', nargs=1, + help='Define the system type where the resulting executables will be ' + 'used') + +@imports(_from='mozbuild.configure.constants', _import='CPU') +@imports(_from='mozbuild.configure.constants', _import='CPU_bitness') +@imports(_from='mozbuild.configure.constants', _import='Endianness') +@imports(_from='mozbuild.configure.constants', _import='Kernel') +@imports(_from='mozbuild.configure.constants', _import='OS') +def split_triplet(triplet): + # The standard triplet is defined as + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM + # There is also a quartet form: + # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + # But we can consider the "KERNEL-OPERATING_SYSTEM" as one. + cpu, manufacturer, os = triplet.split('-', 2) + + # Autoconf uses config.sub to validate and canonicalize those triplets, + # but the granularity of its results has never been satisfying to our + # use, so we've had our own, different, canonicalization. We've also + # historically not been very consistent with how we use the canonicalized + # values. Hopefully, this will help us make things better. + # The tests are inherited from our decades-old autoconf-based configure, + # which can probably be improved/cleaned up because they are based on a + # mix of uname and config.guess output, while we now only use the latter, + # which presumably has a cleaner and leaner output. Let's refine later. + os = os.replace('/', '_') + if 'android' in os: + canonical_os = 'Android' + canonical_kernel = 'Linux' + elif os.startswith('linux'): + canonical_os = 'GNU' + canonical_kernel = 'Linux' + elif os.startswith('kfreebsd') and os.endswith('-gnu'): + canonical_os = 'GNU' + canonical_kernel = 'kFreeBSD' + elif os.startswith('gnu'): + canonical_os = canonical_kernel = 'GNU' + elif os.startswith('mingw'): + canonical_os = canonical_kernel = 'WINNT' + elif os.startswith('darwin'): + canonical_kernel = 'Darwin' + canonical_os = 'OSX' + elif os.startswith('ios'): + canonical_kernel = 'Darwin' + canonical_os = 'iOS' + elif os.startswith('dragonfly'): + canonical_os = canonical_kernel = 'DragonFly' + elif os.startswith('freebsd'): + canonical_os = canonical_kernel = 'FreeBSD' + elif os.startswith('netbsd'): + canonical_os = canonical_kernel = 'NetBSD' + elif os.startswith('openbsd'): + canonical_os = canonical_kernel = 'OpenBSD' + else: + die('Unknown OS: %s' % os) + + # The CPU granularity is probably not enough. Moving more things from + # old-configure will tell us if we need more + if cpu.endswith('86') or (cpu.startswith('i') and '86' in cpu): + canonical_cpu = 'x86' + endianness = 'little' + elif cpu in ('x86_64', 'ia64'): + canonical_cpu = cpu + endianness = 'little' + elif cpu in ('s390', 's390x'): + canonical_cpu = cpu + endianness = 'big' + elif cpu in ('powerpc64', 'ppc64', 'powerpc64le', 'ppc64le'): + canonical_cpu = 'ppc64' + endianness = 'little' if 'le' in cpu else 'big' + elif cpu in ('powerpc', 'ppc', 'rs6000') or cpu.startswith('powerpc'): + canonical_cpu = 'ppc' + endianness = 'big' + elif cpu in ('Alpha', 'alpha', 'ALPHA'): + canonical_cpu = 'Alpha' + endianness = 'little' + elif cpu.startswith('hppa') or cpu == 'parisc': + canonical_cpu = 'hppa' + endianness = 'big' + elif cpu.startswith('sparc64'): + canonical_cpu = 'sparc64' + endianness = 'big' + elif cpu.startswith('sparc') or cpu == 'sun4u': + canonical_cpu = 'sparc' + endianness = 'big' + elif cpu.startswith('arm'): + canonical_cpu = 'arm' + endianness = 'big' if cpu.startswith(('armeb', 'armbe')) else 'little' + elif cpu in ('mips', 'mipsel'): + canonical_cpu = 'mips32' + endianness = 'little' if 'el' in cpu else 'big' + elif cpu in ('mips64', 'mips64el'): + canonical_cpu = 'mips64' + endianness = 'little' if 'el' in cpu else 'big' + elif cpu.startswith('aarch64'): + canonical_cpu = 'aarch64' + endianness = 'little' + else: + die('Unknown CPU type: %s' % cpu) + + return namespace( + alias=triplet, + cpu=CPU(canonical_cpu), + bitness=CPU_bitness[canonical_cpu], + kernel=Kernel(canonical_kernel), + os=OS(canonical_os), + endianness=Endianness(endianness), + raw_cpu=cpu, + raw_os=os, + # Toolchains, most notably for cross compilation may use cpu-os + # prefixes. + toolchain='%s-%s' % (cpu, os), + ) + + +@imports('subprocess') +def config_sub(shell, triplet): + config_sub = os.path.join(os.path.dirname(__file__), '..', + 'autoconf', 'config.sub') + return subprocess.check_output([shell, config_sub, triplet]).strip() + + +@depends('--host', shell) +@checking('for host system type', lambda h: h.alias) +@imports('subprocess') +def host(value, shell): + if not value: + config_guess = os.path.join(os.path.dirname(__file__), '..', + 'autoconf', 'config.guess') + host = subprocess.check_output([shell, config_guess]).strip() + else: + host = value[0] + + return split_triplet(config_sub(shell, host)) + + +@depends('--target', host, shell) +@checking('for target system type', lambda t: t.alias) +def target(value, host, shell): + if not value: + return host + return split_triplet(config_sub(shell, value[0])) + + +@depends(host, target) +@checking('whether cross compiling') +def cross_compiling(host, target): + return host != target + +set_config('CROSS_COMPILE', cross_compiling) +set_define('CROSS_COMPILE', cross_compiling) +add_old_configure_assignment('CROSS_COMPILE', cross_compiling) + + +@depends(target) +def have_64_bit(target): + if target.bitness == 64: + return True + +set_config('HAVE_64BIT_BUILD', have_64_bit) +set_define('HAVE_64BIT_BUILD', have_64_bit) +add_old_configure_assignment('HAVE_64BIT_BUILD', have_64_bit) + + +# Autoconf needs these set +@depends(host) +def host_for_old_configure(host): + return '--host=%s' % host.alias + +add_old_configure_arg(host_for_old_configure) + +@depends(host, target) +def target_for_old_configure(host, target): + target_alias = target.alias + # old-configure does plenty of tests against $target and $target_os + # and expects darwin for iOS, so make it happy. + if target.os == 'iOS': + target_alias = target_alias.replace('-ios', '-darwin') + return '--target=%s' % target_alias + +add_old_configure_arg(target_for_old_configure) + + +# These variables are for compatibility with the current moz.builds and +# old-configure. Eventually, we'll want to canonicalize better. +@depends(target) +def target_variables(target): + if target.kernel == 'kFreeBSD': + os_target = 'GNU/kFreeBSD' + os_arch = 'GNU_kFreeBSD' + elif target.kernel == 'Darwin' or (target.kernel == 'Linux' and + target.os == 'GNU'): + os_target = target.kernel + os_arch = target.kernel + else: + os_target = target.os + os_arch = target.kernel + + if target.kernel == 'Darwin' and target.cpu == 'x86': + os_test = 'i386' + else: + os_test = target.raw_cpu + + return namespace( + OS_TARGET=os_target, + OS_ARCH=os_arch, + OS_TEST=os_test, + INTEL_ARCHITECTURE=target.cpu in ('x86', 'x86_64') or None, + ) + +set_config('OS_TARGET', delayed_getattr(target_variables, 'OS_TARGET')) +add_old_configure_assignment('OS_TARGET', + delayed_getattr(target_variables, 'OS_TARGET')) +set_config('OS_ARCH', delayed_getattr(target_variables, 'OS_ARCH')) +add_old_configure_assignment('OS_ARCH', + delayed_getattr(target_variables, 'OS_ARCH')) +set_config('OS_TEST', delayed_getattr(target_variables, 'OS_TEST')) +add_old_configure_assignment('OS_TEST', + delayed_getattr(target_variables, 'OS_TEST')) +set_config('CPU_ARCH', delayed_getattr(target, 'cpu')) +add_old_configure_assignment('CPU_ARCH', delayed_getattr(target, 'cpu')) +set_config('INTEL_ARCHITECTURE', delayed_getattr(target_variables, + 'INTEL_ARCHITECTURE')) +set_config('TARGET_CPU', delayed_getattr(target, 'raw_cpu')) +set_config('TARGET_OS', delayed_getattr(target, 'raw_os')) + + +@depends(host) +def host_variables(host): + if host.kernel == 'kFreeBSD': + os_arch = 'GNU_kFreeBSD' + else: + os_arch = host.kernel + return namespace( + HOST_OS_ARCH=os_arch, + ) + +set_config('HOST_OS_ARCH', delayed_getattr(host_variables, 'HOST_OS_ARCH')) +add_old_configure_assignment('HOST_OS_ARCH', + delayed_getattr(host_variables, 'HOST_OS_ARCH')) + +@depends(target) +def target_is_windows(target): + if target.kernel == 'WINNT': + return True + +set_define('_WINDOWS', target_is_windows) +set_define('WIN32', target_is_windows) +set_define('XP_WIN', target_is_windows) +set_define('XP_WIN32', target_is_windows) + +@depends(target) +def target_is_unix(target): + if target.kernel != 'WINNT': + return True + +set_define('XP_UNIX', target_is_unix) + +@depends(target) +def target_is_darwin(target): + if target.kernel == 'Darwin': + return True + +set_define('XP_DARWIN', target_is_darwin) + +@depends(target) +def target_is_ios(target): + if target.kernel == 'Darwin' and target.os == 'iOS': + return True + +set_define('XP_IOS', target_is_ios) + +@depends(target) +def target_is_osx(target): + if target.kernel == 'Darwin' and target.os == 'OSX': + return True + +set_define('XP_MACOSX', target_is_osx) + +@depends(target) +def target_is_linux(target): + if target.kernel == 'Linux': + return True + +set_define('XP_LINUX', target_is_linux) + +# The application/project to build +# ============================================================== +option('--enable-application', nargs=1, env='MOZ_BUILD_APP', + help='Application to build. Same as --enable-project.') + +@depends('--enable-application', '--help') +def application(app, help): + if app: + return app + +imply_option('--enable-project', application) + + +@depends(check_build_environment, '--help') +def default_project(build_env, help): + if build_env.topobjdir.endswith('/js/src'): + return 'js' + return 'browser' + +option('--enable-project', nargs=1, default=default_project, + help='Project to build') + +option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1, + help='External directory containing additional build files') + +@depends('--enable-project', '--with-external-source-dir', + check_build_environment, '--help') +@imports(_from='os.path', _import='exists') +def include_project_configure(project, external_source_dir, build_env, help): + if not project: + die('--enable-project is required.') + + base_dir = build_env.topsrcdir + if external_source_dir: + base_dir = os.path.join(base_dir, external_source_dir[0]) + + path = os.path.join(base_dir, project[0], 'moz.configure') + if not exists(path): + die('Cannot find project %s', project[0]) + return path + +@depends('--with-external-source-dir') +def external_source_dir(value): + if value: + return value[0] + +set_config('EXTERNAL_SOURCE_DIR', external_source_dir) +add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir) + + +@depends(include_project_configure, check_build_environment, '--help') +def build_project(include_project_configure, build_env, help): + ret = os.path.dirname(os.path.relpath(include_project_configure, + build_env.topsrcdir)) + return ret + +set_config('MOZ_BUILD_APP', build_project) +set_define('MOZ_BUILD_APP', build_project) +add_old_configure_assignment('MOZ_BUILD_APP', build_project) + + +# set RELEASE_OR_BETA and NIGHTLY_BUILD variables depending on the cycle we're in +# The logic works like this: +# - if we have "a1" in GRE_MILESTONE, we're building Nightly (define NIGHTLY_BUILD) +# - otherwise, if we have "a" in GRE_MILESTONE, we're building Nightly or Aurora +# - otherwise, we're building Release/Beta (define RELEASE_OR_BETA) +@depends(check_build_environment, '--help') +@imports(_from='__builtin__', _import='open') +def milestone(build_env, _): + milestone_path = os.path.join(build_env.topsrcdir, + 'config', + 'milestone.txt') + with open(milestone_path, 'r') as fh: + milestone = fh.read().splitlines()[-1] + + is_nightly = is_release_or_beta = None + + if 'a1' in milestone: + is_nightly = True + elif 'a' not in milestone: + is_release_or_beta = True + + return namespace(version=milestone, + is_nightly=is_nightly, + is_release_or_beta=is_release_or_beta) + +set_config('GRE_MILESTONE', delayed_getattr(milestone, 'version')) +set_config('NIGHTLY_BUILD', delayed_getattr(milestone, 'is_nightly')) +set_define('NIGHTLY_BUILD', delayed_getattr(milestone, 'is_nightly')) +add_old_configure_assignment('NIGHTLY_BUILD', + delayed_getattr(milestone, 'is_nightly')) +set_config('RELEASE_OR_BETA', delayed_getattr(milestone, 'is_release_or_beta')) +set_define('RELEASE_OR_BETA', delayed_getattr(milestone, 'is_release_or_beta')) +add_old_configure_assignment('RELEASE_OR_BETA', + delayed_getattr(milestone, 'is_release_or_beta')) + +# The app update channel is 'default' when not supplied. The value is used in +# the application's confvars.sh (and is made available to a project specific +# moz.configure). +option('--enable-update-channel', + nargs=1, + help='Select application update channel', + default='default') + +@depends('--enable-update-channel') +def update_channel(channel): + if channel[0] == '': + return 'default' + return channel[0].lower() + +set_config('MOZ_UPDATE_CHANNEL', update_channel) +set_define('MOZ_UPDATE_CHANNEL', update_channel) +add_old_configure_assignment('MOZ_UPDATE_CHANNEL', update_channel) + + +# A template providing a shorthand for setting a variable. The created +# option will only be settable with imply_option. +# It is expected that a project-specific moz.configure will call imply_option +# to set a value other than the default. +# If required, the set_as_define and set_for_old_configure arguments +# will additionally cause the variable to be set using set_define and +# add_old_configure_assignment. util.configure would be an appropriate place for +# this, but it uses add_old_configure_assignment, which is defined in this file. +@template +def project_flag(env=None, set_for_old_configure=False, + set_as_define=False, **kwargs): + + if not env: + configure_error("A project_flag must be passed a variable name to set.") + + opt = option(env=env, possible_origins=('implied',), **kwargs) + + @depends(opt.option) + def option_implementation(value): + if value: + if len(value): + return value + return bool(value) + + set_config(env, option_implementation) + if set_as_define: + set_define(env, option_implementation) + if set_for_old_configure: + add_old_configure_assignment(env, option_implementation) + +# milestone.is_nightly corresponds to cases NIGHTLY_BUILD is set. +@depends(milestone, '--help') +def enabled_in_nightly(milestone, _): + return milestone.is_nightly + +# Set the MOZ_CONFIGURE_OPTIONS variable with all the options that +# were passed somehow (environment, command line, mozconfig) +@depends(mozconfig_options) +@imports(_from='mozbuild.shellutil', _import='quote') +@imports('__sandbox__') +def all_configure_options(_): + result = [] + previous = None + for option in __sandbox__._options.itervalues(): + # __sandbox__._options contains items for both option.name and + # option.env. But it's also an OrderedDict, meaning both are + # consecutive. + # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not + # interesting. + if option == previous or option.env in ('OLD_CONFIGURE', 'MOZCONFIG'): + continue + previous = option + value = __sandbox__._value_for(option) + # We only want options that were explicitly given on the command + # line, the environment, or mozconfig, and that differ from the + # defaults. + if (value is not None and value.origin not in ('default', 'implied') and + value != option.default): + result.append(__sandbox__._raw_options[option]) + # We however always include options that are sent to old configure + # because we don't know their actual defaults. (Keep the conditions + # separate for ease of understanding and ease of removal) + elif (option.help == 'Help missing for old configure options' and + option in __sandbox__._raw_options): + result.append(__sandbox__._raw_options[option]) + + return quote(*result) + +set_config('MOZ_CONFIGURE_OPTIONS', all_configure_options) + + +# This is temporary until js/src/configure and configure are merged. +# Use instead of option() in js/moz.configure and more generally, for +# options that are shared between configure and js/src/configure. +@template +def js_option(*args, **kwargs): + opt = option(*args, **kwargs) + + @depends(opt.option, build_project) + def js_option(value, build_project): + if build_project != 'js': + return value.format(opt.option) + + add_old_configure_arg(js_option) + + +# Bug 1278542: This function is a workaround to resolve +# |android_ndk_include|'s dependency on 'gonkdir.' The +# actual implementation is located in b2g/moz.configure. +# Remove this function as soon as 'android_ndk_include' +# depends on 'target.' +@depends('--help') +def gonkdir(_): + return None |