Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(817)

Side by Side Diff: tools/vim/chromium.ycm_extra_conf.py

Issue 1137303005: [Vim/YCM] Calculate system library paths based on Clang++ binary path. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Switch to using shlex and look at first two tokens in commandline. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 # Autocompletion config for YouCompleteMe in Chromium. 5 # Autocompletion config for YouCompleteMe in Chromium.
6 # 6 #
7 # USAGE: 7 # USAGE:
8 # 8 #
9 # 1. Install YCM [https://github.com/Valloric/YouCompleteMe] 9 # 1. Install YCM [https://github.com/Valloric/YouCompleteMe]
10 # (Googlers should check out [go/ycm]) 10 # (Googlers should check out [go/ycm])
(...skipping 22 matching lines...) Expand all
33 # 33 #
34 # * That whole ninja & clang thing? We could support other configs if someone 34 # * That whole ninja & clang thing? We could support other configs if someone
35 # were willing to write the correct commands and a parser. 35 # were willing to write the correct commands and a parser.
36 # 36 #
37 # * This has only been tested on gPrecise. 37 # * This has only been tested on gPrecise.
38 38
39 39
40 import os 40 import os
41 import os.path 41 import os.path
42 import re 42 import re
43 import shlex
43 import subprocess 44 import subprocess
44 import sys 45 import sys
45 46
46 47
47 def SystemIncludeDirectoryFlags(): 48 def SystemIncludeDirectoryFlags(clang_binary, clang_flags):
48 """Determines compile flags to include the system include directories. 49 """Determines compile flags to include the system include directories.
49 50
50 Use as a workaround for https://github.com/Valloric/YouCompleteMe/issues/303 51 Use as a workaround for https://github.com/Valloric/YouCompleteMe/issues/303
51 52
53 Args:
54 clang_binary: (String) Path to clang binary.
55 clang_flags: (List of Strings) List of additional flags to clang. It may
56 affect the choice of system include directories if -stdlib= is specified.
57
52 Returns: 58 Returns:
53 (List of Strings) Compile flags to append. 59 (List of Strings) Compile flags to append.
54 """ 60 """
61 all_flags = ['-v', '-E', '-x', 'c++'] + clang_flags + ['-']
55 try: 62 try:
56 with open(os.devnull, 'rb') as DEVNULL: 63 with open(os.devnull, 'rb') as DEVNULL:
57 output = subprocess.check_output(['clang', '-v', '-E', '-x', 'c++', '-'], 64 output = subprocess.check_output([clang_binary] + all_flags,
58 stdin=DEVNULL, stderr=subprocess.STDOUT) 65 stdin=DEVNULL, stderr=subprocess.STDOUT)
59 except: 66 except:
60 return [] 67 return []
61 includes_regex = r'#include <\.\.\.> search starts here:\s*' \ 68 includes_regex = r'#include <\.\.\.> search starts here:\s*' \
62 r'(.*?)End of search list\.' 69 r'(.*?)End of search list\.'
63 includes = re.search(includes_regex, output.decode(), re.DOTALL).group(1) 70 includes = re.search(includes_regex, output.decode(), re.DOTALL).group(1)
64 flags = [] 71 flags = []
65 for path in includes.splitlines(): 72 for path in includes.splitlines():
66 path = path.strip() 73 path = path.strip()
67 if os.path.isdir(path): 74 if os.path.isdir(path):
68 flags.append('-isystem') 75 flags.append('-isystem')
69 flags.append(path) 76 flags.append(path)
70 return flags 77 return flags
71 78
72
73 _system_include_flags = SystemIncludeDirectoryFlags()
74
75 # Flags from YCM's default config. 79 # Flags from YCM's default config.
76 flags = [ 80 _default_flags = [
77 '-DUSE_CLANG_COMPLETER', 81 '-DUSE_CLANG_COMPLETER',
78 '-std=c++11', 82 '-std=c++11',
79 '-x', 83 '-x',
80 'c++', 84 'c++',
81 ] 85 ]
82 86
83
84 def PathExists(*args): 87 def PathExists(*args):
85 return os.path.exists(os.path.join(*args)) 88 return os.path.exists(os.path.join(*args))
86 89
90 def LooksLikeClangCommand(command):
91 return command.endswith('clang++') or command.endswith('clang')
87 92
88 def FindChromeSrcFromFilename(filename): 93 def FindChromeSrcFromFilename(filename):
89 """Searches for the root of the Chromium checkout. 94 """Searches for the root of the Chromium checkout.
90 95
91 Simply checks parent directories until it finds .gclient and src/. 96 Simply checks parent directories until it finds .gclient and src/.
92 97
93 Args: 98 Args:
94 filename: (String) Path to source file being edited. 99 filename: (String) Path to source file being edited.
95 100
96 Returns: 101 Returns:
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 # clang command. 188 # clang command.
184 clang_line = None 189 clang_line = None
185 for line in reversed(stdout.split('\n')): 190 for line in reversed(stdout.split('\n')):
186 if 'clang' in line: 191 if 'clang' in line:
187 clang_line = line 192 clang_line = line
188 break 193 break
189 else: 194 else:
190 return chrome_flags 195 return chrome_flags
191 196
192 # Parse flags that are important for YCM's purposes. 197 # Parse flags that are important for YCM's purposes.
193 for flag in clang_line.split(' '): 198 clang_tokens = shlex.split(clang_line)
199 for flag in clang_tokens:
194 if flag.startswith('-I'): 200 if flag.startswith('-I'):
195 # Relative paths need to be resolved, because they're relative to the 201 # Relative paths need to be resolved, because they're relative to the
196 # output dir, not the source. 202 # output dir, not the source.
197 if flag[2] == '/': 203 if flag[2] == '/':
198 chrome_flags.append(flag) 204 chrome_flags.append(flag)
199 else: 205 else:
200 abs_path = os.path.normpath(os.path.join(out_dir, flag[2:])) 206 abs_path = os.path.normpath(os.path.join(out_dir, flag[2:]))
201 chrome_flags.append('-I' + abs_path) 207 chrome_flags.append('-I' + abs_path)
202 elif flag.startswith('-std'): 208 elif flag.startswith('-std'):
203 chrome_flags.append(flag) 209 chrome_flags.append(flag)
204 elif flag.startswith('-') and flag[1] in 'DWFfmO': 210 elif flag.startswith('-') and flag[1] in 'DWFfmO':
205 if flag == '-Wno-deprecated-register' or flag == '-Wno-header-guard': 211 if flag == '-Wno-deprecated-register' or flag == '-Wno-header-guard':
206 # These flags causes libclang (3.3) to crash. Remove it until things 212 # These flags causes libclang (3.3) to crash. Remove it until things
207 # are fixed. 213 # are fixed.
208 continue 214 continue
209 chrome_flags.append(flag) 215 chrome_flags.append(flag)
210 216
217 # Assume that the command for invoking clang++ looks like one of the
218 # following:
219 # 1) /path/to/clang/clang++ arguments
220 # 2) /some/wrapper /path/to/clang++ arguments
221 #
222 # We'll look for a token that looks like Clang command within the first two
223 # tokens of the command line and treat it as the clang++ binary. Using the
224 # command line upto the Clang-like token isn't always feasible since the
225 # wrapper may not like the invocation used by SystemIncludeDirectoryFlags()
226 # although the real clang++ binary does.
227 for command in clang_tokens[0:2]:
228 if LooksLikeClangCommand(command):
229 chrome_flags += SystemIncludeDirectoryFlags(command, chrome_flags)
230 break
231
211 return chrome_flags 232 return chrome_flags
212 233
213 234
214 def FlagsForFile(filename): 235 def FlagsForFile(filename):
215 """This is the main entry point for YCM. Its interface is fixed. 236 """This is the main entry point for YCM. Its interface is fixed.
216 237
217 Args: 238 Args:
218 filename: (String) Path to source file being edited. 239 filename: (String) Path to source file being edited.
219 240
220 Returns: 241 Returns:
221 (Dictionary) 242 (Dictionary)
222 'flags': (List of Strings) Command line flags. 243 'flags': (List of Strings) Command line flags.
223 'do_cache': (Boolean) True if the result should be cached. 244 'do_cache': (Boolean) True if the result should be cached.
224 """ 245 """
225 chrome_root = FindChromeSrcFromFilename(filename) 246 chrome_root = FindChromeSrcFromFilename(filename)
226 chrome_flags = GetClangCommandFromNinjaForFilename(chrome_root, 247 chrome_flags = GetClangCommandFromNinjaForFilename(chrome_root,
227 filename) 248 filename)
228 final_flags = flags + chrome_flags + _system_include_flags 249 final_flags = _default_flags + chrome_flags
229 250
230 return { 251 return {
231 'flags': final_flags, 252 'flags': final_flags,
232 'do_cache': True 253 'do_cache': True
233 } 254 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698