[PATCH 02/19] buildman: Support running from an IDE

Simon Glass sjg at chromium.org
Tue Jul 12 03:03:56 CEST 2022


Add a flag to allow buildman to behave properly for use from an IDE. This
shows error/warning output on stderr and drops all summary and progress
information.

This should normally only be used when building a single board.

Fix up a confusing comment for GetResultSummary() while we are here, since
we want to use the Outcome object to access the unprocessed error lines
from the build.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 tools/buildman/README     | 15 +++++++++
 tools/buildman/builder.py | 68 ++++++++++++++++++++++++---------------
 tools/buildman/cmdline.py |  2 ++
 tools/buildman/control.py |  7 ++--
 4 files changed, 63 insertions(+), 29 deletions(-)

diff --git a/tools/buildman/README b/tools/buildman/README
index 49438cb909d..c67a074cb50 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -1092,6 +1092,21 @@ This will write the full build into /tmp/build including object files. You must
 specify the output directory with -o when using -w.
 
 
+Support for IDEs (Integrated Development Environments)
+======================================================
+
+Normally buildman summarises the output and shows information indicating the
+meaning of each line of output. For example a '+' symbol appears at the start of
+each error line. Also, buildman prints information about what it is about to do,
+along with a summary at the end.
+
+When using buildman from an IDE, it is helpful to drop this behaviour. Use the
+-I/--ide option for that. You might find -W helpful also so that warnings do
+not cause the build to fail:
+
+   buildman -o /tmp/build --board sandbox -wWI
+
+
 Changing the configuration
 ==========================
 
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index aa2ffe16f6c..078ddf070d3 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -213,6 +213,8 @@ class Builder:
             threading is not being used
         _terminated: Thread was terminated due to an error
         _restarting_config: True if 'Restart config' is detected in output
+        _ide: Produce output suitable for an Integrated Development Environment,
+            i.e. dont emit progress information and put errors/warnings on stderr
     """
     class Outcome:
         """Records a build outcome for a single make invocation
@@ -325,6 +327,7 @@ class Builder:
         self.config_filenames = BASE_CONFIG_FILENAMES
         self.work_in_output = work_in_output
         self.adjust_cfg = adjust_cfg
+        self._ide = False
 
         if not self.squash_config_y:
             self.config_filenames += EXTRA_CONFIG_FILENAMES
@@ -382,7 +385,7 @@ class Builder:
                           show_detail=False, show_bloat=False,
                           list_error_boards=False, show_config=False,
                           show_environment=False, filter_dtb_warnings=False,
-                          filter_migration_warnings=False):
+                          filter_migration_warnings=False, ide=False):
         """Setup display options for the builder.
 
         Args:
@@ -397,6 +400,8 @@ class Builder:
                 compiler
             filter_migration_warnings: Filter out any warnings about migrating
                 a board to driver model
+            ide: Create output that can be parsed by an IDE. There is no '+' prefix on
+                error lines and output on stderr stays on stderr.
         """
         self._show_errors = show_errors
         self._show_sizes = show_sizes
@@ -407,6 +412,7 @@ class Builder:
         self._show_environment = show_environment
         self._filter_dtb_warnings = filter_dtb_warnings
         self._filter_migration_warnings = filter_migration_warnings
+        self._ide = ide
 
     def _AddTimestamp(self):
         """Add a new timestamp to the list and record the build period.
@@ -535,8 +541,9 @@ class Builder:
             line += '%s  : ' % self._complete_delay
 
         line += target
-        terminal.print_clear()
-        tprint(line, newline=False, limit_to_line=True)
+        if not self._ide:
+            terminal.print_clear()
+            tprint(line, newline=False, limit_to_line=True)
 
     def _GetOutputDir(self, commit_upto):
         """Get the name of the output directory for a commit number
@@ -834,8 +841,9 @@ class Builder:
 
         Returns:
             Tuple:
-                Dict containing boards which passed building this commit.
-                    keyed by board.target
+                Dict containing boards which built this commit:
+                    key: board.target
+                    value: Builder.Outcome object
                 List containing a summary of error lines
                 Dict keyed by error line, containing a list of the Board
                     objects with that error
@@ -1369,8 +1377,14 @@ class Builder:
         better_warn, worse_warn = _CalcErrorDelta(self._base_warn_lines,
                 self._base_warn_line_boards, warn_lines, warn_line_boards, 'w')
 
+        # For the IDE mode, print out all the output
+        if self._ide:
+            outcome = board_dict[target]
+            for line in outcome.err_lines:
+                sys.stderr.write(line)
+
         # Display results by arch
-        if any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards,
+        elif any((ok_boards, warn_boards, err_boards, unknown_boards, new_boards,
                 worse_err, better_err, worse_warn, better_warn)):
             arch_list = {}
             self.AddOutcome(board_selected, arch_list, ok_boards, '',
@@ -1746,7 +1760,8 @@ class Builder:
         self._PrepareWorkingSpace(min(self.num_threads, len(board_selected)),
                 commits is not None)
         self._PrepareOutputSpace()
-        tprint('\rStarting build...', newline=False)
+        if not self._ide:
+            tprint('\rStarting build...', newline=False)
         self.SetupBuild(board_selected, commits)
         self.ProcessResult(None)
         self.thread_exceptions = []
@@ -1773,24 +1788,25 @@ class Builder:
 
             # Wait until we have processed all output
             self.out_queue.join()
-        tprint()
-
-        msg = 'Completed: %d total built' % self.count
-        if self.already_done:
-           msg += ' (%d previously' % self.already_done
-           if self.already_done != self.count:
-               msg += ', %d newly' % (self.count - self.already_done)
-           msg += ')'
-        duration = datetime.now() - self._start_time
-        if duration > timedelta(microseconds=1000000):
-            if duration.microseconds >= 500000:
-                duration = duration + timedelta(seconds=1)
-            duration = duration - timedelta(microseconds=duration.microseconds)
-            rate = float(self.count) / duration.total_seconds()
-            msg += ', duration %s, rate %1.2f' % (duration, rate)
-        tprint(msg)
-        if self.thread_exceptions:
-            tprint('Failed: %d thread exceptions' % len(self.thread_exceptions),
-                  colour=self.col.RED)
+        if not self._ide:
+            tprint()
+
+            msg = 'Completed: %d total built' % self.count
+            if self.already_done:
+                msg += ' (%d previously' % self.already_done
+            if self.already_done != self.count:
+                msg += ', %d newly' % (self.count - self.already_done)
+            msg += ')'
+            duration = datetime.now() - self._start_time
+            if duration > timedelta(microseconds=1000000):
+                if duration.microseconds >= 500000:
+                    duration = duration + timedelta(seconds=1)
+                duration = duration - timedelta(microseconds=duration.microseconds)
+                rate = float(self.count) / duration.total_seconds()
+                msg += ', duration %s, rate %1.2f' % (duration, rate)
+            tprint(msg)
+            if self.thread_exceptions:
+                tprint('Failed: %d thread exceptions' % len(self.thread_exceptions),
+                    colour=self.col.RED)
 
         return (self.fail, self.warned, self.thread_exceptions)
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index ddcb1ec5fcd..cef2068c983 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -59,6 +59,8 @@ def ParseArgs():
     parser.add_option('-i', '--in-tree', dest='in_tree',
           action='store_true', default=False,
           help='Build in the source tree instead of a separate directory')
+    parser.add_option('-I', '--ide', action='store_true', default=False,
+          help='Create build output that can be parsed by an IDE')
     parser.add_option('-j', '--jobs', dest='jobs', type='int',
           default=None, help='Number of jobs to run at once (passed to make)')
     parser.add_option('-k', '--keep-outputs', action='store_true',
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index beade62408b..68dca97413f 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -359,8 +359,9 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
         else:
             commits = None
 
-        tprint(GetActionSummary(options.summary, commits, board_selected,
-                               options))
+        if not options.ide:
+            tprint(GetActionSummary(options.summary, commits, board_selected,
+                                    options))
 
         # We can't show function sizes without board details at present
         if options.show_bloat:
@@ -369,7 +370,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
             options.show_errors, options.show_sizes, options.show_detail,
             options.show_bloat, options.list_error_boards, options.show_config,
             options.show_environment, options.filter_dtb_warnings,
-            options.filter_migration_warnings)
+            options.filter_migration_warnings, options.ide)
         if options.summary:
             builder.ShowSummary(commits, board_selected)
         else:
-- 
2.37.0.144.g8ac04bfd2-goog



More information about the U-Boot mailing list