Bug 1412460 - Move configure invocation out of mach_commands.py; r?build
While we're here, also move the low-level code to invoke configure
to a proper Python module.
We needed to muck around with the log manager because the underlying
logger for output changed from "mach" (which is registered by default)
to something under the "mozbuild" hierarchy.
MozReview-Commit-ID: 4rlCxOwcVu1
--- a/python/mozbuild/mozbuild/controller/building.py
+++ b/python/mozbuild/mozbuild/controller/building.py
@@ -41,16 +41,19 @@ from ..backend import (
)
from ..testing import (
install_test_files,
)
from ..compilation.warnings import (
WarningsCollector,
WarningsDatabase,
)
+from ..shellutil import (
+ quote as shell_quote,
+)
from ..util import (
mkdir,
resolve_target_to_make,
)
FINDER_SLOW_MESSAGE = '''
===================
@@ -970,25 +973,29 @@ class CCacheStats(object):
return '%.1f Mbytes' % (float(v) / CCacheStats.MiB)
else:
return '%.1f Kbytes' % (float(v) / CCacheStats.KiB)
class BuildDriver(MozbuildObject):
"""Provides a high-level API for build actions."""
+ def __init__(self, *args, **kwargs):
+ super(BuildDriver, self).__init__(*args, **kwargs)
+
+ self.log_manager.register_structured_logger(
+ logging.getLogger('mozbuild'))
+
def build(self, what=None, disable_extra_make_dependencies=None, jobs=0,
directory=None, verbose=False, keep_going=False, mach_context=None):
"""Invoke the build backend.
``what`` defines the thing to build. If not defined, the default
target is used.
"""
- self.log_manager.register_structured_logger(logging.getLogger('mozbuild'))
-
warnings_path = self._get_state_filename('warnings.json')
monitor = self._spawn(BuildMonitor)
monitor.init(warnings_path)
ccache_start = monitor.ccache_stats()
footer = BuildProgressFooter(self.log_manager.terminal, monitor)
# Disable indexing in objdir because it is not necessary and can slow
# down builds.
@@ -1269,16 +1276,41 @@ class BuildDriver(MozbuildObject):
'https://developer.mozilla.org/docs/Developer_Guide/So_You_Just_Built_Firefox')
except Exception:
# Ignore Exceptions in case we can't find config.status (such
# as when doing OSX Universal builds)
pass
return status
+ def configure(self, options=None, buildstatus_messages=False,
+ line_handler=None):
+ def on_line(line):
+ self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
+
+ line_handler = line_handler or on_line
+
+ options = ' '.join(shell_quote(o) for o in options or ())
+ append_env = {b'CONFIGURE_ARGS': options.encode('utf-8')}
+
+ # Only print build status messages when we have an active
+ # monitor.
+ if not buildstatus_messages:
+ append_env[b'NO_BUILDSTATUS_MESSAGES'] = b'1'
+ status = self._run_make(srcdir=True, filename='client.mk',
+ target='configure', line_handler=line_handler, log=False,
+ print_directory=False, allow_parallel=False, ensure_exit_code=False,
+ append_env=append_env)
+
+ if not status:
+ print('Configure complete!')
+ print('Be sure to run |mach build| to pick up any changes');
+
+ return status
+
def install_tests(self, test_objs):
"""Install test files."""
if self.is_clobber_needed():
print(INSTALL_TESTS_CLOBBER.format(
clobber_file=os.path.join(self.topobjdir, 'CLOBBER')))
sys.exit(1)
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -1,16 +1,15 @@
# 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/.
from __future__ import absolute_import, print_function, unicode_literals
import argparse
-import collections
import hashlib
import itertools
import json
import logging
import operator
import os
import subprocess
import sys
@@ -35,17 +34,16 @@ from mozbuild.base import (
MachCommandConditions as conditions,
MozbuildObject,
)
from mozbuild.util import ensureParentDir
from mozbuild.backend import (
backends,
)
-from mozbuild.shellutil import quote as shell_quote
BUILD_WHAT_HELP = '''
What to build. Can be a top-level make target or a relative directory. If
multiple options are provided, they will be built serially. Takes dependency
information from `topsrcdir/build/dumbmake-dependencies` to build additional
targets as needed. BUILDING ONLY PARTS OF THE TREE CAN RESULT IN BAD TREE
STATE. USE AT YOUR OWN RISK.
@@ -169,38 +167,27 @@ class Build(MachCommandBase):
keep_going=keep_going,
mach_context=self._mach_context)
@Command('configure', category='build',
description='Configure the tree (run configure and config.status).')
@CommandArgument('options', default=None, nargs=argparse.REMAINDER,
help='Configure options')
def configure(self, options=None, buildstatus_messages=False, line_handler=None):
- def on_line(line):
- self.log(logging.INFO, 'build_output', {'line': line}, '{line}')
-
- line_handler = line_handler or on_line
-
- options = ' '.join(shell_quote(o) for o in options or ())
- append_env = {b'CONFIGURE_ARGS': options.encode('utf-8')}
+ from mozbuild.controller.building import (
+ BuildDriver,
+ )
- # Only print build status messages when we have an active
- # monitor.
- if not buildstatus_messages:
- append_env[b'NO_BUILDSTATUS_MESSAGES'] = b'1'
- status = self._run_make(srcdir=True, filename='client.mk',
- target='configure', line_handler=line_handler, log=False,
- print_directory=False, allow_parallel=False, ensure_exit_code=False,
- append_env=append_env)
+ driver = self._spawn(BuildDriver)
+ self.log_manager.add_terminal_logging()
- if not status:
- print('Configure complete!')
- print('Be sure to run |mach build| to pick up any changes');
-
- return status
+ return driver.configure(
+ options=options,
+ buildstatus_messages=buildstatus_messages,
+ line_handler=line_handler)
@Command('resource-usage', category='post-build',
description='Show information about system resource usage for a build.')
@CommandArgument('--address', default='localhost',
help='Address the HTTP server should listen on.')
@CommandArgument('--port', type=int, default=0,
help='Port number the HTTP server should listen on.')
@CommandArgument('--browser', default='firefox',