gecko-dev/build/moz.configure/init.configure

326 строки
12 KiB
Plaintext
Исходник Обычный вид История

# -*- 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/.
include('util.configure')
option(env='DIST', nargs=1, help='DIST directory')
# Do not allow objdir == srcdir builds.
# ==============================================================
@depends('--help', 'DIST')
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__), '..', '..')))
set_config('TOPSRCDIR', topsrcdir)
set_config('TOPOBJDIR', topobjdir)
set_config('MOZ_BUILD_ROOT', topobjdir)
if dist:
set_config('DIST', normsep(dist[0]))
else:
set_config('DIST', os.path.join(topobjdir, 'dist'))
if help:
return
if topsrcdir == topobjdir:
error(
' ***\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 os.path.exists(os.path.join(topsrcdir, f))
]
if conflict_files:
error(
' ***\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)
)
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')
@advanced
def mozconfig(current_project, mozconfig, old_configure, build_env, help):
from mozbuild.mozconfig import MozconfigLoader
if not old_configure:
error('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
# Hacks related to old-configure
# ==============================
@depends('--help')
def old_configure_assignments(help):
return []
@depends('--help')
def extra_old_configure_args(help):
return []
@template
def add_old_configure_assignment(var, value):
@depends(old_configure_assignments)
@advanced
def add_assignment(assignments):
from mozbuild.shellutil import quote
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
def virtualenv_python(env_python, build_env, mozconfig):
import os
import sys
import subprocess
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']
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]
verify_python_version(sys.stderr)
topsrcdir, topobjdir = build_env['TOPSRCDIR'], build_env['TOPOBJDIR']
if topobjdir.endswith('/js/src'):
topobjdir = topobjdir[:-7]
manager = VirtualenvManager(
topsrcdir, topobjdir,
os.path.join(topobjdir, '_virtualenv'), sys.stdout,
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:
error('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):
warn('Creating Python environment')
manager.build(python)
python = normsep(manager.python_path)
if python != normsep(sys.executable):
warn('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():
error('Could not determine python site packages directory')
set_config('PYTHON', python)
add_old_configure_assignment('PYTHON', python)
return 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
@depends(mozconfig)
def mozconfig_options(mozconfig):
if mozconfig['path']:
helper = command_line_helper()
warn('Adding configure options from %s' % mozconfig['path'])
for arg in mozconfig['configure_args']:
warn(' %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)
# Ideally we'd handle mozconfig['env'] and mozconfig['vars'] here,
# but at the moment, moz.configure has no knowledge of the options
# that may appear there. We'll opt-in when we move things from
# old-configure.in, which will be tedious but necessary until we
# can discriminate what old-configure.in supports.
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
def shell(mozillabuild):
import sys
shell = 'sh'
if mozillabuild:
shell = mozillabuild[0] + '/msys/bin/sh'
if sys.platform == 'win32':
shell = shell + '.exe'
return shell
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:
imply_option(app.format('--enable-project'))
@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')
def include_project_configure(project, external_source_dir, build_env, help):
if not project:
error('--enable-project is required.')
base_dir = build_env['TOPSRCDIR']
if external_source_dir:
set_config('EXTERNAL_SOURCE_DIR', external_source_dir[0])
add_old_configure_assignment('EXTERNAL_SOURCE_DIR',
external_source_dir[0])
base_dir = os.path.join(base_dir, external_source_dir[0])
path = os.path.join(base_dir, project[0], 'moz.configure')
if not os.path.exists(path):
error('Cannot find project %s' % project[0])
return path
@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']))
add_old_configure_assignment('MOZ_BUILD_APP', ret)
return ret
# This is temporary until js/src/configure and configure are merged.
# Use instead of option() in js/moz.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':
add_old_configure_arg(value.format(opt.option))
include(include_project_configure)