Bug 1304508 - Support passing --keep-going to make; r?ted draft
authorGregory Szorc <gps@mozilla.com>
Wed, 21 Sep 2016 13:41:34 -0700
changeset 570922 fa7352f0b64030011c96f3bd4317ccbae28cdee1
parent 570921 dd106297f07103b3acc1704fca21aa5aec268ee5
child 570923 50260ff4e3221efda4f638548ced10f05eb4438c
push id56623
push usergszorc@mozilla.com
push dateMon, 01 May 2017 17:20:54 +0000
reviewersted
bugs1304508
milestone55.0a1
Bug 1304508 - Support passing --keep-going to make; r?ted mozharness is currently making a manual `make -k` invocation. We don't want automation calling `make` directly. So teach `mach build` to accept a --keep-going argument that results in `make -k`. MozReview-Commit-ID: H3lJ4r8S4vj
python/mozbuild/mozbuild/base.py
python/mozbuild/mozbuild/mach_commands.py
--- a/python/mozbuild/mozbuild/base.py
+++ b/python/mozbuild/mozbuild/base.py
@@ -446,17 +446,17 @@ class MozbuildObject(ProcessExecutionMix
 
     def _wrap_path_argument(self, arg):
         return PathArgument(arg, self.topsrcdir, self.topobjdir)
 
     def _run_make(self, directory=None, filename=None, target=None, log=True,
             srcdir=False, allow_parallel=True, line_handler=None,
             append_env=None, explicit_env=None, ignore_errors=False,
             ensure_exit_code=0, silent=True, print_directory=True,
-            pass_thru=False, num_jobs=0):
+            pass_thru=False, num_jobs=0, keep_going=False):
         """Invoke make.
 
         directory -- Relative directory to look for Makefile in.
         filename -- Explicit makefile to run.
         target -- Makefile target(s) to make. Can be a string or iterable of
             strings.
         srcdir -- If True, invoke make from the source directory tree.
             Otherwise, make will be invoked from the object directory.
@@ -508,16 +508,19 @@ class MozbuildObject(ProcessExecutionMix
         if silent:
             args.append('-s')
 
         # Print entering/leaving directory messages. Some consumers look at
         # these to measure progress.
         if print_directory:
             args.append('-w')
 
+        if keep_going:
+            args.append('-k')
+
         if isinstance(target, list):
             args.extend(target)
         elif target:
             args.append(target)
 
         fn = self._run_command_in_objdir
 
         if srcdir:
--- a/python/mozbuild/mozbuild/mach_commands.py
+++ b/python/mozbuild/mozbuild/mach_commands.py
@@ -292,18 +292,20 @@ class Build(MachCommandBase):
     @CommandArgument('-C', '--directory', default=None,
         help='Change to a subdirectory of the build directory first.')
     @CommandArgument('what', default=None, nargs='*', help=BUILD_WHAT_HELP)
     @CommandArgument('-X', '--disable-extra-make-dependencies',
                      default=False, action='store_true',
                      help='Do not add extra make dependencies.')
     @CommandArgument('-v', '--verbose', action='store_true',
         help='Verbose output for what commands the build is running.')
+    @CommandArgument('--keep-going', action='store_true',
+                     help='Keep building after an error has occurred')
     def build(self, what=None, disable_extra_make_dependencies=None, jobs=0,
-        directory=None, verbose=False):
+        directory=None, verbose=False, keep_going=False):
         """Build the source tree.
 
         With no arguments, this will perform a full build.
 
         Positional arguments define targets to build. These can be make targets
         or patterns like "<dir>/<target>" to indicate a make target within a
         directory.
 
@@ -407,28 +409,29 @@ class Build(MachCommandBase):
 
                 # Ensure build backend is up to date. The alternative is to
                 # have rules in the invoked Makefile to rebuild the build
                 # backend. But that involves make reinvoking itself and there
                 # are undesired side-effects of this. See bug 877308 for a
                 # comprehensive history lesson.
                 self._run_make(directory=self.topobjdir, target='backend',
                     line_handler=output.on_line, log=False,
-                    print_directory=False)
+                    print_directory=False, keep_going=keep_going)
 
                 # Build target pairs.
                 for make_dir, make_target in target_pairs:
                     # We don't display build status messages during partial
                     # tree builds because they aren't reliable there. This
                     # could potentially be fixed if the build monitor were more
                     # intelligent about encountering undefined state.
                     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'})
+                        append_env={b'NO_BUILDSTATUS_MESSAGES': b'1'},
+                        keep_going=keep_going)
 
                     if status != 0:
                         break
             else:
                 # 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
@@ -456,17 +459,17 @@ class Build(MachCommandBase):
                         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)
+                        silent=not verbose, keep_going=keep_going)
 
                 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()