diff options
Diffstat (limited to 'tools/buildman/builder.py')
-rw-r--r-- | tools/buildman/builder.py | 140 |
1 files changed, 76 insertions, 64 deletions
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index aa2ffe16f6c..76252b90792 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -108,7 +108,7 @@ u-boot/ source directory boards: List of Board objects which have line in the error/warning output errline: The text of the error line """ -ErrLine = collections.namedtuple('ErrLine', 'char,boards,errline') +ErrLine = collections.namedtuple('ErrLine', 'char,brds,errline') # Possible build outcomes OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = list(range(4)) @@ -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 @@ -662,17 +669,15 @@ class Builder: """ sym = {} for line in fd.readlines(): - try: - if line.strip(): - size, type, name = line[:-1].split() - except: - tprint("Invalid line in file '%s': '%s'" % (fname, line[:-1])) - continue - if type in 'tTdDbB': - # function names begin with '.' on 64-bit powerpc - if '.' in name[1:]: - name = 'static.' + name.split('.')[0] - sym[name] = sym.get(name, 0) + int(size, 16) + line = line.strip() + parts = line.split() + if line and len(parts) == 3: + size, type, name = line.split() + if type in 'tTdDbB': + # function names begin with '.' on 64-bit powerpc + if '.' in name[1:]: + name = 'static.' + name.split('.')[0] + sym[name] = sym.get(name, 0) + int(size, 16) return sym def _ProcessConfig(self, fname): @@ -834,8 +839,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 @@ -867,11 +873,11 @@ class Builder: config = {} environment = {} - for board in boards_selected.values(): - outcome = self.GetBuildOutcome(commit_upto, board.target, + for brd in boards_selected.values(): + outcome = self.GetBuildOutcome(commit_upto, brd.target, read_func_sizes, read_config, read_environment) - board_dict[board.target] = outcome + board_dict[brd.target] = outcome last_func = None last_was_warning = False for line in outcome.err_lines: @@ -886,29 +892,29 @@ class Builder: if is_warning or (last_was_warning and is_note): if last_func: AddLine(warn_lines_summary, warn_lines_boards, - last_func, board) + last_func, brd) AddLine(warn_lines_summary, warn_lines_boards, - line, board) + line, brd) else: if last_func: AddLine(err_lines_summary, err_lines_boards, - last_func, board) + last_func, brd) AddLine(err_lines_summary, err_lines_boards, - line, board) + line, brd) last_was_warning = is_warning last_func = None - tconfig = Config(self.config_filenames, board.target) + tconfig = Config(self.config_filenames, brd.target) for fname in self.config_filenames: if outcome.config: for key, value in outcome.config[fname].items(): tconfig.Add(fname, key, value) - config[board.target] = tconfig + config[brd.target] = tconfig - tenvironment = Environment(board.target) + tenvironment = Environment(brd.target) if outcome.environment: for key, value in outcome.environment.items(): tenvironment.Add(key, value) - environment[board.target] = tenvironment + environment[brd.target] = tenvironment return (board_dict, err_lines_summary, err_lines_boards, warn_lines_summary, warn_lines_boards, config, environment) @@ -963,9 +969,8 @@ class Builder: board.target """ self._base_board_dict = {} - for board in board_selected: - self._base_board_dict[board] = Builder.Outcome(0, [], [], {}, {}, - {}) + for brd in board_selected: + self._base_board_dict[brd] = Builder.Outcome(0, [], [], {}, {}, {}) self._base_err_lines = [] self._base_warn_lines = [] self._base_err_line_boards = {} @@ -1209,14 +1214,14 @@ class Builder: List of boards with that error line, or [] if the user has not requested such a list """ - boards = [] + brds = [] board_set = set() if self._list_error_boards: - for board in line_boards[line]: - if not board in board_set: - boards.append(board) - board_set.add(board) - return boards + for brd in line_boards[line]: + if not brd in board_set: + brds.append(brd) + board_set.add(brd) + return brds def _CalcErrorDelta(base_lines, base_line_boards, lines, line_boards, char): @@ -1319,8 +1324,7 @@ class Builder: if err_lines: out_list = [] for line in err_lines: - boards = '' - names = [board.target for board in line.boards] + names = [brd.target for brd in line.brds] board_str = ' '.join(names) if names else '' if board_str: out = self.col.build(colour, line.char + '(') @@ -1369,8 +1373,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, '', @@ -1535,9 +1545,9 @@ class Builder: # Get a list of boards that did not get built, if needed not_built = [] - for board in board_selected: - if not board in board_dict: - not_built.append(board) + for brd in board_selected: + if not brd in board_dict: + not_built.append(brd) if not_built: tprint("Boards not built (%d): %s" % (len(not_built), ', '.join(not_built))) @@ -1746,14 +1756,15 @@ 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 = [] # Create jobs to build all commits for each board for brd in board_selected.values(): job = builderthread.BuilderJob() - job.board = brd + job.brd = brd job.commits = commits job.keep_outputs = keep_outputs job.work_in_output = self.work_in_output @@ -1773,24 +1784,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) |