Bug 968245 - Regenerate mozinfo.json as part of build backend; r=glandium

Previously, mozinfo.json was only generated as configure time.
Unfortunately, the build dependencies did not capture this relationship.
So, changes to mozinfo.py (or any supporting Python file) would not
trigger mozinfo regeneration, possibly leading to clobbers.

This patch moves mozinfo.json generation from the body of config.status
to the build backend. We had to add an AC_SUBST so the build config
knows when to build mozinfo.json. This was needed because js/src's build
system doesn't define all the required variables to create mozinfo.json.
Once js/src's configure/config.status is merged into the main build
config tree, this workaround can be removed.

While we were here, mozinfo.json was made to have consistent output and
its changes are now viewable with config.status --diff.

--HG--
extra : rebase_source : e91ed7173efdcde5831ae13b1ce69fc3cf32af97
extra : amend_source : 1610bcc6c3af764fdf685ee76188fb211bd828de
This commit is contained in:
Gregory Szorc 2014-02-05 20:53:47 -08:00
parent ca47d1143e
commit 78b22e13e0
7 changed files with 37 additions and 12 deletions

View File

@ -9073,11 +9073,9 @@ ac_configure_args="$_SUBDIR_CONFIG_ARGS"
fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
export WRITE_MOZINFO=1
dnl we need to run config.status after js/src subconfigure because we're
dnl traversing its moz.build and we need its config.status for that.
dnl However, writing our own config.status needs to happen before
dnl subconfigures because the setup surrounding subconfigures alters
dnl many AC_SUBSTed variables.
MOZ_RUN_CONFIG_STATUS()
unset WRITE_MOZINFO

View File

@ -25,7 +25,7 @@ from ..frontend.data import (
XPIDLFile,
WebIDLFile,
)
from ..mozinfo import write_mozinfo
from ..util import DefaultOnReadDict
@ -172,6 +172,8 @@ class CommonBackend(BuildBackend):
self._webidls = WebIDLCollection()
self._configs = set()
self._write_mozinfo = True # For testing
def consume_object(self, obj):
self._configs.add(obj.config)
@ -237,6 +239,13 @@ class CommonBackend(BuildBackend):
for config in self._configs:
self.backend_input_files.add(config.source)
# Write out a JSON file used by test harnesses, other parts of
# automation.
if self._write_mozinfo and 'JS_STANDALONE' not in self.environment.substs:
path = mozpath.join(self.environment.topobjdir, 'mozinfo.json')
with self._write_file(path) as fh:
write_mozinfo(fh, self.environment, os.environ)
# Write out a machine-readable file describing every test.
path = mozpath.join(self.environment.topobjdir, 'all-tests.json')
with self._write_file(path) as fh:

View File

@ -20,7 +20,6 @@ from mozbuild.backend.recursivemake import RecursiveMakeBackend
from mozbuild.base import MachCommandConditions
from mozbuild.frontend.emitter import TreeMetadataEmitter
from mozbuild.frontend.reader import BuildReader
from mozbuild.mozinfo import write_mozinfo
log_manager = LoggingManager()
@ -107,11 +106,6 @@ def config_status(topobjdir='.', topsrcdir='.',
env = ConfigEnvironment(topsrcdir, topobjdir, defines=defines,
non_global_defines=non_global_defines, substs=substs, source=source)
# mozinfo.json only needs written if configure changes and configure always
# passes this environment variable.
if 'WRITE_MOZINFO' in os.environ:
write_mozinfo(os.path.join(topobjdir, 'mozinfo.json'), env, os.environ)
# Make an appropriate backend instance, defaulting to RecursiveMakeBackend.
backend_cls = RecursiveMakeBackend
if options.backend == 'AndroidEclipse':

View File

@ -98,8 +98,9 @@ def write_mozinfo(file, config, env=os.environ):
and what keys are produced.
"""
build_conf = build_dict(config, env)
args = {'indent': 2, 'sort_keys': True}
if isinstance(file, basestring):
with open(file, "w") as f:
json.dump(build_conf, f)
json.dump(build_conf, f, **args)
else:
json.dump(build_conf, file)
json.dump(build_conf, file, **args)

View File

@ -68,6 +68,18 @@ CONFIGS = DefaultOnReadDict({
('MOZ_APP_NAME', 'my_app'),
],
},
'mozinfo': {
'defines': [],
'non_global_defines': [],
'substs': [
('WRITE_MOZINFO', '1'),
# Some variables required for mozinfo generation.
('TARGET_CPU', 'dummy'),
('OS_TARGET', 'dummy'),
('MOZ_WIDGET_TOOLKIT', 'dummy'),
],
},
}, global_default={
'defines': [],
'non_global_defines': [],
@ -98,9 +110,12 @@ class BackendTester(unittest.TestCase):
return env, emitter.emit(reader.read_topsrcdir())
def _consume(self, name, cls, env=None):
def _consume(self, name, cls, env=None, write_mozinfo=False):
env, objs = self._emit(name, env=env)
backend = cls(env)
# Don't write mozinfo.json by default since it requires certain
# environment variables.
backend._write_mozinfo = write_mozinfo
backend.consume(objs)
return env

View File

@ -230,6 +230,7 @@ class TestRecursiveMakeBackend(BackendTester):
reader = BuildReader(env)
emitter = TreeMetadataEmitter(env)
backend = RecursiveMakeBackend(env)
backend._write_mozinfo = False
backend.consume(emitter.emit(reader.read_topsrcdir()))
self.assertEqual(os.path.getmtime(makefile_path), makefile_mtime)
@ -475,6 +476,7 @@ class TestRecursiveMakeBackend(BackendTester):
def test_install_manifests_written(self):
env, objs = self._emit('stub0')
backend = RecursiveMakeBackend(env)
backend._write_mozinfo = False
m = InstallManifest()
backend._install_manifests['testing'] = m
@ -673,6 +675,12 @@ class TestRecursiveMakeBackend(BackendTester):
stem = '%s/android_eclipse/%s' % (env.topobjdir, project_name)
self.assertIn(command_template % (stem, stem), lines)
def test_mozinfo(self):
env = self._consume('mozinfo', RecursiveMakeBackend, write_mozinfo=True)
self.assertTrue(os.path.exists(os.path.join(env.topobjdir,
'mozinfo.json')))
if __name__ == '__main__':
main()