summaryrefslogtreecommitdiffstats
path: root/build/moz.configure/init.configure
diff options
context:
space:
mode:
Diffstat (limited to 'build/moz.configure/init.configure')
-rw-r--r--build/moz.configure/init.configure780
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