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

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

Issue 9972015: Create a gyp generator for Eclipse CDT settings (Closed) Base URL: http://git.chromium.org/external/gyp.git@master
Patch Set: Created 8 years, 8 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
(Empty)
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
3 # found in the LICENSE file.
4
5 """GYP backend that generates Eclipse CDT settings files.
6
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
9 list of include paths and symbols (i.e. defines).
10 """
Nico 2012/04/16 17:21:52 Since you don't intend this to be generally useful
Jesse Greenwald 2012/04/27 17:12:29 Done.
11
12 import os.path
13 import subprocess
14 import gyp
15 import gyp.common
16 import shlex
17
18 generator_wants_static_library_dependencies_adjusted = False
19
20 generator_default_variables = {
21 }
22
23 for dirname in ['INTERMEDIATE_DIR', 'PRODUCT_DIR', 'LIB_DIR', 'SHARED_LIB_DIR']:
24 # Some gyp steps fail if these are empty(!).
25 generator_default_variables[dirname] = 'dir'
26
27 for unused in ['RULE_INPUT_PATH', 'RULE_INPUT_ROOT', 'RULE_INPUT_NAME',
28 'RULE_INPUT_DIRNAME', 'RULE_INPUT_EXT',
29 'EXECUTABLE_PREFIX', 'EXECUTABLE_SUFFIX',
30 'STATIC_LIB_PREFIX', 'STATIC_LIB_SUFFIX',
31 'SHARED_LIB_PREFIX', 'SHARED_LIB_SUFFIX']:
32 generator_default_variables[unused] = ''
33
34 # Include dirs will occasionaly use the SHARED_INTERMEDIATE_DIR variable as
35 # part of the path when dealing with generated headers.
36 # TODO: Make this work for all gyp generators (possible?). This currently
37 # matches what make gyp generator does.
38 generator_default_variables['SHARED_INTERMEDIATE_DIR'] = \
39 os.getcwd() + '/out/Release/obj/gen'
Nico 2012/04/16 17:21:52 If this supports just one configuration, maybe you
Jesse Greenwald 2012/04/27 17:12:29 I've updated it to match the ninja generator behav
40
41
42 def CalculateVariables(default_variables, params):
43 generator_flags = params.get('generator_flags', {})
44 for key, val in generator_flags.items():
45 default_variables.setdefault(key, val)
46 default_variables.setdefault('OS', gyp.common.GetFlavor(params))
47
48
49 def CalculateGeneratorInputInfo(params):
50 """Calculate the generator specific info that gets fed to input (called by
51 gyp)."""
52 generator_flags = params.get('generator_flags', {})
53 if generator_flags.get('adjust_static_libraries', False):
54 global generator_wants_static_library_dependencies_adjusted
55 generator_wants_static_library_dependencies_adjusted = True
56
57
58 def GetAllIncludeDirs(target_list, target_dicts):
59 """Calculate the set of include dirs to be used.
60
61 Returns:
62 A list including all the include_dir's specified for every target followed
63 by any incude dirs that were added as cflag compiler options.
Nico 2012/04/16 16:12:12 typo incude
Jesse Greenwald 2012/04/16 17:00:55 Done.
64 """
65
66 gyp_includes = []
67 compiler_includes = []
68
69 for target_name in target_list:
70 target = target_dicts[target_name]
71
72 for _, config in target['configurations'].iteritems():
73
74 # Look for any include dirs that were explicitly added via cflags. This
75 # may be done in gyp files to force certain includes to come at the end.
76 cflags = config['cflags']
Nico 2012/04/16 16:12:12 'cflags' is linux-specific. It shouldn't be used t
Jesse Greenwald 2012/04/16 17:00:55 That makes sense.. but unfortunately this is being
Nico 2012/04/16 17:21:52 build/common.gypi could be changed though, right?
Jesse Greenwald 2012/04/27 17:12:29 It could probably be fixed at some point, although
77 for cflag in cflags:
78 include_dir = ''
79 if cflag.startswith('-I'):
80 include_dir = cflag[2:]
81 if include_dir and not include_dir in compiler_includes:
82 compiler_includes.append(include_dir)
83
84 # Find standard gyp include dirs
Nico 2012/04/16 16:12:12 add trailing .
Jesse Greenwald 2012/04/16 17:00:55 Done.
85 if config.has_key('include_dirs'):
86 include_dirs = config['include_dirs']
87 for include_dir in include_dirs:
88 if not os.path.isabs(include_dir):
89 base_dir = os.path.dirname(target_name)
90
91 include_dir = base_dir + '/' + include_dir
92 include_dir = os.path.abspath(include_dir)
93
94 if not include_dir in gyp_includes:
95 gyp_includes.append(include_dir)
96
97 gyp_includes.sort()
98
99 # Generate a list that has all the include dirs
100 all_includes = list(gyp_includes)
101 for compiler_include in compiler_includes:
102 if not compiler_include in all_includes:
103 all_includes.append(compiler_include)
104
105 # All done
106 return all_includes
107
108
109 def GetCompilerPath(target_list, target_dicts, data):
110 """Determine a command that can be used to invoke the compiler.
111
112 Returns:
113 If this is a gyp project that has explicit make settings, try to determine
114 the compiler from that. Otherwise, see if a compiler was specified via the
115 CC_target environment variable.
116 """
117
118 # First, see if the compiler is configured in make's settings
119 build_file, _, _ = gyp.common.ParseQualifiedTarget(target_list[0])
120 make_global_settings_dict = data[build_file].get('make_global_settings', {})
121 for key, value in make_global_settings_dict:
122 if key in ['CC', 'CXX']:
123 return value
124
125 # Check to see if the compiler was specified as an environment variable
126 cc_target = os.environ.get('CC_target')
127 if cc_target:
128 return cc_target
129
130 # Default
131 return 'gcc'
132
133
134 def GetAllDefines(target_list, target_dicts, data):
135 """Calculate the defines for a project.
136
137 Returns:
138 A dict that includes explict defines declared in gyp files along with all of
139 the default defines that the compiler uses.
140 """
141
142 # Get defines declared in the gyp files
143 all_defines = {}
144 for target_name in target_list:
145 target = target_dicts[target_name]
146
147 for _, config in target['configurations'].iteritems():
148 for define in config['defines']:
149 split_define = define.split('=', 1)
150 if len(split_define) == 1:
151 split_define.append('1')
152 if split_define[0].strip() in all_defines:
153 # Already defined
154 continue
155
156 all_defines[split_define[0].strip()] = split_define[1].strip()
157
158 # Get default compiler defines (if possible)
159 cc_target = GetCompilerPath(target_list, target_dicts, data)
160 if cc_target:
161 command = shlex.split(cc_target)
162 command.extend(['-E', '-dM', '-'])
163 cpp_proc = subprocess.Popen(args=command, cwd='.',
164 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
165 cpp_output = cpp_proc.communicate()[0]
166 cpp_lines = cpp_output.split('\n')
167 for cpp_line in cpp_lines:
168 if not cpp_line.strip():
169 continue
170 cpp_line_parts = cpp_line.split(' ', 2)
171 key = cpp_line_parts[1]
172 if len(cpp_line_parts) >= 3:
173 val = cpp_line_parts[2]
174 else:
175 val = '1'
176 all_defines[key] = val
177
178 return all_defines
179
180
181 def WriteIncludePaths(out, eclipse_langs, include_dirs):
182 """Write the includes section of a CDT settings export file."""
183
184 out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \
185 'settingswizards.IncludePaths">\n')
186 out.write(' <language name="holder for library settings"></language>\n')
187 for lang in eclipse_langs:
188 out.write(' <language name="%s">\n' % lang)
189 for include_dir in include_dirs:
190 out.write(' <includepath workspace_path="false">%s</includepath>\n' %
191 include_dir)
192 out.write(' </language>\n')
193 out.write(' </section>\n')
194
195
196 def WriteMacros(out, eclipse_langs, defines):
197 """Write the macros section of a CDT settings export file."""
198
199 out.write(' <section name="org.eclipse.cdt.internal.ui.wizards.' \
200 'settingswizards.Macros">\n')
201 out.write(' <language name="holder for library settings"></language>\n')
202 for lang in eclipse_langs:
203 out.write(' <language name="%s">\n' % lang)
204 for key in sorted(defines.iterkeys()):
205 out.write(' <macro><name>%s</name><value>%s</value></macro>\n' %
206 (key, defines[key]))
207 out.write(' </language>\n')
208 out.write(' </section>\n')
209
210
211 def GenerateOutput(target_list, target_dicts, data, params):
212 """Generate an XML settings file that can be imported into a CDT project."""
213
Nico 2012/04/16 17:21:52 You might want to print a warning or error if any
Jesse Greenwald 2012/04/27 17:12:29 Done.
214 out = open('eclipse-cdt-settings.xml', 'w')
215
216 out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
217 out.write('<cdtprojectproperties>\n')
218
219 eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
220 'GNU C++', 'GNU C', 'Assembly']
221 WriteIncludePaths(out, eclipse_langs,
222 GetAllIncludeDirs(target_list, target_dicts))
223 WriteMacros(out, eclipse_langs, GetAllDefines(target_list, target_dicts,
Nico 2012/04/16 16:12:12 This looks like it sets all defines from all targe
Jesse Greenwald 2012/04/16 17:00:55 The settings.xml file that gets generated isn't pe
224 data))
225
226 out.write('</cdtprojectproperties>\n')
227 out.close()
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