76
90
gyp_includes_set = set()
77
91
compiler_includes_list = []
93
# Find compiler's default include dirs.
95
command = shlex.split(compiler_path)
96
command.extend(['-E', '-xc++', '-v', '-'])
97
proc = subprocess.Popen(args=command, stdin=subprocess.PIPE,
98
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
99
output = proc.communicate()[1]
100
# Extract the list of include dirs from the output, which has this format:
102
# #include "..." search starts here:
103
# #include <...> search starts here:
104
# /usr/include/c++/4.6
106
# End of search list.
108
in_include_list = False
109
for line in output.splitlines():
110
if line.startswith('#include'):
111
in_include_list = True
113
if line.startswith('End of search list.'):
116
include_dir = line.strip()
117
if include_dir not in compiler_includes_list:
118
compiler_includes_list.append(include_dir)
120
flavor = gyp.common.GetFlavor(params)
122
generator_flags = params.get('generator_flags', {})
79
123
for target_name in target_list:
80
124
target = target_dicts[target_name]
81
125
if config_name in target['configurations']:
157
202
# Get defines declared in the gyp files.
204
flavor = gyp.common.GetFlavor(params)
206
generator_flags = params.get('generator_flags', {})
159
207
for target_name in target_list:
160
208
target = target_dicts[target_name]
211
msvs_settings = gyp.msvs_emulation.MsvsSettings(target, generator_flags)
212
extra_defines = msvs_settings.GetComputedDefines(config_name)
162
215
if config_name in target['configurations']:
163
216
config = target['configurations'][config_name]
164
for define in config['defines']:
165
split_define = define.split('=', 1)
166
if len(split_define) == 1:
167
split_define.append('1')
168
if split_define[0].strip() in all_defines:
172
all_defines[split_define[0].strip()] = split_define[1].strip()
217
target_defines = config['defines']
220
for define in target_defines + extra_defines:
221
split_define = define.split('=', 1)
222
if len(split_define) == 1:
223
split_define.append('1')
224
if split_define[0].strip() in all_defines:
227
all_defines[split_define[0].strip()] = split_define[1].strip()
174
228
# Get default compiler defines (if possible).
175
cc_target = GetCompilerPath(target_list, target_dicts, data)
177
command = shlex.split(cc_target)
230
return all_defines # Default defines already processed in the loop above.
232
command = shlex.split(compiler_path)
178
233
command.extend(['-E', '-dM', '-'])
179
234
cpp_proc = subprocess.Popen(args=command, cwd='.',
180
235
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
240
295
shared_intermediate_dirs = [os.path.join(toplevel_build, 'obj', 'gen'),
241
296
os.path.join(toplevel_build, 'gen')]
243
if not os.path.exists(toplevel_build):
244
os.makedirs(toplevel_build)
245
out = open(os.path.join(toplevel_build, 'eclipse-cdt-settings.xml'), 'w')
247
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
248
out.write('<cdtprojectproperties>\n')
250
eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
251
'GNU C++', 'GNU C', 'Assembly']
252
include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
253
shared_intermediate_dirs, config_name)
254
WriteIncludePaths(out, eclipse_langs, include_dirs)
255
defines = GetAllDefines(target_list, target_dicts, data, config_name)
256
WriteMacros(out, eclipse_langs, defines)
258
out.write('</cdtprojectproperties>\n')
298
GenerateCdtSettingsFile(target_list,
303
os.path.join(toplevel_build,
304
'eclipse-cdt-settings.xml'),
306
shared_intermediate_dirs)
307
GenerateClasspathFile(target_list,
309
options.toplevel_dir,
311
os.path.join(toplevel_build,
312
'eclipse-classpath.xml'))
315
def GenerateCdtSettingsFile(target_list, target_dicts, data, params,
316
config_name, out_name, options,
317
shared_intermediate_dirs):
318
gyp.common.EnsureDirExists(out_name)
319
with open(out_name, 'w') as out:
320
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
321
out.write('<cdtprojectproperties>\n')
323
eclipse_langs = ['C++ Source File', 'C Source File', 'Assembly Source File',
324
'GNU C++', 'GNU C', 'Assembly']
325
compiler_path = GetCompilerPath(target_list, data, options)
326
include_dirs = GetAllIncludeDirectories(target_list, target_dicts,
327
shared_intermediate_dirs,
328
config_name, params, compiler_path)
329
WriteIncludePaths(out, eclipse_langs, include_dirs)
330
defines = GetAllDefines(target_list, target_dicts, data, config_name,
331
params, compiler_path)
332
WriteMacros(out, eclipse_langs, defines)
334
out.write('</cdtprojectproperties>\n')
337
def GenerateClasspathFile(target_list, target_dicts, toplevel_dir,
338
toplevel_build, out_name):
339
'''Generates a classpath file suitable for symbol navigation and code
340
completion of Java code (such as in Android projects) by finding all
341
.java and .jar files used as action inputs.'''
342
gyp.common.EnsureDirExists(out_name)
343
result = ET.Element('classpath')
345
def AddElements(kind, paths):
346
# First, we need to normalize the paths so they are all relative to the
350
if os.path.isabs(path):
351
rel_paths.add(os.path.relpath(path, toplevel_dir))
355
for path in sorted(rel_paths):
356
entry_element = ET.SubElement(result, 'classpathentry')
357
entry_element.set('kind', kind)
358
entry_element.set('path', path)
360
AddElements('lib', GetJavaJars(target_list, target_dicts, toplevel_dir))
361
AddElements('src', GetJavaSourceDirs(target_list, target_dicts, toplevel_dir))
362
# Include the standard JRE container and a dummy out folder
363
AddElements('con', ['org.eclipse.jdt.launching.JRE_CONTAINER'])
364
# Include a dummy out folder so that Eclipse doesn't use the default /bin
365
# folder in the root of the project.
366
AddElements('output', [os.path.join(toplevel_build, '.eclipse-java-build')])
368
ET.ElementTree(result).write(out_name)
371
def GetJavaJars(target_list, target_dicts, toplevel_dir):
372
'''Generates a sequence of all .jars used as inputs.'''
373
for target_name in target_list:
374
target = target_dicts[target_name]
375
for action in target.get('actions', []):
376
for input_ in action['inputs']:
377
if os.path.splitext(input_)[1] == '.jar' and not input_.startswith('$'):
378
if os.path.isabs(input_):
381
yield os.path.join(os.path.dirname(target_name), input_)
384
def GetJavaSourceDirs(target_list, target_dicts, toplevel_dir):
385
'''Generates a sequence of all likely java package root directories.'''
386
for target_name in target_list:
387
target = target_dicts[target_name]
388
for action in target.get('actions', []):
389
for input_ in action['inputs']:
390
if (os.path.splitext(input_)[1] == '.java' and
391
not input_.startswith('$')):
392
dir_ = os.path.dirname(os.path.join(os.path.dirname(target_name),
394
# If there is a parent 'src' or 'java' folder, navigate up to it -
395
# these are canonical package root names in Chromium. This will
396
# break if 'src' or 'java' exists in the package structure. This
397
# could be further improved by inspecting the java file for the
398
# package name if this proves to be too fragile in practice.
400
while os.path.basename(parent_search) not in ['src', 'java']:
401
parent_search, _ = os.path.split(parent_search)
402
if not parent_search or parent_search == toplevel_dir:
403
# Didn't find a known root, just return the original path
262
410
def GenerateOutput(target_list, target_dicts, data, params):
263
411
"""Generate an XML settings file that can be imported into a CDT project."""
265
413
if params['options'].generator_output:
266
raise NotImplementedError, "--generator_output not implemented for eclipse"
414
raise NotImplementedError("--generator_output not implemented for eclipse")
268
416
user_config = params.get('generator_flags', {}).get('config', None)