3 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
7 # Eclipse CDT 5.0 generator for Waf
8 # Richard Quirk 2009-1011 (New BSD License)
9 # Thomas Nagy 2011 (ported to Waf 1.6)
17 $ waf configure eclipse
21 from waflib import Utils, Logs, Context, Build, TaskGen, Scripting, Errors, Node
22 from xml.dom.minidom import Document
24 STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ]
26 oe_cdt = 'org.eclipse.cdt'
27 cdt_mk = oe_cdt + '.make.core'
28 cdt_core = oe_cdt + '.core'
29 cdt_bld = oe_cdt + '.build.core'
31 class eclipse(Build.BuildContext):
33 fun = Scripting.default_cmd
42 self.recurse([self.run_dir])
44 appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath()))
45 self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH'])
47 def create_cproject(self, appname, workspace_includes=[], pythonpath=[]):
49 Create the Eclipse CDT .project and .cproject files
50 @param appname The name that will appear in the Project Explorer
51 @param build The BuildContext object to extract includes from
52 @param workspace_includes Optional project includes to prevent
53 "Unresolved Inclusion" errors in the Eclipse editor
54 @param pythonpath Optional project specific python paths
56 hasc = hasjava = haspython = False
58 cpppath = self.env['CPPPATH']
60 includes = STANDARD_INCLUDES
61 if sys.platform != 'win32':
62 cc = self.env.CC or self.env.CXX
64 cmd = cc + ['-xc++', '-E', '-Wp,-v', '-']
66 gccout = self.cmd_and_log(cmd, output=Context.STDERR, quiet=Context.BOTH, input='\n'.encode()).splitlines()
67 except Errors.WafError:
72 if ipath.startswith(' /'):
73 includes.append(ipath[1:])
75 Logs.warn('Generating Eclipse CDT project files')
79 if not isinstance(tg, TaskGen.task_gen):
82 # Add local Python modules paths to configuration so object resolving will work in IDE
83 if 'py' in tg.features:
84 pypath = tg.path.relpath()
85 py_installfrom = getattr(tg, 'install_from', None)
87 pypath += os.sep + py_installfrom
88 pythonpath.append(pypath)
92 # Add Java source directories so object resolving works in IDE
93 if 'java' in tg.features:
94 java_src = tg.path.relpath()
95 java_srcdir = getattr(tg, 'srcdir', None)
97 if isinstance(java_srcdir, Node.Node):
98 java_srcdir = [java_srcdir]
99 for x in Utils.to_list(java_srcdir):
100 if isinstance(x, Node.Node):
105 this_src = java_src + os.sep + x
106 javasrcpath.append(this_src)
108 javasrcpath.append(java_src)
112 if not getattr(tg, 'link_task', None):
115 features = Utils.to_list(getattr(tg, 'features', ''))
117 is_cc = 'c' in features or 'cxx' in features
119 incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES'])
121 path = p.path_from(self.srcnode)
123 if (path.startswith("/")):
126 workspace_includes.append(path)
128 if is_cc and path not in source_dirs:
129 source_dirs.append(path)
133 project = self.impl_create_project(sys.executable, appname, hasc, hasjava, haspython)
134 self.srcnode.make_node('.project').write(project.toprettyxml())
137 waf = os.path.abspath(sys.argv[0])
138 project = self.impl_create_cproject(sys.executable, waf, appname, workspace_includes, cpppath, source_dirs)
139 self.srcnode.make_node('.cproject').write(project.toprettyxml())
142 project = self.impl_create_pydevproject(sys.path, pythonpath)
143 self.srcnode.make_node('.pydevproject').write(project.toprettyxml())
146 project = self.impl_create_javaproject(javasrcpath)
147 self.srcnode.make_node('.classpath').write(project.toprettyxml())
149 def impl_create_project(self, executable, appname, hasc, hasjava, haspython):
151 projectDescription = doc.createElement('projectDescription')
152 self.add(doc, projectDescription, 'name', appname)
153 self.add(doc, projectDescription, 'comment')
154 self.add(doc, projectDescription, 'projects')
155 buildSpec = self.add(doc, projectDescription, 'buildSpec')
156 buildCommand = self.add(doc, buildSpec, 'buildCommand')
157 self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder')
158 self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,')
159 arguments = self.add(doc, buildCommand, 'arguments')
160 # the default make-style targets are overwritten by the .cproject values
162 cdt_mk + '.contents': cdt_mk + '.activeConfigSettings',
163 cdt_mk + '.enableAutoBuild': 'false',
164 cdt_mk + '.enableCleanBuild': 'true',
165 cdt_mk + '.enableFullBuild': 'true',
167 for k, v in dictionaries.items():
168 self.addDictionary(doc, arguments, k, v)
170 natures = self.add(doc, projectDescription, 'natures')
175 managedbuilder.core.ScannerConfigNature
176 managedbuilder.core.managedBuildNature
179 for n in nature_list:
180 self.add(doc, natures, 'nature', oe_cdt + '.' + n)
183 self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature')
185 self.add(doc, natures, 'nature', 'org.eclipse.jdt.core.javanature')
187 doc.appendChild(projectDescription)
190 def impl_create_cproject(self, executable, waf, appname, workspace_includes, cpppath, source_dirs=[]):
192 doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0'))
193 cconf_id = cdt_core + '.default.config.1'
194 cproject = doc.createElement('cproject')
195 storageModule = self.add(doc, cproject, 'storageModule',
196 {'moduleId': cdt_core + '.settings'})
197 cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id})
199 storageModule = self.add(doc, cconf, 'storageModule',
200 {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider',
202 'moduleId': cdt_core + '.settings',
205 self.add(doc, storageModule, 'externalSettings')
207 extensions = self.add(doc, storageModule, 'extensions')
215 self.add(doc, extensions, 'extension', {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'})
216 for e in extension_list:
217 self.add(doc, extensions, 'extension', {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'})
219 storageModule = self.add(doc, cconf, 'storageModule',
220 {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'})
221 config = self.add(doc, storageModule, 'configuration',
222 {'artifactName': appname,
225 'parent': cdt_bld + '.prefbase.cfg'})
226 folderInfo = self.add(doc, config, 'folderInfo',
227 {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''})
229 toolChain = self.add(doc, folderInfo, 'toolChain',
230 {'id': cdt_bld + '.prefbase.toolchain.1',
231 'name': 'No ToolChain',
232 'resourceTypeBasedDiscovery': 'false',
233 'superClass': cdt_bld + '.prefbase.toolchain'})
235 self.add(doc, toolChain, 'targetPlatform', {'binaryParser': 'org.eclipse.cdt.core.ELF', 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''})
237 waf_build = '"%s" %s'%(waf, eclipse.fun)
238 waf_clean = '"%s" clean'%(waf)
239 self.add(doc, toolChain, 'builder',
240 {'autoBuildTarget': waf_build,
241 'command': executable,
242 'enableAutoBuild': 'false',
243 'cleanBuildTarget': waf_clean,
244 'enableIncrementalBuild': 'true',
245 'id': cdt_bld + '.settings.default.builder.1',
246 'incrementalBuildTarget': waf_build,
247 'managedBuildOn': 'false',
248 'name': 'Gnu Make Builder',
249 'superClass': cdt_bld + '.settings.default.builder'})
252 for tool_name in ("Assembly", "GNU C++", "GNU C"):
253 tool = self.add(doc, toolChain, 'tool',
254 {'id': cdt_bld + '.settings.holder.' + str(tool_index),
256 'superClass': cdt_bld + '.settings.holder'})
257 if cpppath or workspace_includes:
258 incpaths = cdt_bld + '.settings.holder.incpaths'
259 option = self.add(doc, tool, 'option',
260 {'id': incpaths + '.' + str(tool_index),
261 'name': 'Include Paths',
262 'superClass': incpaths,
263 'valueType': 'includePath'})
264 for i in workspace_includes:
265 self.add(doc, option, 'listOptionValue',
267 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)})
269 self.add(doc, option, 'listOptionValue',
271 'value': '"%s"'%(i)})
272 if tool_name == "GNU C++" or tool_name == "GNU C":
273 self.add(doc,tool,'inputType',{ 'id':'org.eclipse.cdt.build.core.settings.holder.inType.' + str(tool_index), \
274 'languageId':'org.eclipse.cdt.core.gcc' if tool_name == "GNU C" else 'org.eclipse.cdt.core.g++','languageName':tool_name, \
275 'sourceContentType':'org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader', \
276 'superClass':'org.eclipse.cdt.build.core.settings.holder.inType' })
280 sourceEntries = self.add(doc, config, 'sourceEntries')
281 for i in source_dirs:
282 self.add(doc, sourceEntries, 'entry',
284 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
285 'kind': 'sourcePath',
287 self.add(doc, sourceEntries, 'entry',
289 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
290 'kind': 'sourcePath',
293 storageModule = self.add(doc, cconf, 'storageModule',
294 {'moduleId': cdt_mk + '.buildtargets'})
295 buildTargets = self.add(doc, storageModule, 'buildTargets')
296 def addTargetWrap(name, runAll):
297 return self.addTarget(doc, buildTargets, executable, name,
298 '"%s" %s'%(waf, name), runAll)
299 addTargetWrap('configure', True)
300 addTargetWrap('dist', False)
301 addTargetWrap('install', False)
302 addTargetWrap('check', False)
304 storageModule = self.add(doc, cproject, 'storageModule',
305 {'moduleId': 'cdtBuildSystem',
308 self.add(doc, storageModule, 'project', {'id': '%s.null.1'%appname, 'name': appname})
310 doc.appendChild(cproject)
313 def impl_create_pydevproject(self, system_path, user_path):
314 # create a pydevproject file
316 doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"'))
317 pydevproject = doc.createElement('pydev_project')
318 prop = self.add(doc, pydevproject,
320 'python %d.%d'%(sys.version_info[0], sys.version_info[1]))
321 prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION')
322 prop = self.add(doc, pydevproject, 'pydev_property', 'Default')
323 prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER')
325 wafadmin = [p for p in system_path if p.find('wafadmin') != -1]
327 prop = self.add(doc, pydevproject, 'pydev_pathproperty',
328 {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'})
330 self.add(doc, prop, 'path', i)
332 prop = self.add(doc, pydevproject, 'pydev_pathproperty',
333 {'name':'org.python.pydev.PROJECT_SOURCE_PATH'})
335 self.add(doc, prop, 'path', '/${PROJECT_DIR_NAME}/'+i)
337 doc.appendChild(pydevproject)
340 def impl_create_javaproject(self, javasrcpath):
341 # create a .classpath file for java usage
343 javaproject = doc.createElement('classpath')
345 for i in javasrcpath:
346 self.add(doc, javaproject, 'classpathentry',
347 {'kind': 'src', 'path': i})
349 self.add(doc, javaproject, 'classpathentry', {'kind': 'con', 'path': 'org.eclipse.jdt.launching.JRE_CONTAINER'})
350 self.add(doc, javaproject, 'classpathentry', {'kind': 'output', 'path': self.bldnode.name })
351 doc.appendChild(javaproject)
354 def addDictionary(self, doc, parent, k, v):
355 dictionary = self.add(doc, parent, 'dictionary')
356 self.add(doc, dictionary, 'key', k)
357 self.add(doc, dictionary, 'value', v)
360 def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True):
361 target = self.add(doc, buildTargets, 'target',
364 'targetID': oe_cdt + '.build.MakeTargetBuilder'})
365 self.add(doc, target, 'buildCommand', executable)
366 self.add(doc, target, 'buildArguments', None)
367 self.add(doc, target, 'buildTarget', buildTarget)
368 self.add(doc, target, 'stopOnError', 'true')
369 self.add(doc, target, 'useDefaultCommand', 'false')
370 self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower())
372 def add(self, doc, parent, tag, value = None):
373 el = doc.createElement(tag)
375 if type(value) == type(str()):
376 el.appendChild(doc.createTextNode(value))
377 elif type(value) == type(dict()):
378 self.setAttributes(el, value)
379 parent.appendChild(el)
382 def setAttributes(self, node, attrs):
383 for k, v in attrs.items():
384 node.setAttribute(k, v)