OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright 2014 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 """ | |
7 Clang tools on Windows are still a bit busted. The tooling can't handle | |
8 backslashes in paths, doesn't understand how to read .rsp files, etc. In | |
9 addition, ninja generates compile commands prefixed with the ninja msvc helper, | |
10 which also confuses clang. This script generates a compile DB that should mostly | |
11 work until clang tooling can be improved upstream. | |
12 """ | |
13 | |
14 import argparse | |
15 import os | |
16 import re | |
17 import json | |
18 import shlex | |
19 import subprocess | |
20 import sys | |
21 | |
22 | |
23 _NINJA_MSVC_WRAPPER = re.compile('ninja -t msvc -e .+? -- ') | |
24 _RSP_RE = re.compile(r' (@(.+?\.rsp)) ') | |
25 | |
26 | |
27 def _ProcessEntry(e): | |
28 # Strip off the ninja -t msvc wrapper. | |
29 e['command'] = _NINJA_MSVC_WRAPPER.sub('', e['command']) | |
30 | |
31 # Prepend --driver-mode=cl to the command's arguments. | |
32 # Escape backslashes so shlex doesn't try to interpret them. | |
33 escaped_command = e['command'].replace('\\', '\\\\') | |
34 split_command = shlex.split(escaped_command) | |
35 e['command'] = ' '.join( | |
36 split_command[:1] + ['--driver-mode=cl'] + split_command[1:]) | |
37 | |
38 # Expand the contents of the response file, if any. | |
39 # http://llvm.org/bugs/show_bug.cgi?id=21634 | |
40 try: | |
41 match = _RSP_RE.search(e['command']) | |
42 rsp_path = os.path.join(e['directory'], match.group(2)) | |
43 rsp_contents = file(rsp_path).read() | |
44 e['command'] = ''.join([ | |
45 e['command'][:match.start(1)], | |
46 rsp_contents, | |
47 e['command'][match.end(1):]]) | |
48 except IOError: | |
49 pass | |
50 | |
51 return e | |
52 | |
53 | |
54 def main(argv): | |
55 # Parse argument | |
56 parser = argparse.ArgumentParser() | |
57 parser.add_argument( | |
58 'build_path', | |
59 nargs='?', | |
60 help='Path to build directory', | |
61 default='out/Debug') | |
62 args = parser.parse_args() | |
63 # First, generate the compile database. | |
64 print 'Generating compile DB with ninja...' | |
65 compile_db_as_json = subprocess.check_output(shlex.split( | |
66 'ninja -C %s -t compdb cc cxx objc objcxx' % args.build_path)) | |
67 | |
68 compile_db = json.loads(compile_db_as_json) | |
69 print 'Read in %d entries from the compile db' % len(compile_db) | |
70 compile_db = [_ProcessEntry(e) for e in compile_db] | |
71 original_length = len(compile_db) | |
72 | |
73 # Filter out NaCl stuff. The clang tooling chokes on them. | |
74 compile_db = [e for e in compile_db if '_nacl.cc.pdb' not in e['command'] | |
75 and '_nacl_win64.cc.pdb' not in e['command']] | |
76 print 'Filtered out %d entries...' % (original_length - len(compile_db)) | |
77 f = file('%s/compile_commands.json' % args.build_path, 'w') | |
78 f.write(json.dumps(compile_db, indent=2)) | |
79 print 'Done!' | |
80 | |
81 | |
82 if __name__ == '__main__': | |
83 sys.exit(main(sys.argv[1:])) | |
OLD | NEW |