Bug 1293448 - Allow build backends to specify custom build commands; r?glandium
MozReview-Commit-ID: G6fICkYUDxd
--- a/python/mozbuild/mozbuild/backend/base.py
+++ b/python/mozbuild/mozbuild/backend/base.py
@@ -189,16 +189,25 @@ class BuildBackend(LoggingMixin):
This is the main method used by child classes to react to build
metadata.
"""
def consume_finished(self):
"""Called when consume() has completed handling all objects."""
+ def build(self, config, output, jobs, verbose):
+ """Called when 'mach build' is executed.
+
+ This should return the status value of a subprocess, where 0 denotes
+ success and any other value is an error code. A return value of None
+ indicates that the default 'make -f client.mk' should run.
+ """
+ return None
+
@contextmanager
def _write_file(self, path=None, fh=None, mode='rU'):
"""Context manager to write a file.
This is a glorified wrapper around FileAvoidWrite with integration to
update the summary data on this instance.
Example usage:
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -31,21 +31,20 @@ from mozbuild.base import (
MachCommandBase,
MachCommandConditions as conditions,
MozbuildObject,
MozconfigFindException,
MozconfigLoadException,
ObjdirMismatchException,
)
-from mozpack.manifests import (
- InstallManifest,
+from mozbuild.backend import (
+ backends,
+ get_backend_class,
)
-
-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
@@ -408,20 +407,49 @@ class Build(MachCommandBase):
status = self._run_make(directory=make_dir, target=make_target,
line_handler=output.on_line, log=False, print_directory=False,
ensure_exit_code=False, num_jobs=jobs, silent=not verbose,
append_env={b'NO_BUILDSTATUS_MESSAGES': b'1'})
if status != 0:
break
else:
- status = self._run_make(srcdir=True, filename='client.mk',
- line_handler=output.on_line, log=False, print_directory=False,
- allow_parallel=False, ensure_exit_code=False, num_jobs=jobs,
- silent=not verbose)
+ # Try to call the default backend's build() method. This will
+ # run configure to determine BUILD_BACKENDS if it hasn't run
+ # yet.
+ config = None
+ try:
+ config = self.config_environment
+ except Exception:
+ config_rc = self.configure()
+ if config_rc != 0:
+ return config_rc
+
+ # Even if configure runs successfully, we may have trouble
+ # getting the config_environment for some builds, such as
+ # OSX Universal builds. These have to go through client.mk
+ # regardless.
+ try:
+ config = self.config_environment
+ except Exception:
+ pass
+
+ if config:
+ active_backend = config.substs.get('BUILD_BACKENDS', [None])[0]
+ if active_backend:
+ backend_cls = get_backend_class(active_backend)(config)
+ status = backend_cls.build(self, output, jobs, verbose)
+
+ # If the backend doesn't specify a build() method, then just
+ # call client.mk directly.
+ if status is None:
+ status = self._run_make(srcdir=True, filename='client.mk',
+ line_handler=output.on_line, log=False, print_directory=False,
+ allow_parallel=False, ensure_exit_code=False, num_jobs=jobs,
+ silent=not verbose)
self.log(logging.WARNING, 'warning_summary',
{'count': len(monitor.warnings_database)},
'{count} compiler warnings present.')
monitor.finish(record_usage=status==0)
high_finder, finder_percent = monitor.have_high_finder_usage()