gecko-dev/js/sub.configure
Mike Hommey 250c3cbc9a Bug 844509 - Don't encode environment in get_cmd_output and old_configure. r=nalexander
The configure sandbox has wrapped subprocess methods to add its own
encoded environment if none is provided, since bug 1520394. It only
makes sense that it normalizes the environment that comes in too,
avoiding caller in the configure sandbox to have to do it themselves.

OTOH, and while we're here, none of get_cmd_output, old_configure or the
sandbox were actually using the right encoding for this conversion, so
fix the configure sandbox to use the right one, and make it stop using
encode(), which does deep recursion that is not necessary here, and that
I'm trying to remove entirely.

Also while here, remove an unused import of encode().

Differential Revision: https://phabricator.services.mozilla.com/D42608

--HG--
extra : moz-landing-system : lando
2019-08-20 22:12:23 +00:00

188 lines
7.1 KiB
Plaintext

# 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/.
@depends(check_build_environment, prepare_configure_options, prepare_mozconfig,
old_configure, old_configure_assignments, '--cache-file')
@imports('errno')
@imports('itertools')
@imports('logging')
@imports('os')
@imports('pickle')
@imports('sys')
@imports(_from='__main__', _import='config_status')
@imports(_from='__builtin__', _import='OSError')
@imports(_from='__builtin__', _import='open')
@imports(_from='__builtin__', _import='object')
@imports(_from='mozbuild.configure', _import='ConfigureSandbox')
@imports(_from='mozbuild.configure.util', _import='ConfigureOutputHandler')
def js_subconfigure(build_env, prepare_configure_options, mozconfig,
old_configure, old_configure_assignments, cache_file):
class PrefixOutput(object):
def __init__(self, prefix, fh):
self._fh = fh
self._begin_line = True
self._prefix = prefix
def write(self, content):
if self._begin_line:
self._fh.write(self._prefix)
self._fh.write(('\n' + self._prefix).join(content.splitlines()))
self._begin_line = content.endswith('\n')
if self._begin_line:
self._fh.write('\n')
def flush(self):
self._fh.flush()
logger = logging.getLogger('moz.configure')
formatter = logging.Formatter('js/src> %(levelname)s: %(message)s')
for handler in logger.handlers:
handler.setFormatter(formatter)
if isinstance(handler, ConfigureOutputHandler):
handler._stdout = PrefixOutput('js/src> ', handler._stdout)
substs = dict(old_configure['substs'])
assignments = dict(old_configure_assignments)
environ = dict(os.environ)
if prepare_configure_options.extra_env:
environ.update(prepare_configure_options.extra_env)
options = [
o for o in prepare_configure_options.options
# --with-system-nspr will have been converted into the relevant $NSPR_CFLAGS
# and $NSPR_LIBS.
if not o.startswith('--with-system-nspr')
]
if not substs.get('ENABLE_INTL_API'):
options.append('--without-intl-api')
if substs.get('NSPR_CFLAGS') or substs.get('NSPR_LIBS'):
options.append(
'--with-nspr-cflags=%s' % ' '.join(substs.get('NSPR_CFLAGS', [])))
options.append(
'--with-nspr-libs=%s' % ' '.join(substs.get('NSPR_LIBS', [])))
options.append('--prefix=%s/dist' % build_env.topobjdir)
if substs.get('ZLIB_IN_MOZGLUE'):
substs['MOZ_ZLIB_LIBS'] = ''
environ['MOZILLA_CENTRAL_PATH'] = build_env.topsrcdir
if 'MOZ_BUILD_APP' in environ:
del environ['MOZ_BUILD_APP']
# Here, we mimic what we used to do from old-configure, which makes this
# all awkward.
# The following variables were saved at the beginning of old-configure,
# and restored before invoking the subconfigure. Which means their value
# should be taken from the old_configure_assignments or mozconfig.
from_assignment = set(
('CC', 'CXX', 'CPPFLAGS', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS', 'HOST_CC',
'HOST_CXXFLAGS', 'HOST_LDFLAGS'))
# Variables that were explicitly exported from old-configure, and those
# explicitly set in the environment when invoking old-configure, were
# automatically inherited from subconfigure. We assume the relevant ones
# have a corresponding AC_SUBST in old-configure, making them available
# in `substs`.
for var in itertools.chain((
'MOZ_SYSTEM_ZLIB', 'MOZ_ZLIB_CFLAGS', 'MOZ_ZLIB_LIBS',
'MOZ_APP_NAME', 'MOZ_APP_REMOTINGNAME', 'MOZ_DEV_EDITION',
'STLPORT_LIBS', 'DIST', 'MOZ_LINKER', 'ZLIB_IN_MOZGLUE', 'RANLIB',
'AR', 'CPP', 'CC', 'CXX', 'CPPFLAGS', 'CFLAGS', 'CXXFLAGS',
'LDFLAGS', 'HOST_CC', 'HOST_CXX', 'HOST_CPPFLAGS',
'HOST_CXXFLAGS', 'HOST_LDFLAGS'
), prepare_configure_options.extra_env):
if var not in from_assignment and var in substs:
value = substs[var]
elif var in assignments:
value = assignments[var]
elif mozconfig and var in mozconfig and \
not mozconfig[var][1].startswith('removed'):
value = mozconfig[var][0]
else:
continue
if isinstance(value, list):
value = ' '.join(value)
environ[var] = value
options.append('JS_STANDALONE=')
srcdir = os.path.join(build_env.topsrcdir, 'js', 'src')
objdir = os.path.join(build_env.topobjdir, 'js', 'src')
data_file = os.path.join(objdir, 'configure.pkl')
previous_args = None
if os.path.exists(data_file):
with open(data_file, 'rb') as f:
previous_args = pickle.load(f)
cache_file = cache_file or './config.cache'
cache_file = os.path.join(build_env.topobjdir, cache_file)
try:
os.makedirs(objdir)
except OSError as e:
if e.errno != errno.EEXIST:
raise
with open(data_file, 'wb') as f:
pickle.dump(options, f)
# Only run configure if one of the following is true:
# - config.status doesn't exist
# - config.status is older than an input to configure
# - the configure arguments changed
configure = os.path.join(srcdir, 'old-configure')
config_status_path = os.path.join(objdir, 'config.status')
skip_configure = True
if not os.path.exists(config_status_path):
skip_configure = False
else:
config_status_deps = os.path.join(objdir, 'config_status_deps.in')
if not os.path.exists(config_status_deps):
skip_configure = False
else:
with open(config_status_deps, 'r') as fh:
dep_files = fh.read().splitlines() + [configure]
if (any(not os.path.exists(f) or
(os.path.getmtime(config_status_path) < os.path.getmtime(f))
for f in dep_files) or
((previous_args or options) != options)):
skip_configure = False
ret = 0
if not skip_configure:
oldpwd = os.getcwd()
os.chdir(objdir)
command = [
os.path.join(build_env.topsrcdir, 'configure.py'),
'--enable-project=js',
]
environ['OLD_CONFIGURE'] = os.path.join(
os.path.dirname(configure), 'old-configure')
command += options
command += ['--cache-file=%s' % cache_file]
log.info('configuring')
log.info('running %s' % ' '.join(command[:-1]))
config = {}
sandbox = ConfigureSandbox(config, environ, command, logger=logger)
sandbox.run(os.path.join(build_env.topsrcdir, 'moz.configure'))
ret = config_status(config)
os.chdir(oldpwd)
# Restore unprefixed logging.
formatter = logging.Formatter('%(levelname)s: %(message)s')
for handler in logger.handlers:
handler.setFormatter(formatter)
if isinstance(handler, ConfigureOutputHandler):
handler._stdout.flush()
handler._stdout = handler._stdout._fh
return ret