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

Side by Side Diff: tools/sublime/ninja_options_script.py

Issue 2129993002: [SublimeText] Get the clang flags with the same script that vim uses (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments from PS1 Created 4 years, 5 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 | « docs/linux_sublime_dev.md ('k') | 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 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2016 The Chromium Authors. All rights reserved. 2 # Copyright 2016 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 # Usage within SublimeClang: 6 # Usage within SublimeClang:
7 # "sublimeclang_options_script": "python 7 # "sublimeclang_options_script": "python
8 # ${project_path}/src/tools/sublime/ninja_options_script.py \ 8 # ${project_path}/src/tools/sublime/ninja_options_script.py \
9 # ${project_path}/src \ 9 # -d '/path/to/depot_tools'"
10 # ${project_path}/src/out/Debug" 10 #
11 # 11 #
12 # NOTE: ${project_path} expands to the directory of the Sublime project file, 12 # NOTE: ${project_path} expands to the directory of the Sublime project file,
13 # and SublimgClang passes the absolute file path to the current file as an 13 # and SublimeClang passes the absolute file path to the current file as an
14 # additional argument. 14 # additional argument. You should change the -d argument to point to your
15 # depot_tools directory.
15 16
16 import fnmatch 17 import imp
17 import logging 18 import optparse
18 import os 19 import os
19 import sys
20 20
21 # Change to an absolute reference if ninja is not on your path 21 ycm_module_path = os.path.normpath(
22 path_to_ninja = 'ninja' 22 os.path.join(os.path.dirname(os.path.abspath(__file__)),
23 '../vim/chromium.ycm_extra_conf.py'))
24 ycm_extra_conf = imp.load_source('ycm_extra_conf', ycm_module_path)
23 25
24 # Ninja file options to extract (add 'cflags' if you need the c flags too, 26 def main():
25 # although these usually break things) 27 usage = "usage: %prog [options] file"
26 ninja_file_options = ['defines', 'include_dirs', 'cflags_cc'] 28 parser = optparse.OptionParser(usage)
29 parser.add_option("-d", "--depot_tools", dest="depot_path",
30 help="path to depot_tools")
31 (options, args) = parser.parse_args()
32 if options.depot_path:
33 os.environ["PATH"] += ":%s" % options.depot_path
34 if len(args) != 1:
35 parser.error("incorrect number of arguments")
27 36
28 def merge_options_dicts(options_dict_1, options_dict_2): 37 path = os.path.realpath(args[0])
29 ''' 38 results = ycm_extra_conf.FlagsForFile(path)
30 Given two dictionaries of options, returns one dictionary with both sets of
31 options appended together.
32 39
33 Both dictionaries must have the same options, even if some of them are empty 40 for flag in results['flags']:
34 lists. 41 print flag
35 '''
36 assert set(options_dict_1.keys()) == set(options_dict_2.keys()), \
37 "Both options dicts must have the same keys"
38 final_options_dict = {}
39 for key in options_dict_1:
40 final_options_dict[key] = options_dict_1[key] + options_dict_2[key]
41 return final_options_dict
42 42
43 def extract_options_from_ninja_file(ninja_file_path, options_to_extract): 43 if __name__ == "__main__":
44 ''' 44 main()
Dirk Pranke 2016/07/20 02:00:31 nit: two spaces here?
jkarlin 2016/07/20 02:32:36 Done.
45 Extracts the given options from the file at ninja_file_path and returns them
46 as a dictionary.
47 '''
48 extracted_options = dict((o, []) for o in options_to_extract)
49 for line in open(ninja_file_path):
50 for option in options_to_extract:
51 if line.strip().startswith(option):
52 extracted_options[option] += line.split('=', 1)[1].split()
53 return extracted_options
54
55 def find_ninja_file_options(ninja_root_path, relative_file_path_to_find,
56 options_to_extract):
57 '''
58 Returns a dictionary of the given extracted options for the ninja file for
59 relative_file_path_to_find.
60
61 The options are extracted from the first *.ninja file in ninja_root_path that
62 contains relative_file_path_to_find. Otherwise, the first *.ninja file that
63 contains relative_file_path_to_find without the file extension. Otherwise, the
64 script walks up directories until it finds ninja files and then concatenates
65 the found options from all of them.
66 '''
67 matches = []
68 for root, dirnames, filenames in os.walk(ninja_root_path):
69 for filename in fnmatch.filter(filenames, '*.ninja'):
70 matches.append(os.path.join(root, filename))
71 logging.debug("Found %d Ninja targets", len(matches))
72
73 # First, look for a *.ninja file containing the full filename.
74 for ninja_file in matches:
75 for line in open(ninja_file):
76 if relative_file_path_to_find in line:
77 return extract_options_from_ninja_file(ninja_file, options_to_extract)
78
79 # Next, look for a *.ninja file containing the basename (no extension).
80 # This is a fix for header files with a corresponding cpp file.
81 for ninja_file in matches:
82 for line in open(ninja_file):
83 if os.path.splitext(relative_file_path_to_find)[0] in line:
84 all_options = extract_options_from_ninja_file(ninja_file,
85 options_to_extract)
86 if all_options['include_dirs']:
87 return all_options
88
89 # Finally, open any *.ninja files in the directory or higher.
90 current_path = os.path.join(ninja_root_path, 'obj',
91 os.path.dirname(relative_file_path_to_find))
92 while current_path != ninja_root_path:
93 if os.path.exists(current_path):
94 matches = []
95 for root, dirnames, filenames in os.walk(ninja_root_path):
96 for filename in fnmatch.filter(filenames, '*.ninja'):
97 matches.append(os.path.join(root, filename))
98 logging.debug("Found %d Ninja targets", len(matches))
99
100 matches = []
101 for match in os.listdir(current_path):
102 if match.endswith('.ninja'):
103 matches.append(os.path.join(current_path, match))
104 all_options = dict((o, []) for o in options_to_extract)
105 for ninja_file in matches:
106 all_options = merge_options_dicts(all_options,
107 extract_options_from_ninja_file(ninja_file, options_to_extract))
108 # As soon as we have some include_dirs from the ninja files, return.
109 if all_options['include_dirs']:
110 return all_options
111 current_path = os.path.dirname(current_path)
112
113 return None
114
115 project_path = sys.argv[1]
116 build_path = sys.argv[2]
117 file_path = sys.argv[3]
118
119 logging.debug("Compiling file %s\n", file_path)
120 # The file must be somewhere under the project folder...
121 if not file_path.lower().startswith(project_path.lower()):
122 logging.error("File %s is not in current project folder %s\n",
123 file_path, project_path)
124 sys.exit(1)
125 file_relative_path = os.path.relpath(file_path, project_path)
126
127 # Look for a .ninja file that contains our current file, since the ninja
128 # project file name is needed to construct the full Ninja target path.
129 logging.debug("Searching for Ninja target")
130 options = find_ninja_file_options(build_path, file_relative_path,
131 ninja_file_options)
132 if not options:
133 logging.error("File %s is not in any Ninja file under %s",
134 file_relative_path, build_path)
135 sys.exit(2)
136
137 for option in ninja_file_options:
138 for piece in options[option]:
139 # Resolve relative includes
140 if piece.startswith('-I'):
141 print('-I' + os.path.join(build_path, piece[2:]))
142 else:
143 print(piece)
OLDNEW
« no previous file with comments | « docs/linux_sublime_dev.md ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698