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