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

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

Issue 23606009: Fix eclipse generator when running on Windows. (Closed) Base URL: http://gyp.googlecode.com/svn/trunk
Patch Set: Don't call GetFlavor twice. Created 7 years, 2 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
11 Because a full .cproject definition is not created by this generator, it's not 11 Because a full .cproject definition is not created by this generator, it's not
12 possible to properly define the include dirs and symbols for each file 12 possible to properly define the include dirs and symbols for each file
13 individually. Instead, one set of includes/symbols is generated for the entire 13 individually. Instead, one set of includes/symbols is generated for the entire
14 project. This works fairly well (and is a vast improvement in general), but may 14 project. This works fairly well (and is a vast improvement in general), but may
15 still result in a few indexer issues here and there. 15 still result in a few indexer issues here and there.
16 16
17 This generator has no automated tests, so expect it to be broken. 17 This generator has no automated tests, so expect it to be broken.
18 """ 18 """
19 19
20 from xml.sax.saxutils import escape 20 from xml.sax.saxutils import escape
21 import os.path 21 import os.path
22 import subprocess 22 import subprocess
23 import gyp 23 import gyp
24 import gyp.common 24 import gyp.common
25 import gyp.msvs_emulation
25 import shlex 26 import shlex
26 27
27 generator_wants_static_library_dependencies_adjusted = False 28 generator_wants_static_library_dependencies_adjusted = False
28 29
29 generator_default_variables = { 30 generator_default_variables = {
30 } 31 }
31 32
32 for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']: 33 for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']:
33 # Some gyp steps fail if these are empty(!). 34 # Some gyp steps fail if these are empty(!).
34 generator_default_variables[dirname] = 'dir' 35 generator_default_variables[dirname] = 'dir'
(...skipping 10 matching lines...) Expand all
45 # part of the path when dealing with generated headers. This value will be 46 # part of the path when dealing with generated headers. This value will be
46 # replaced dynamically for each configuration. 47 # replaced dynamically for each configuration.
47 generator_default_variables['SHARED_INTERMEDIATE_DIR'] = \ 48 generator_default_variables['SHARED_INTERMEDIATE_DIR'] = \
48 '$SHARED_INTERMEDIATE_DIR' 49 '$SHARED_INTERMEDIATE_DIR'
49 50
50 51
51 def CalculateVariables(default_variables, params): 52 def CalculateVariables(default_variables, params):
52 generator_flags = params.get('generator_flags', {}) 53 generator_flags = params.get('generator_flags', {})
53 for key, val in generator_flags.items(): 54 for key, val in generator_flags.items():
54 default_variables.setdefault(key, val) 55 default_variables.setdefault(key, val)
55 default_variables.setdefault('OS', gyp.common.GetFlavor(params)) 56 flavor = gyp.common.GetFlavor(params)
57 default_variables.setdefault('OS', flavor)
58 if flavor == 'win':
59 # Copy additional generator configuration data from VS, which is shared
60 # by the Eclipse generator.
61 import gyp.generator.msvs as msvs_generator
62 generator_additional_non_configuration_keys = getattr(msvs_generator,
63 'generator_additional_non_configuration_keys', [])
64 generator_additional_path_sections = getattr(msvs_generator,
65 'generator_additional_path_sections', [])
66
67 # Set a variable so conditions can be based on msvs_version.
68 msvs_version = gyp.msvs_emulation.GetVSVersion(generator_flags)
69 default_variables['MSVS_VERSION'] = msvs_version.ShortName()
70
71 # To determine processor word size on Windows, in addition to checking
72 # PROCESSOR_ARCHITECTURE (which reflects the word size of the current
73 # process), it is also necessary to check PROCESSOR_ARCHITEW6432 (which
74 # contains the actual word size of the system when running thru WOW64).
75 if ('64' in os.environ.get('PROCESSOR_ARCHITECTURE', '') or
76 '64' in os.environ.get('PROCESSOR_ARCHITEW6432', '')):
77 default_variables['MSVS_OS_BITS'] = 64
78 else:
79 default_variables['MSVS_OS_BITS'] = 32
56 80
57 81
58 def CalculateGeneratorInputInfo(params): 82 def CalculateGeneratorInputInfo(params):
59 """Calculate the generator specific info that gets fed to input (called by 83 """Calculate the generator specific info that gets fed to input (called by
60 gyp).""" 84 gyp)."""
61 generator_flags = params.get('generator_flags', {}) 85 generator_flags = params.get('generator_flags', {})
62 if generator_flags.get('adjust_static_libraries', False): 86 if generator_flags.get('adjust_static_libraries', False):
63 global generator_wants_static_library_dependencies_adjusted 87 global generator_wants_static_library_dependencies_adjusted
64 generator_wants_static_library_dependencies_adjusted = True 88 generator_wants_static_library_dependencies_adjusted = True
65 89
66 90
67 def GetAllIncludeDirectories(target_list, target_dicts, 91 def GetAllIncludeDirectories(target_list, target_dicts,
68 shared_intermediate_dirs, config_name): 92 shared_intermediate_dirs, config_name, params):
69 """Calculate the set of include directories to be used. 93 """Calculate the set of include directories to be used.
70 94
71 Returns: 95 Returns:
72 A list including all the include_dir's specified for every target followed 96 A list including all the include_dir's specified for every target followed
73 by any include directories that were added as cflag compiler options. 97 by any include directories that were added as cflag compiler options.
74 """ 98 """
75 99
76 gyp_includes_set = set() 100 gyp_includes_set = set()
77 compiler_includes_list = [] 101 compiler_includes_list = []
78 102
103 flavor = gyp.common.GetFlavor(params)
104 if flavor == 'win':
105 generator_flags = params.get('generator_flags', {})
79 for target_name in target_list: 106 for target_name in target_list:
80 target = target_dicts[target_name] 107 target = target_dicts[target_name]
81 if config_name in target['configurations']: 108 if config_name in target['configurations']:
82 config = target['configurations'][config_name] 109 config = target['configurations'][config_name]
83 110
84 # Look for any include dirs that were explicitly added via cflags. This 111 # Look for any include dirs that were explicitly added via cflags. This
85 # may be done in gyp files to force certain includes to come at the end. 112 # may be done in gyp files to force certain includes to come at the end.
86 # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and 113 # TODO(jgreenwald): Change the gyp files to not abuse cflags for this, and
87 # remove this. 114 # remove this.
88 cflags = config['cflags'] 115 if flavor == 'win':
116 msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags)
117 cflags = msvs_settings.GetCflags(config_name)
118 else:
119 cflags = config['cflags']
89 for cflag in cflags: 120 for cflag in cflags:
90 include_dir = '' 121 include_dir = ''
91 if cflag.startswith('-I'): 122 if cflag.startswith('-I'):
92 include_dir = cflag[2:] 123 include_dir = cflag[2:]
93 if include_dir and not include_dir in compiler_includes_list: 124 if include_dir and not include_dir in compiler_includes_list:
94 compiler_includes_list.append(include_dir) 125 compiler_includes_list.append(include_dir)
95 126
96 # Find standard gyp include dirs. 127 # Find standard gyp include dirs.
97 if config.has_key('include_dirs'): 128 if config.has_key('include_dirs'):
98 include_dirs = config['include_dirs'] 129 include_dirs = config['include_dirs']
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 170
140 # Check to see if the compiler was specified as an environment variable. 171 # Check to see if the compiler was specified as an environment variable.
141 for key in ['CC_target', 'CC', 'CXX']: 172 for key in ['CC_target', 'CC', 'CXX']:
142 compiler = os.environ.get(key) 173 compiler = os.environ.get(key)
143 if compiler: 174 if compiler:
144 return compiler 175 return compiler
145 176
146 return 'gcc' 177 return 'gcc'
147 178
148 179
149 def GetAllDefines(target_list, target_dicts, data, config_name): 180 def GetAllDefines(target_list, target_dicts, data, config_name, params):
150 """Calculate the defines for a project. 181 """Calculate the defines for a project.
151 182
152 Returns: 183 Returns:
153 A dict that includes explict defines declared in gyp files along with all of 184 A dict that includes explict defines declared in gyp files along with all of
154 the default defines that the compiler uses. 185 the default defines that the compiler uses.
155 """ 186 """
156 187
157 # Get defines declared in the gyp files. 188 # Get defines declared in the gyp files.
158 all_defines = {} 189 all_defines = {}
190 flavor = gyp.common.GetFlavor(params)
191 if flavor == 'win':
192 generator_flags = params.get('generator_flags', {})
159 for target_name in target_list: 193 for target_name in target_list:
160 target = target_dicts[target_name] 194 target = target_dicts[target_name]
161 195
196 if flavor == 'win':
197 msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags)
198 extra_defines = msvs_settings.GetComputedDefines(config_name)
199 else:
200 extra_defines = []
162 if config_name in target['configurations']: 201 if config_name in target['configurations']:
163 config = target['configurations'][config_name] 202 config = target['configurations'][config_name]
164 for define in config['defines']: 203 target_defines = config['defines']
165 split_define = define.split('=', 1) 204 else:
166 if len(split_define) == 1: 205 target_defines = []
167 split_define.append('1') 206 for define in target_defines + extra_defines:
168 if split_define[0].strip() in all_defines: 207 split_define = define.split('=', 1)
169 # Already defined 208 if len(split_define) == 1:
170 continue 209 split_define.append('1')
171 210 if split_define[0].strip() in all_defines:
172 all_defines[split_define[0].strip()] = split_define[1].strip() 211 # Already defined
173 212 continue
213 all_defines[split_define[0].strip()] = split_define[1].strip()
174 # Get default compiler defines (if possible). 214 # Get default compiler defines (if possible).
215 if flavor == 'win':
216 return all_defines # Default defines already processed in the loop above.
175 cc_target = GetCompilerPath(target_list, target_dicts, data) 217 cc_target = GetCompilerPath(target_list, target_dicts, data)
176 if cc_target: 218 if cc_target:
177 command = shlex.split(cc_target) 219 command = shlex.split(cc_target)
178 command.extend(['-E', '-dM', '-']) 220 command.extend(['-E', '-dM', '-'])
179 cpp_proc = subprocess.Popen(args=command, cwd='.', 221 cpp_proc = subprocess.Popen(args=command, cwd='.',
180 stdin=subprocess.PIPE, stdout=subprocess.PIPE) 222 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
181 cpp_output = cpp_proc.communicate()[0] 223 cpp_output = cpp_proc.communicate()[0]
182 cpp_lines = cpp_output.split('\n') 224 cpp_lines = cpp_output.split('\n')
183 for cpp_line in cpp_lines: 225 for cpp_line in cpp_lines:
184 if not cpp_line.strip(): 226 if not cpp_line.strip():
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 if not os.path.exists(toplevel_build): 285 if not os.path.exists(toplevel_build):
244 os.makedirs(toplevel_build) 286 os.makedirs(toplevel_build)
245 out = open(os.path.join(toplevel_build, 'eclipse-cdt-settings.xml'), 'w') 287 out = open(os.path.join(toplevel_build, 'eclipse-cdt-settings.xml'), 'w')
246 288
247 out.write('<?xml version="1.0" encoding="UTF-8"?>\n') 289 out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
248 out.write('<cdtprojectproperties>\n') 290 out.write('<cdtprojectproperties>\n')
249 291
250 eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File', 292 eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
251 'GNU C++', 'GNU C', 'Assembly'] 293 'GNU C++', 'GNU C', 'Assembly']
252 include_dirs = GetAllIncludeDirectories(target_list, target_dicts, 294 include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
253 shared_intermediate_dirs, config_name) 295 shared_intermediate_dirs, config_name,
296 params)
254 WriteIncludePaths(out, eclipse_langs, include_dirs) 297 WriteIncludePaths(out, eclipse_langs, include_dirs)
255 defines = GetAllDefines(target_list, target_dicts, data, config_name) 298 defines = GetAllDefines(target_list, target_dicts, data, config_name, params)
256 WriteMacros(out, eclipse_langs, defines) 299 WriteMacros(out, eclipse_langs, defines)
257 300
258 out.write('</cdtprojectproperties>\n') 301 out.write('</cdtprojectproperties>\n')
259 out.close() 302 out.close()
260 303
261 304
262 def GenerateOutput(target_list, target_dicts, data, params): 305 def GenerateOutput(target_list, target_dicts, data, params):
263 """Generate an XML settings file that can be imported into a CDT project.""" 306 """Generate an XML settings file that can be imported into a CDT project."""
264 307
265 if params['options'].generator_output: 308 if params['options'].generator_output:
266 raise NotImplementedError, "--generator_output not implemented for eclipse" 309 raise NotImplementedError, "--generator_output not implemented for eclipse"
267 310
268 user_config = params.get('generator_flags', {}).get('config', None) 311 user_config = params.get('generator_flags', {}).get('config', None)
269 if user_config: 312 if user_config:
270 GenerateOutputForConfig(target_list, target_dicts, data, params, 313 GenerateOutputForConfig(target_list, target_dicts, data, params,
271 user_config) 314 user_config)
272 else: 315 else:
273 config_names = target_dicts[target_list[0]]['configurations'].keys() 316 config_names = target_dicts[target_list[0]]['configurations'].keys()
274 for config_name in config_names: 317 for config_name in config_names:
275 GenerateOutputForConfig(target_list, target_dicts, data, params, 318 GenerateOutputForConfig(target_list, target_dicts, data, params,
276 config_name) 319 config_name)
277 320
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