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.
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.
22 _NINJA_MSVC_WRAPPER
= re
.compile('ninja -t msvc -e .+? -- ')
23 _RSP_RE
= re
.compile(r
' (@(.+?\.rsp)) ')
27 # Strip off the ninja -t msvc wrapper.
28 e
['command'] = _NINJA_MSVC_WRAPPER
.sub('', e
['command'])
30 # Prepend --driver-mode=cl to the command's arguments.
31 # Escape backslashes so shlex doesn't try to interpret them.
32 escaped_command
= e
['command'].replace('\\', '\\\\')
33 split_command
= shlex
.split(escaped_command
)
34 e
['command'] = ' '.join(
35 split_command
[:1] + ['--driver-mode=cl'] + split_command
[1:])
37 # Expand the contents of the response file, if any.
38 # http://llvm.org/bugs/show_bug.cgi?id=21634
40 match
= _RSP_RE
.search(e
['command'])
41 rsp_path
= os
.path
.join(e
['directory'], match
.group(2))
42 rsp_contents
= file(rsp_path
).read()
43 e
['command'] = ''.join([
44 e
['command'][:match
.start(1)],
46 e
['command'][match
.end(1):]])
50 # TODO(dcheng): This should be implemented in Clang tooling.
51 # http://llvm.org/bugs/show_bug.cgi?id=19687
52 # Finally, use slashes instead of backslashes to avoid bad escaping by the
53 # tooling. This should really only matter for command, but we do it for all
54 # keys for consistency.
55 e
['directory'] = e
['directory'].replace('\\', '/')
56 e
['command'] = e
['command'].replace('\\', '/')
57 e
['file'] = e
['file'].replace('\\', '/')
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 out/Debug -t compdb cc cxx objc objcxx'))
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
)
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('out/Debug/compile_commands.json', 'w')
78 f
.write(json
.dumps(compile_db
, indent
=2))
82 if __name__
== '__main__':
83 sys
.exit(main(sys
.argv
[1:]))