| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2017 The Chromium Authors. All rights reserved. | 2 # Copyright 2017 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Find header files missing in GN. | 6 """Find header files missing in GN. |
| 7 | 7 |
| 8 This script gets all the header files from ninja_deps, which is from the true | 8 This script gets all the header files from ninja_deps, which is from the true |
| 9 dependency generated by the compiler, and report if they don't exist in GN. | 9 dependency generated by the compiler, and report if they don't exist in GN. |
| 10 """ | 10 """ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 ans = ParseNinjaDepsOutput(NinjaSource(), out_dir) | 45 ans = ParseNinjaDepsOutput(NinjaSource(), out_dir) |
| 46 except Exception as e: | 46 except Exception as e: |
| 47 err = str(e) | 47 err = str(e) |
| 48 q.put((ans, err)) | 48 q.put((ans, err)) |
| 49 | 49 |
| 50 | 50 |
| 51 def ParseNinjaDepsOutput(ninja_out, out_dir): | 51 def ParseNinjaDepsOutput(ninja_out, out_dir): |
| 52 """Parse ninja output and get the header files""" | 52 """Parse ninja output and get the header files""" |
| 53 all_headers = set() | 53 all_headers = set() |
| 54 | 54 |
| 55 prefix = '..' + os.sep + '..' + os.sep | 55 # Ninja always uses "/", even on Windows. |
| 56 prefix = '../../' |
| 56 | 57 |
| 57 is_valid = False | 58 is_valid = False |
| 58 for line in ninja_out: | 59 for line in ninja_out: |
| 59 if line.startswith(' '): | 60 if line.startswith(' '): |
| 60 if not is_valid: | 61 if not is_valid: |
| 61 continue | 62 continue |
| 62 if line.endswith('.h') or line.endswith('.hh'): | 63 if line.endswith('.h') or line.endswith('.hh'): |
| 63 f = line.strip() | 64 f = line.strip() |
| 64 if f.startswith(prefix): | 65 if f.startswith(prefix): |
| 65 f = f[6:] # Remove the '../../' prefix | 66 f = f[6:] # Remove the '../../' prefix |
| 66 # build/ only contains build-specific files like build_config.h | 67 # build/ only contains build-specific files like build_config.h |
| 67 # and buildflag.h, and system header files, so they should be | 68 # and buildflag.h, and system header files, so they should be |
| 68 # skipped. | 69 # skipped. |
| 69 if f.startswith(out_dir) or f.startswith('out'): | 70 if f.startswith(out_dir) or f.startswith('out'): |
| 70 continue | 71 continue |
| 71 if not f.startswith('build'): | 72 if not f.startswith('build'): |
| 72 all_headers.add(f) | 73 all_headers.add(f) |
| 73 else: | 74 else: |
| 74 is_valid = line.endswith('(VALID)') | 75 is_valid = line.endswith('(VALID)') |
| 75 | 76 |
| 76 return all_headers | 77 return all_headers |
| 77 | 78 |
| 78 | 79 |
| 79 def GetHeadersFromGN(out_dir, q): | 80 def GetHeadersFromGN(out_dir, q): |
| 80 """Return all the header files from GN""" | 81 """Return all the header files from GN""" |
| 81 | 82 |
| 82 tmp = None | 83 tmp = None |
| 83 ans, err = set(), None | 84 ans, err = set(), None |
| 84 try: | 85 try: |
| 85 tmp = tempfile.mkdtemp() | 86 # Argument |dir| is needed to make sure it's on the same drive on Windows. |
| 87 # dir='' means dir='.', but doesn't introduce an unneeded prefix. |
| 88 tmp = tempfile.mkdtemp(dir='') |
| 86 shutil.copy2(os.path.join(out_dir, 'args.gn'), | 89 shutil.copy2(os.path.join(out_dir, 'args.gn'), |
| 87 os.path.join(tmp, 'args.gn')) | 90 os.path.join(tmp, 'args.gn')) |
| 88 # Do "gn gen" in a temp dir to prevent dirtying |out_dir|. | 91 # Do "gn gen" in a temp dir to prevent dirtying |out_dir|. |
| 92 gn_exe = 'gn.bat' if sys.platform == 'win32' else 'gn' |
| 89 subprocess.check_call([ | 93 subprocess.check_call([ |
| 90 os.path.join(DEPOT_TOOLS_DIR, 'gn'), 'gen', tmp, '--ide=json', '-q']) | 94 os.path.join(DEPOT_TOOLS_DIR, gn_exe), 'gen', tmp, '--ide=json', '-q']) |
| 91 gn_json = json.load(open(os.path.join(tmp, 'project.json'))) | 95 gn_json = json.load(open(os.path.join(tmp, 'project.json'))) |
| 92 ans = ParseGNProjectJSON(gn_json, out_dir, tmp) | 96 ans = ParseGNProjectJSON(gn_json, out_dir, tmp) |
| 93 except Exception as e: | 97 except Exception as e: |
| 94 err = str(e) | 98 err = str(e) |
| 95 finally: | 99 finally: |
| 96 if tmp: | 100 if tmp: |
| 97 shutil.rmtree(tmp) | 101 shutil.rmtree(tmp) |
| 98 q.put((ans, err)) | 102 q.put((ans, err)) |
| 99 | 103 |
| 100 | 104 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 116 f = out_dir + f[len(tmp_out):] | 120 f = out_dir + f[len(tmp_out):] |
| 117 all_headers.add(f) | 121 all_headers.add(f) |
| 118 | 122 |
| 119 return all_headers | 123 return all_headers |
| 120 | 124 |
| 121 | 125 |
| 122 def GetDepsPrefixes(q): | 126 def GetDepsPrefixes(q): |
| 123 """Return all the folders controlled by DEPS file""" | 127 """Return all the folders controlled by DEPS file""" |
| 124 prefixes, err = set(), None | 128 prefixes, err = set(), None |
| 125 try: | 129 try: |
| 130 gclient_exe = 'gclient.bat' if sys.platform == 'win32' else 'gclient' |
| 126 gclient_out = subprocess.check_output([ | 131 gclient_out = subprocess.check_output([ |
| 127 os.path.join(DEPOT_TOOLS_DIR, 'gclient'), | 132 os.path.join(DEPOT_TOOLS_DIR, gclient_exe), |
| 128 'recurse', '--no-progress', '-j1', | 133 'recurse', '--no-progress', '-j1', |
| 129 'python', '-c', 'import os;print os.environ["GCLIENT_DEP_PATH"]']) | 134 'python', '-c', 'import os;print os.environ["GCLIENT_DEP_PATH"]'], |
| 135 universal_newlines=True) |
| 130 for i in gclient_out.split('\n'): | 136 for i in gclient_out.split('\n'): |
| 131 if i.startswith('src/'): | 137 if i.startswith('src/'): |
| 132 i = i[4:] | 138 i = i[4:] |
| 133 prefixes.add(i) | 139 prefixes.add(i) |
| 134 except Exception as e: | 140 except Exception as e: |
| 135 err = str(e) | 141 err = str(e) |
| 136 q.put((prefixes, err)) | 142 q.put((prefixes, err)) |
| 137 | 143 |
| 138 | 144 |
| 139 def IsBuildClean(out_dir): | 145 def IsBuildClean(out_dir): |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 if len(nonexisting) > 0: | 270 if len(nonexisting) > 0: |
| 265 print '\nThe following non-existing files should be removed from gn files:' | 271 print '\nThe following non-existing files should be removed from gn files:' |
| 266 for i in nonexisting: | 272 for i in nonexisting: |
| 267 print i | 273 print i |
| 268 | 274 |
| 269 return 1 | 275 return 1 |
| 270 | 276 |
| 271 | 277 |
| 272 if __name__ == '__main__': | 278 if __name__ == '__main__': |
| 273 sys.exit(main()) | 279 sys.exit(main()) |
| OLD | NEW |