diff --git a/build/check_gn_headers.py b/build/check_gn_headers.py index fe884db..c5095e61 100755 --- a/build/check_gn_headers.py +++ b/build/check_gn_headers.py
@@ -38,13 +38,13 @@ ans, err = set(), None try: - ans = ParseNinjaDepsOutput(NinjaSource()) + ans = ParseNinjaDepsOutput(NinjaSource(), out_dir) except Exception as e: err = str(e) q.put((ans, err)) -def ParseNinjaDepsOutput(ninja_out): +def ParseNinjaDepsOutput(ninja_out, out_dir): """Parse ninja output and get the header files""" all_headers = set() @@ -62,6 +62,8 @@ # build/ only contains build-specific files like build_config.h # and buildflag.h, and system header files, so they should be # skipped. + if f.startswith(out_dir) or f.startswith('out'): + continue if not f.startswith('build'): all_headers.add(f) else: @@ -128,6 +130,12 @@ q.put((prefixes, err)) +def IsBuildClean(out_dir): + cmd = ['ninja', '-C', out_dir, '-n'] + out = subprocess.check_output(cmd) + return 'no work to do.' in out + + def ParseWhiteList(whitelist): out = set() for line in whitelist.split('\n'): @@ -150,6 +158,16 @@ def main(): + + def DumpJson(data): + if args.json: + with open(args.json, 'w') as f: + json.dump(data, f) + + def PrintError(msg): + DumpJson([]) + parser.error(msg) + parser = argparse.ArgumentParser(description=''' NOTE: Use ninja to build all targets in OUT_DIR before running this script.''') @@ -158,12 +176,27 @@ parser.add_argument('--json', help='JSON output filename for missing headers') parser.add_argument('--whitelist', help='file containing whitelist') + parser.add_argument('--skip-dirty-check', action='store_true', + help='skip checking whether the build is dirty') args, _extras = parser.parse_known_args() if not os.path.isdir(args.out_dir): parser.error('OUT_DIR "%s" does not exist.' % args.out_dir) + if not args.skip_dirty_check and not IsBuildClean(args.out_dir): + dirty_msg = 'OUT_DIR looks dirty. You need to build all there.' + if args.json: + # Assume running on the bots. Silently skip this step. + # This is possible because "analyze" step can be wrong due to + # underspecified header files. See crbug.com/725877 + print dirty_msg + DumpJson([]) + return 0 + else: + # Assume running interactively. + parser.error(dirty_msg) + d_q = Queue() d_p = Process(target=GetHeadersFromNinja, args=(args.out_dir, d_q,)) d_p.start() @@ -190,29 +223,29 @@ deps_p.join() if d_err: - parser.error(d_err) + PrintError(d_err) if gn_err: - parser.error(gn_err) + PrintError(gn_err) if deps_err: - parser.error(deps_err) + PrintError(deps_err) if len(GetNonExistingFiles(d)) > 0: - parser.error('''Found non-existing files in ninja deps. You should - build all in OUT_DIR.''') + print 'Non-existing files in ninja deps:', GetNonExistingFiles(d) + PrintError('Found non-existing files in ninja deps. You should ' + + 'build all in OUT_DIR.') if len(d) == 0: - parser.error('OUT_DIR looks empty. You should build all there.') + PrintError('OUT_DIR looks empty. You should build all there.') if any((('/gen/' in i) for i in nonexisting)): - parser.error('OUT_DIR looks wrong. You should build all there.') + PrintError('OUT_DIR looks wrong. You should build all there.') if args.whitelist: whitelist = ParseWhiteList(open(args.whitelist).read()) missing -= whitelist + nonexisting -= whitelist missing = sorted(missing) nonexisting = sorted(nonexisting) - if args.json: - with open(args.json, 'w') as f: - json.dump(missing, f) + DumpJson(sorted(missing + nonexisting)) if len(missing) == 0 and len(nonexisting) == 0: return 0
diff --git a/build/check_gn_headers_unittest.py b/build/check_gn_headers_unittest.py index 78c7877..e0853fd 100755 --- a/build/check_gn_headers_unittest.py +++ b/build/check_gn_headers_unittest.py
@@ -25,6 +25,7 @@ ../../c.cc ../../build/a.h gen/b.h + ../../out/Release/gen/no.h ../../dir3/path/b.h ../../c3.hh ''' @@ -64,7 +65,8 @@ class CheckGnHeadersTest(unittest.TestCase): def testNinja(self): - headers = check_gn_headers.ParseNinjaDepsOutput(ninja_input.split('\n')) + headers = check_gn_headers.ParseNinjaDepsOutput( + ninja_input.split('\n'), 'out/Release') expected = set([ 'dir/path/b.h', 'c.hh', @@ -78,7 +80,7 @@ os.sep = '\\' headers = check_gn_headers.ParseNinjaDepsOutput( - ninja_input_win.split('\n')) + ninja_input_win.split('\n'), 'out\\Release') expected = set([ 'dir\\path\\b.h', 'c.hh',
diff --git a/build/toolchain/win/setup_toolchain.py b/build/toolchain/win/setup_toolchain.py index e8b0849..d91bf9b2 100644 --- a/build/toolchain/win/setup_toolchain.py +++ b/build/toolchain/win/setup_toolchain.py
@@ -50,7 +50,7 @@ # path. Add the path to this python here so that if it's not in the # path when ninja is run later, python will still be found. setting = os.path.dirname(sys.executable) + os.pathsep + setting - env[var.upper()] = setting + env[var.upper()] = setting.lower() break if sys.platform in ('win32', 'cygwin'): for required in ('SYSTEMROOT', 'TEMP', 'TMP'):