mirror of https://github.com/roytam1/UXP
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
815 lines
29 KiB
815 lines
29 KiB
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- |
|
# 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' |
|
elif os.startswith('solaris'): |
|
canonical_os = canonical_kernel = 'SunOS' |
|
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) |
|
|
|
@depends(target) |
|
def target_is_solaris(target): |
|
if target.kernel == 'SunOS': |
|
return True |
|
|
|
set_define('XP_SOLARIS', target_is_solaris) |
|
|
|
@depends(target) |
|
def target_is_sparc(target): |
|
if target.cpu == 'sparc': |
|
return True |
|
|
|
set_define('SPARC', target_is_sparc) |
|
|
|
@depends(target) |
|
def target_is_sparc64(target): |
|
if target.cpu == 'sparc64': |
|
return True |
|
|
|
set_define('SPARC64', target_is_sparc64) |
|
|
|
|
|
# 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]) |
|
|
|
build_app = project[0] |
|
|
|
# XXX: Change this when 'browser' becomes invalid as an alias |
|
if build_app == 'browser': |
|
build_app = 'basilisk' |
|
#die('The project "browser" is no longer valid. Perhaps you meant "basilisk" or "palemoon"?') |
|
|
|
path_project_src_dir_application = os.path.join(base_dir, 'application/' + build_app, 'moz.configure') |
|
path_project_src_dir_root = os.path.join(base_dir, build_app, 'moz.configure') |
|
|
|
if exists(path_project_src_dir_application): |
|
return path_project_src_dir_application |
|
elif exists(path_project_src_dir_root): |
|
return path_project_src_dir_root |
|
else: |
|
die('Cannot find project %s', build_app) |
|
|
|
@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
|
|
|