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

Side by Side Diff: pylib/gyp/generator/eclipse.py

Issue 145363002: Eclipse generator now uses compiler's default include dirs. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: add comment Created 6 years, 11 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 | Annotate | Revision Log
« 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 Google Inc. All rights reserved. 1 # Copyright (c) 2012 Google Inc. 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 """GYP backend that generates Eclipse CDT settings files. 5 """GYP backend that generates Eclipse CDT settings files.
6 6
7 This backend DOES NOT generate Eclipse CDT projects. Instead, it generates XML 7 This backend DOES NOT generate Eclipse CDT projects. Instead, it generates XML
8 files that can be imported into an Eclipse CDT project. The XML file contains a 8 files that can be imported into an Eclipse CDT project. The XML file contains a
9 list of include paths and symbols (i.e. defines). 9 list of include paths and symbols (i.e. defines).
10 10
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 def CalculateGeneratorInputInfo(params): 70 def CalculateGeneratorInputInfo(params):
71 """Calculate the generator specific info that gets fed to input (called by 71 """Calculate the generator specific info that gets fed to input (called by
72 gyp).""" 72 gyp)."""
73 generator_flags = params.get('generator_flags', {}) 73 generator_flags = params.get('generator_flags', {})
74 if generator_flags.get('adjust_static_libraries', False): 74 if generator_flags.get('adjust_static_libraries', False):
75 global generator_wants_static_library_dependencies_adjusted 75 global generator_wants_static_library_dependencies_adjusted
76 generator_wants_static_library_dependencies_adjusted = True 76 generator_wants_static_library_dependencies_adjusted = True
77 77
78 78
79 def GetAllIncludeDirectories(target_list, target_dicts, 79 def GetAllIncludeDirectories(target_list, target_dicts,
80 shared_intermediate_dirs, config_name, params): 80 shared_intermediate_dirs, config_name, params,
81 compiler_path):
81 """Calculate the set of include directories to be used. 82 """Calculate the set of include directories to be used.
82 83
83 Returns: 84 Returns:
84 A list including all the include_dir's specified for every target followed 85 A list including all the include_dir's specified for every target followed
85 by any include directories that were added as cflag compiler options. 86 by any include directories that were added as cflag compiler options.
86 """ 87 """
87 88
88 gyp_includes_set = set() 89 gyp_includes_set = set()
89 compiler_includes_list = [] 90 compiler_includes_list = []
90 91
92 # Find compiler's default include dirs.
93 if compiler_path:
94 command = shlex.split(compiler_path)
95 command.extend(['-E', '-xc++', '-v', '-'])
96 proc = subprocess.Popen(args=command, stdin=subprocess.PIPE,
97 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
98 output = proc.communicate()[1]
99 # Extract the list of include dirs from the output, which has this format:
100 # ...
101 # #include "..." search starts here:
102 # #include <...> search starts here:
103 # /usr/include/c++/4.6
104 # /usr/local/include
105 # End of search list.
106 # ...
107 in_include_list = False
108 for line in output.splitlines():
109 if line.startswith('#include'):
110 in_include_list = True
111 continue
112 if line.startswith('End of search list.'):
113 break
114 if in_include_list:
115 include_dir = line.strip()
116 if include_dir not in compiler_includes_list:
117 compiler_includes_list.append(include_dir)
118
91 flavor = gyp.common.GetFlavor(params) 119 flavor = gyp.common.GetFlavor(params)
92 if flavor == 'win': 120 if flavor == 'win':
93 generator_flags = params.get('generator_flags', {}) 121 generator_flags = params.get('generator_flags', {})
94 for target_name in target_list: 122 for target_name in target_list:
95 target = target_dicts[target_name] 123 target = target_dicts[target_name]
96 if config_name in target['configurations']: 124 if config_name in target['configurations']:
97 config = target['configurations'][config_name] 125 config = target['configurations'][config_name]
98 126
99 # Look for any include dirs that were explicitly added via cflags. This 127 # Look for any include dirs that were explicitly added via cflags. This
100 # may be done in gyp files to force certain includes to come at the end. 128 # may be done in gyp files to force certain includes to come at the end.
101 # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and 129 # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and
102 # remove this. 130 # remove this.
103 if flavor == 'win': 131 if flavor == 'win':
104 msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags) 132 msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags)
105 cflags = msvs_settings.GetCflags(config_name) 133 cflags = msvs_settings.GetCflags(config_name)
106 else: 134 else:
107 cflags = config['cflags'] 135 cflags = config['cflags']
108 for cflag in cflags: 136 for cflag in cflags:
109 include_dir = ''
110 if cflag.startswith('-I'): 137 if cflag.startswith('-I'):
111 include_dir = cflag[2:] 138 include_dir = cflag[2:]
112 if include_dir and not include_dir in compiler_includes_list: 139 if include_dir not in compiler_includes_list:
113 compiler_includes_list.append(include_dir) 140 compiler_includes_list.append(include_dir)
114 141
115 # Find standard gyp include dirs. 142 # Find standard gyp include dirs.
116 if config.has_key('include_dirs'): 143 if config.has_key('include_dirs'):
117 include_dirs = config['include_dirs'] 144 include_dirs = config['include_dirs']
118 for shared_intermediate_dir in shared_intermediate_dirs: 145 for shared_intermediate_dir in shared_intermediate_dirs:
119 for include_dir in include_dirs: 146 for include_dir in include_dirs:
120 include_dir = include_dir.replace('$SHARED_INTERMEDIATE_DIR', 147 include_dir = include_dir.replace('$SHARED_INTERMEDIATE_DIR',
121 shared_intermediate_dir) 148 shared_intermediate_dir)
122 if not os.path.isabs(include_dir): 149 if not os.path.isabs(include_dir):
123 base_dir = os.path.dirname(target_name) 150 base_dir = os.path.dirname(target_name)
124 151
125 include_dir = base_dir + '/' + include_dir 152 include_dir = base_dir + '/' + include_dir
126 include_dir = os.path.abspath(include_dir) 153 include_dir = os.path.abspath(include_dir)
127 154
128 if not include_dir in gyp_includes_set: 155 gyp_includes_set.add(include_dir)
129 gyp_includes_set.add(include_dir)
130
131 156
132 # Generate a list that has all the include dirs. 157 # Generate a list that has all the include dirs.
133 all_includes_list = list(gyp_includes_set) 158 all_includes_list = list(gyp_includes_set)
134 all_includes_list.sort() 159 all_includes_list.sort()
135 for compiler_include in compiler_includes_list: 160 for compiler_include in compiler_includes_list:
136 if not compiler_include in gyp_includes_set: 161 if not compiler_include in gyp_includes_set:
137 all_includes_list.append(compiler_include) 162 all_includes_list.append(compiler_include)
138 163
139 # All done. 164 # All done.
140 return all_includes_list 165 return all_includes_list
141 166
142 167
143 def GetCompilerPath(target_list, target_dicts, data): 168 def GetCompilerPath(target_list, data):
144 """Determine a command that can be used to invoke the compiler. 169 """Determine a command that can be used to invoke the compiler.
145 170
146 Returns: 171 Returns:
147 If this is a gyp project that has explicit make settings, try to determine 172 If this is a gyp project that has explicit make settings, try to determine
148 the compiler from that. Otherwise, see if a compiler was specified via the 173 the compiler from that. Otherwise, see if a compiler was specified via the
149 CC_target environment variable. 174 CC_target environment variable.
150 """ 175 """
151 176
152 # First, see if the compiler is configured in make's settings. 177 # First, see if the compiler is configured in make's settings.
153 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0]) 178 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
154 make_global_settings_dict = data[build_file].get('make_global_settings', {}) 179 make_global_settings_dict = data[build_file].get('make_global_settings', {})
155 for key, value in make_global_settings_dict: 180 for key, value in make_global_settings_dict:
156 if key in ['CC', 'CXX']: 181 if key in ['CC', 'CXX']:
157 return value 182 return value
158 183
159 # Check to see if the compiler was specified as an environment variable. 184 # Check to see if the compiler was specified as an environment variable.
160 for key in ['CC_target', 'CC', 'CXX']: 185 for key in ['CC_target', 'CC', 'CXX']:
161 compiler = os.environ.get(key) 186 compiler = os.environ.get(key)
162 if compiler: 187 if compiler:
163 return compiler 188 return compiler
164 189
165 return 'gcc' 190 return 'gcc'
166 191
167 192
168 def GetAllDefines(target_list, target_dicts, data, config_name, params): 193 def GetAllDefines(target_list, target_dicts, data, config_name, params,
194 compiler_path):
169 """Calculate the defines for a project. 195 """Calculate the defines for a project.
170 196
171 Returns: 197 Returns:
172 A dict that includes explict defines declared in gyp files along with all of 198 A dict that includes explict defines declared in gyp files along with all of
173 the default defines that the compiler uses. 199 the default defines that the compiler uses.
174 """ 200 """
175 201
176 # Get defines declared in the gyp files. 202 # Get defines declared in the gyp files.
177 all_defines = {} 203 all_defines = {}
178 flavor = gyp.common.GetFlavor(params) 204 flavor = gyp.common.GetFlavor(params)
(...skipping 16 matching lines...) Expand all
195 split_define = define.split('=', 1) 221 split_define = define.split('=', 1)
196 if len(split_define) == 1: 222 if len(split_define) == 1:
197 split_define.append('1') 223 split_define.append('1')
198 if split_define[0].strip() in all_defines: 224 if split_define[0].strip() in all_defines:
199 # Already defined 225 # Already defined
200 continue 226 continue
201 all_defines[split_define[0].strip()] = split_define[1].strip() 227 all_defines[split_define[0].strip()] = split_define[1].strip()
202 # Get default compiler defines (if possible). 228 # Get default compiler defines (if possible).
203 if flavor == 'win': 229 if flavor == 'win':
204 return all_defines # Default defines already processed in the loop above. 230 return all_defines # Default defines already processed in the loop above.
205 cc_target = GetCompilerPath(target_list, target_dicts, data) 231 if compiler_path:
206 if cc_target: 232 command = shlex.split(compiler_path)
207 command = shlex.split(cc_target)
208 command.extend(['-E', '-dM', '-']) 233 command.extend(['-E', '-dM', '-'])
209 cpp_proc = subprocess.Popen(args=command, cwd='.', 234 cpp_proc = subprocess.Popen(args=command, cwd='.',
210 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 235 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
211 cpp_output = cpp_proc.communicate()[0] 236 cpp_output = cpp_proc.communicate()[0]
212 cpp_lines = cpp_output.split('\n') 237 cpp_lines = cpp_output.split('\n')
213 for cpp_line in cpp_lines: 238 for cpp_line in cpp_lines:
214 if not cpp_line.strip(): 239 if not cpp_line.strip():
215 continue 240 continue
216 cpp_line_parts = cpp_line.split(' ', 2) 241 cpp_line_parts = cpp_line.split(' ', 2)
217 key = cpp_line_parts[1] 242 key = cpp_line_parts[1]
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 297
273 out_name = os.path.join(toplevel_build, 'eclipse-cdt-settings.xml') 298 out_name = os.path.join(toplevel_build, 'eclipse-cdt-settings.xml')
274 gyp.common.EnsureDirExists(out_name) 299 gyp.common.EnsureDirExists(out_name)
275 out = open(out_name, 'w') 300 out = open(out_name, 'w')
276 301
277 out.write('<?xml version="1.0" encoding="UTF-8"?>\n') 302 out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
278 out.write('<cdtprojectproperties>\n') 303 out.write('<cdtprojectproperties>\n')
279 304
280 eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File', 305 eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
281 'GNU C++', 'GNU C', 'Assembly'] 306 'GNU C++', 'GNU C', 'Assembly']
307 compiler_path = GetCompilerPath(target_list, data)
282 include_dirs = GetAllIncludeDirectories(target_list, target_dicts, 308 include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
283 shared_intermediate_dirs, config_name, 309 shared_intermediate_dirs, config_name,
284 params) 310 params, compiler_path)
285 WriteIncludePaths(out, eclipse_langs, include_dirs) 311 WriteIncludePaths(out, eclipse_langs, include_dirs)
286 defines = GetAllDefines(target_list, target_dicts, data, config_name, params) 312 defines = GetAllDefines(target_list, target_dicts, data, config_name, params,
313 compiler_path)
287 WriteMacros(out, eclipse_langs, defines) 314 WriteMacros(out, eclipse_langs, defines)
288 315
289 out.write('</cdtprojectproperties>\n') 316 out.write('</cdtprojectproperties>\n')
290 out.close() 317 out.close()
291 318
292 319
293 def GenerateOutput(target_list, target_dicts, data, params): 320 def GenerateOutput(target_list, target_dicts, data, params):
294 """Generate an XML settings file that can be imported into a CDT project.""" 321 """Generate an XML settings file that can be imported into a CDT project."""
295 322
296 if params['options'].generator_output: 323 if params['options'].generator_output:
297 raise NotImplementedError, "--generator_output not implemented for eclipse" 324 raise NotImplementedError, "--generator_output not implemented for eclipse"
298 325
299 user_config = params.get('generator_flags', {}).get('config', None) 326 user_config = params.get('generator_flags', {}).get('config', None)
300 if user_config: 327 if user_config:
301 GenerateOutputForConfig(target_list, target_dicts, data, params, 328 GenerateOutputForConfig(target_list, target_dicts, data, params,
302 user_config) 329 user_config)
303 else: 330 else:
304 config_names = target_dicts[target_list[0]]['configurations'].keys() 331 config_names = target_dicts[target_list[0]]['configurations'].keys()
305 for config_name in config_names: 332 for config_name in config_names:
306 GenerateOutputForConfig(target_list, target_dicts, data, params, 333 GenerateOutputForConfig(target_list, target_dicts, data, params,
307 config_name) 334 config_name)
308 335
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