--- a/build/moz.configure/checks.configure
+++ b/build/moz.configure/checks.configure
@@ -7,17 +7,18 @@
# Templates implementing some generic checks.
# ==============================================================
# Declare some exceptions. This is cumbersome, but since we shouldn't need a
# lot of them, let's stack them all here. When adding a new one, put it in the
# _declare_exceptions template, and add it to the return statement. Then
# destructure in the assignment below the function declaration.
@template
-@advanced
+@imports(_from='__builtin__', _import='Exception')
+@imports(_from='__builtin__', _import='__name__')
def _declare_exceptions():
class FatalCheckError(Exception):
'''An exception to throw from a function decorated with @checking.
It will result in calling die() with the given message.
Debugging messages emitted from the decorated function will also be
printed out.'''
return FatalCheckError
@@ -84,21 +85,19 @@ def checking(what, callback=None):
# - `allow_missing` indicates whether not finding the program is an error.
#
# The simplest form is:
# check_prog('PROG', ('a', 'b'))
# will look for 'a' or 'b' in $PATH, and set_config PROG to the one
# it can find. If PROG is already set from the environment or command line,
# use that value instead.
@template
-@advanced
+@imports(_from='mozbuild.shellutil', _import='quote')
+@imports(_from='mozbuild.configure', _import='DependsFunction')
def check_prog(var, progs, what=None, input=None, allow_missing=False):
- from mozbuild.shellutil import quote
- from mozbuild.configure import DependsFunction
-
if input:
# Wrap input with type checking and normalization.
@depends(input)
def input(value):
if not value:
return
if isinstance(value, str):
return (value,)
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -78,20 +78,18 @@ option(env='MOZCONFIG', nargs=1, help='M
# 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')
-@advanced
+@imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
def mozconfig(current_project, mozconfig, old_configure, build_env, help):
- from mozbuild.mozconfig import MozconfigLoader
-
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
@@ -125,59 +123,54 @@ def mozconfig(current_project, mozconfig
def old_configure_assignments(help):
return []
@depends('--help')
def extra_old_configure_args(help):
return []
@template
-@advanced
+@imports(_from='mozbuild.configure', _import='DependsFunction')
def add_old_configure_assignment(var, value_func):
- from mozbuild.configure import DependsFunction
assert isinstance(value_func, DependsFunction)
@depends(old_configure_assignments, value_func)
- @advanced
+ @imports(_from='mozbuild.shellutil', _import='quote')
def add_assignment(assignments, value):
if value is None:
return
if value is True:
assignments.append('%s=1' % var)
elif value is False:
assignments.append('%s=' % var)
else:
- from mozbuild.shellutil import quote
if isinstance(value, (list, tuple)):
value = ' '.join(quote(v) for v in value)
assignments.append('%s=%s' % (var, quote(value)))
@template
def add_old_configure_arg(arg):
@depends(extra_old_configure_args)
def add_arg(args):
args.append(arg)
option(env='PYTHON', nargs=1, help='Python interpreter')
# Setup python virtualenv
# ==============================================================
@depends('PYTHON', check_build_environment, mozconfig)
-@advanced
+@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):
- import os
- import sys
- import subprocess
- from mozbuild.configure.util import LineIO
- from mozbuild.virtualenv import (
- VirtualenvManager,
- verify_python_version,
- )
-
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']
@@ -223,46 +216,36 @@ def virtualenv_python(env_python, build_
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
- import distutils.sysconfig
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
# ==============================================================
-@template
-@advanced
-def command_line_helper():
- # This escapes the sandbox. Don't copy this. This is only here because
- # it is a one off and because the required functionality doesn't need
- # to be exposed for other usecases.
- return depends.__self__._helper
-
-
# All options defined above this point can't be injected in mozconfig_options
# below, so collect them.
@template
def early_options():
@depends('--help')
- @advanced
+ @imports('__sandbox__')
def early_options(help):
return set(
option.env
- for option in depends.__self__._options.itervalues()
+ for option in __sandbox__._options.itervalues()
if option.env
)
return early_options
early_options = early_options()
# At the moment, moz.configure doesn't have complete knowledge of all the
# supported options in mozconfig because of all that is still in old.configure.
@@ -310,19 +293,21 @@ def wanted_mozconfig_variables(help):
'WITHOUT_X',
'XARGS',
'YASM',
'ZIP',
])
@depends(mozconfig, wanted_mozconfig_variables, '--help')
+# This gives access to the sandbox. Don't copy this blindly.
+@imports('__sandbox__')
def mozconfig_options(mozconfig, wanted_mozconfig_variables, help):
if mozconfig['path']:
- helper = command_line_helper()
+ 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)
@@ -338,31 +323,26 @@ def mozconfig_options(mozconfig, wanted_
for key, (_, value) in mozconfig['env']['modified'].iteritems():
add(key, value)
for key, value in mozconfig['vars']['added'].iteritems():
add(key, value)
for key, (_, value) in mozconfig['vars']['modified'].iteritems():
add(key, value)
-del command_line_helper
-
-
# Mozilla-Build
# ==============================================================
option(env='MOZILLABUILD', nargs=1,
help='Path to Mozilla Build (Windows-only)')
# It feels dirty replicating this from python/mozbuild/mozbuild/mozconfig.py,
# but the end goal being that the configure script would go away...
@depends('MOZILLABUILD')
-@advanced
+@imports('sys')
def shell(mozillabuild):
- import sys
-
shell = 'sh'
if mozillabuild:
shell = mozillabuild[0] + '/msys/bin/sh'
if sys.platform == 'win32':
shell = shell + '.exe'
return shell
@@ -456,30 +436,28 @@ def split_triplet(triplet):
kernel=canonical_kernel,
os=canonical_os,
raw_cpu=cpu,
raw_os=os,
)
@template
-@advanced
+@imports('subprocess')
def config_sub(shell, triplet):
- import subprocess
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)
-@advanced
+@imports('subprocess')
def host(value, shell):
if not value:
- import subprocess
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))
@@ -669,17 +647,17 @@ add_old_configure_assignment('MOZ_BUILD_
# set RELEASE_BUILD 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_BUILD)
@depends(check_build_environment)
-@advanced
+@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 = None
--- a/build/moz.configure/old.configure
+++ b/build/moz.configure/old.configure
@@ -1,30 +1,27 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
@template
-@advanced
+@imports('codecs')
+@imports('sys')
def encoded_open(path, mode):
- import codecs
- import sys
encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8'
return codecs.open(path, mode, encoding)
option(env='AUTOCONF', nargs=1, help='Path to autoconf 2.13')
@depends(mozconfig, 'AUTOCONF')
-@advanced
+@imports('re')
def autoconf(mozconfig, autoconf):
- import re
-
mozconfig_autoconf = None
if mozconfig['path']:
make_extra = mozconfig['make_extra']
if make_extra:
for assignment in make_extra:
m = re.match('(?:export\s+)?AUTOCONF\s*:?=\s*(.+)$',
assignment)
if m:
@@ -58,46 +55,45 @@ def autoconf(mozconfig, autoconf):
return autoconf
set_config('AUTOCONF', autoconf)
# See comment in mozconfig_options() from build/moz.configure/init.configure
@template
-@advanced
+# This gives access to the sandbox. Don't copy this blindly.
+@imports('__sandbox__')
def check_mozconfig_variables():
# This escapes the sandbox. Don't copy this. This is only here because it
# is a one off until old-configure is gone.
- all_options = depends.__self__._options.itervalues()
+ all_options = __sandbox__._options.itervalues()
@depends(early_options, wanted_mozconfig_variables)
def check_mozconfig_variables(early_options, wanted_mozconfig_variables):
for option in all_options:
if (option.env and option.env not in early_options and
option.env not in wanted_mozconfig_variables):
die('You need to add `%s` to the `wanted_mozconfig_variables` '
'list in build/moz.configure/init.configure.', option.env)
check_mozconfig_variables()
@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell,
old_configure_assignments, build_project)
-@advanced
+@imports(_from='__builtin__', _import='print')
+@imports('glob')
+@imports('itertools')
+@imports('subprocess')
+# Import getmtime without overwriting the sandbox os.path.
+@imports(_from='os.path', _import='getmtime')
+@imports(_from='mozbuild.shellutil', _import='quote')
def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
old_configure_assignments, build_project):
- import glob
- import itertools
- import subprocess
- # Import getmtime without overwriting the sandbox os.path.
- from os.path import getmtime
-
- from mozbuild.shellutil import quote
-
# os.path.abspath in the sandbox will ensure forward slashes on Windows,
# which is actually necessary because this path actually ends up literally
# as $0, and backslashes there breaks autoconf's detection of the source
# directory.
old_configure = os.path.abspath(old_configure[0])
if build_project == 'js':
old_configure_dir = os.path.dirname(old_configure)
if not old_configure_dir.endswith('/js/src'):
@@ -364,25 +360,25 @@ def old_configure_options(*options):
'--x-libraries',
# Below are the configure flags used by comm-central.
'--enable-ldap',
'--enable-mapi',
'--enable-calendar',
'--enable-incomplete-external-linkage',
)
-@advanced
+@imports(_from='__builtin__', _import='compile')
+@imports(_from='__builtin__', _import='zip')
+@imports('logging')
+@imports('os')
+@imports('subprocess')
+@imports('sys')
+@imports(_from='mozbuild.shellutil', _import='quote')
def old_configure(prepare_configure, extra_old_configure_args, all_options,
*options):
- import logging
- import os
- import subprocess
- import sys
- from mozbuild.shellutil import quote
-
cmd = prepare_configure
# old-configure only supports the options listed in @old_configure_options
# so we don't need to pass it every single option we've been passed. Only
# the ones that are not supported by python configure need to.
cmd += [
value.format(name)
for name, value in zip(all_options, options)
@@ -451,20 +447,18 @@ def set_old_configure_config(name, value
# Same as set_old_configure_config, but for set_define.
@template
def set_old_configure_define(name, value):
set_define(name, value)
@depends(old_configure)
-@advanced
+@imports('types')
def post_old_configure(raw_config):
- import types
-
for k, v in raw_config['substs']:
set_old_configure_config(
k[1:-1], v[1:-1] if isinstance(v, types.StringTypes) else v)
for k, v in dict(raw_config['defines']).iteritems():
set_old_configure_define(k[1:-1], v[1:-1])
set_old_configure_config('non_global_defines',
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -5,19 +5,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# yasm detection
# ==============================================================
yasm = check_prog('YASM', ['yasm'], allow_missing=True)
@depends_if(yasm)
@checking('yasm version')
-@advanced
+@imports('subprocess')
def yasm_version(yasm):
- import subprocess
try:
version = Version(subprocess.check_output(
[yasm, '--version']
).splitlines()[0].split()[1])
return version
except subprocess.CalledProcessError as e:
die('Failed to get yasm version: %s', e.message)
@@ -80,19 +79,18 @@ ccache = check_prog('CCACHE', progs=(),
@depends_if(ccache)
def using_ccache(ccache):
return True
set_config('MOZ_USING_CCACHE', using_ccache)
@depends('--with-compiler-wrapper', ccache)
-@advanced
+@imports(_from='mozbuild.shellutil', _import='split', _as='shell_split')
def compiler_wrapper(wrapper, ccache):
- from mozbuild.shellutil import split as shell_split
if ccache:
if wrapper:
return tuple([ccache] + shell_split(wrapper[0]))
else:
return (ccache,)
elif wrapper:
return tuple(shell_split(wrapper[0]))
--- a/build/moz.configure/util.configure
+++ b/build/moz.configure/util.configure
@@ -1,74 +1,73 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
@template
-@advanced
+@imports('sys')
def die(*args):
'Print an error and terminate configure.'
- import sys
log.error(*args)
sys.exit(1)
@template
-@advanced
+@imports(_from='mozbuild.configure', _import='ConfigureError')
def configure_error(message):
'''Raise a programming error and terminate configure.
Primarily for use in moz.configure templates to sanity check
their inputs from moz.configure usage.'''
- from mozbuild.configure import ConfigureError
raise ConfigureError(message)
@template
-@advanced
+@imports('os')
def is_absolute_or_relative(path):
- import os
if os.altsep and os.altsep in path:
return True
return os.sep in path
@template
-@advanced
+@imports(_import='mozpack.path', _as='mozpath')
def normsep(path):
- import mozpack.path as mozpath
return mozpath.normsep(path)
@template
-@advanced
+# This unlocks the sandbox. Do not copy blindly.
+@imports(_import='__builtin__', _as='__builtins__')
def find_program(file):
if is_absolute_or_relative(file):
return os.path.abspath(file) if os.path.isfile(file) else None
+ # We can't use @imports here because it imports at declaration time,
+ # and the declaration of find_program happens before we ensure the
+ # which module is available in sys.path somehow.
from which import which, WhichError
try:
return normsep(which(file))
except WhichError:
return None
@template
def unique_list(l):
result = []
for i in l:
if l not in result:
result.append(i)
return result
@template
-@advanced
+@imports(_from='mozbuild.configure.util', _import='Version', _as='_Version')
def Version(v):
'A version number that can be compared usefully.'
- from mozbuild.configure.util import Version as _Version
return _Version(v)
# Denotes a deprecated option. Combines option() and @depends:
# @deprecated_option('--option')
# def option(value):
# ...
# @deprecated_option() takes the same arguments as option(), except `help`.
# The function may handle the option like a typical @depends function would,
@@ -87,35 +86,34 @@ def deprecated_option(*args, **kwargs):
return func(value)
return deprecated
return decorator
# from mozbuild.util import ReadOnlyNamespace as namespace
@template
-@advanced
+@imports(_from='mozbuild.util', _import='ReadOnlyNamespace')
def namespace(**kwargs):
- from mozbuild.util import ReadOnlyNamespace
return ReadOnlyNamespace(**kwargs)
# Some @depends function return namespaces, and one could want to use one
# specific attribute from such a namespace as a "value" given to functions
# such as `set_config`. But those functions do not take immediate values.
# The `delayed_getattr` function allows access to attributes from the result
# of a @depends function in a non-immediate manner.
# @depends('--option')
# def option(value)
# return namespace(foo=value)
# set_config('FOO', delayed_getattr(option, 'foo')
@template
def delayed_getattr(func, key):
@depends(func)
- @advanced
+ @imports(_from='__builtin__', _import='getattr')
def result(value):
try:
return getattr(value, key)
except AttributeError:
# The @depends function we're being passed may have returned
# None, or an object that simply doesn't have the wanted key.
# In that case, just return None.
return None
--- a/moz.configure
+++ b/moz.configure
@@ -57,19 +57,18 @@ add_old_configure_assignment('COMPILE_EN
def toolchain_include(value, help):
if value:
return 'build/moz.configure/toolchain.configure'
include(toolchain_include)
@depends('--help')
-@advanced
+@imports(_from='mozbuild.backend', _import='backends')
def build_backends_choices(help):
- from mozbuild.backend import backends
return tuple(backends)
option('--enable-build-backend', nargs='+', choices=build_backends_choices,
help='Enable additional build backends')
@depends('--enable-build-backend', '--enable-artifact-builds')
def build_backend(backends, artifact_builds):
@@ -105,34 +104,32 @@ def perl_for_old_configure(value):
return value
add_old_configure_assignment('PERL', perl_for_old_configure)
@template
def perl_version_check(min_version):
@depends(perl)
@checking('for minimum required perl version >= %s' % min_version)
- @advanced
+ @imports('subprocess')
def get_perl_version(perl):
- import subprocess
try:
return Version(subprocess.check_output([perl, '-e', 'print $]']))
except subprocess.CalledProcessError as e:
die('Failed to get perl version: %s', e.message)
@depends(get_perl_version)
def check_perl_version(version):
if version < min_version:
die('Perl %s or higher is required.', min_version)
@depends(perl)
@checking('for full perl installation')
- @advanced
+ @imports('subprocess')
def has_full_perl_installation(perl):
- import subprocess
ret = subprocess.call(
[perl, '-e', 'use Config; exit(!-d $Config{archlib})'])
return ret == 0
@depends(has_full_perl_installation)
def require_full_perl_installation(has_full_perl_installation):
if not has_full_perl_installation:
die('Cannot find Config.pm or $Config{archlib}. '