Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(837)

Unified Diff: scripts/slave/compile.py

Issue 1766873002: Collect failed "target"s from ninja in the compile step on Waterfall. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@check_target_existence
Patch Set: Rebase. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | scripts/slave/recipe_modules/chromium/api.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: scripts/slave/compile.py
diff --git a/scripts/slave/compile.py b/scripts/slave/compile.py
index 3a4eba45dcf4842a2c600dcdc62764ca2bb48346..0db39165e746c0caea99c0fc1745ca4822fb36dd 100755
--- a/scripts/slave/compile.py
+++ b/scripts/slave/compile.py
@@ -13,6 +13,7 @@
import datetime
import errno
+import json
import multiprocessing
import optparse
import os
@@ -75,6 +76,54 @@ class EchoDict(dict):
fh.write('\n')
+class NinjaFailedTargetCollector(object):
+ """This is to scrape the ninja output to collect failed "target"s.
+
+ A target here is actually an output node in the ninja build graph. Thus it
+ could be an object file, a lib, an executable, output of an action, etc.
+
+ When a build edge fails, its output nodes will be printed in a single line
+ in the following format these without quotes:
+ "FAILED: obj/path/to/file1.o obj/path/to/file2.o "
+ "FAILED: gen/path/to/name.cc gen/path/to/name.h "
+
+ If a target is specified in the test spec but it is not defined in the gn or
+ gyp build config, an "unknown target" error occurs in these two possible
+ formats without quotes:
+ "ninja: error: unknown target 'executable_target'"
+ "ninja: error: unknown target 'exe1', did you mean 'exe2'?"
+ """
+ NINJA_FAILURE_PREFIX = 'FAILED: '
+ NINJA_UNKNOWN_TARGET_PREFIX = 'ninja: error: unknown target '
+
+ def __init__(self, file_path):
+ self.file_path = file_path
+ self.failed_targets = []
+ self.unknown_targets = []
+ self.unrecognized_format = False
+
+ def extract(self, line):
+ if line.startswith(self.NINJA_FAILURE_PREFIX):
+ for node in line[len(self.NINJA_FAILURE_PREFIX):].split(' '):
+ node = node.strip()
+ if node:
+ self.failed_targets.append(node)
+ elif line.startswith(self.NINJA_UNKNOWN_TARGET_PREFIX):
+ parts = line[len(self.NINJA_UNKNOWN_TARGET_PREFIX):].split('\'')
+ if len(parts) >= 3 and parts[1].strip():
+ self.unknown_targets.append(parts[1].strip())
+ else:
+ self.unrecognized_format = True
+
+ def dump_as_json(self):
+ with open(self.file_path, 'wb') as f:
+ json.dump({
+ 'failed_targets': self.failed_targets,
+ 'unknown_targets': self.unknown_targets,
+ 'unrecognized_format': self.unrecognized_format,
+ }, f)
+
+
def ReadHKLMValue(path, value):
"""Retrieve the install path from the registry for Visual Studio 8.0 and
Incredibuild."""
@@ -953,7 +1002,15 @@ def main_ninja(options, args):
# Run the build.
env.print_overrides()
- exit_status = chromium_utils.RunCommand(command, env=env)
+ kwargs = {
+ 'env': env,
+ }
+ failed_target_collector = None
+ if options.ninja_compile_failure:
+ failed_target_collector = NinjaFailedTargetCollector(
+ options.ninja_compile_failure)
+ kwargs['parser_func'] = failed_target_collector.extract
+ exit_status = chromium_utils.RunCommand(command, **kwargs)
if exit_status == 0 and options.ninja_ensure_up_to_date:
# Run the build again if we want to check that the no-op build is clean.
filter_obj = EnsureUpToDateFilter()
@@ -967,6 +1024,8 @@ def main_ninja(options, args):
print 'wasn\'t a no-op). Consult the first "ninja explain:" line for a'
print 'likely culprit.'
return 1
+ if exit_status != 0 and failed_target_collector:
+ failed_target_collector.dump_as_json()
return exit_status
finally:
goma_teardown(options, env, exit_status)
@@ -1280,6 +1339,10 @@ def real_main():
help='Checks the output of the ninja builder to '
'confirm that a second compile immediately '
'the first is a no-op.')
+ option_parser.add_option('--ninja-compile-failure',
+ help='Specify a file to dump detailed info of '
+ 'compile failure from ninja. Effective only '
+ 'when building with ninja.')
options, args = option_parser.parse_args()
« no previous file with comments | « no previous file | scripts/slave/recipe_modules/chromium/api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698