third_party:waf: update to upstream 2.0.4 release
[vlendec/samba-autobuild/.git] / third_party / waf / waflib / extras / eclipse.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file
4
5 #! /usr/bin/env python
6 # encoding: utf-8
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)
10
11 """
12 Usage:
13
14 def options(opt):
15         opt.load('eclipse')
16
17 $ waf configure eclipse
18 """
19
20 import sys, os
21 from waflib import Utils, Logs, Context, Build, TaskGen, Scripting, Errors, Node
22 from xml.dom.minidom import Document
23
24 STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ]
25
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'
30
31 class eclipse(Build.BuildContext):
32         cmd = 'eclipse'
33         fun = Scripting.default_cmd
34
35         def execute(self):
36                 """
37                 Entry point
38                 """
39                 self.restore()
40                 if not self.all_envs:
41                         self.load_envs()
42                 self.recurse([self.run_dir])
43
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'])
46
47         def create_cproject(self, appname, workspace_includes=[], pythonpath=[]):
48                 """
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
55                 """
56                 hasc = hasjava = haspython = False
57                 source_dirs = []
58                 cpppath = self.env['CPPPATH']
59                 javasrcpath = []
60                 includes = STANDARD_INCLUDES
61                 if sys.platform != 'win32':
62                         cc = self.env.CC or self.env.CXX
63                         if cc:
64                                 cmd = cc + ['-xc++', '-E', '-Wp,-v', '-']
65                                 try:
66                                         gccout = self.cmd_and_log(cmd, output=Context.STDERR, quiet=Context.BOTH, input='\n'.encode()).splitlines()
67                                 except Errors.WafError:
68                                         pass
69                                 else:
70                                         includes = []
71                                         for ipath in gccout:
72                                                 if ipath.startswith(' /'):
73                                                         includes.append(ipath[1:])
74                         cpppath += includes
75                 Logs.warn('Generating Eclipse CDT project files')
76
77                 for g in self.groups:
78                         for tg in g:
79                                 if not isinstance(tg, TaskGen.task_gen):
80                                         continue
81
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)
86                                         if py_installfrom:
87                                                 pypath += os.sep + py_installfrom
88                                         pythonpath.append(pypath)
89                                         haspython = True
90
91
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)
96                                         if java_srcdir:
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):
101                                                                 x = x.name
102                                                         if java_src == '.':
103                                                                 this_src = x
104                                                         else:
105                                                                 this_src = java_src + os.sep + x
106                                                         javasrcpath.append(this_src)
107                                         else:
108                                                 javasrcpath.append(java_src)
109                                         hasjava = True
110
111                                 tg.post()
112                                 if not getattr(tg, 'link_task', None):
113                                         continue
114
115                                 features = Utils.to_list(getattr(tg, 'features', ''))
116
117                                 is_cc = 'c' in features or 'cxx' in features
118
119                                 incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES'])
120                                 for p in incnodes:
121                                         path = p.path_from(self.srcnode)
122
123                                         if (path.startswith("/")):
124                                                 cpppath.append(path)
125                                         else:
126                                                 workspace_includes.append(path)
127
128                                         if is_cc and path not in source_dirs:
129                                                 source_dirs.append(path)
130
131                                         hasc = True
132
133                 project = self.impl_create_project(sys.executable, appname, hasc, hasjava, haspython)
134                 self.srcnode.make_node('.project').write(project.toprettyxml())
135
136                 if hasc:
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())
140
141                 if haspython:
142                         project = self.impl_create_pydevproject(sys.path, pythonpath)
143                         self.srcnode.make_node('.pydevproject').write(project.toprettyxml())
144
145                 if hasjava:
146                         project = self.impl_create_javaproject(javasrcpath)
147                         self.srcnode.make_node('.classpath').write(project.toprettyxml())
148
149         def impl_create_project(self, executable, appname, hasc, hasjava, haspython):
150                 doc = Document()
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
161                 dictionaries = {
162                                 cdt_mk + '.contents': cdt_mk + '.activeConfigSettings',
163                                 cdt_mk + '.enableAutoBuild': 'false',
164                                 cdt_mk + '.enableCleanBuild': 'true',
165                                 cdt_mk + '.enableFullBuild': 'true',
166                                 }
167                 for k, v in dictionaries.items():
168                         self.addDictionary(doc, arguments, k, v)
169
170                 natures = self.add(doc, projectDescription, 'natures')
171
172                 if hasc:
173                         nature_list = """
174                                 core.ccnature
175                                 managedbuilder.core.ScannerConfigNature
176                                 managedbuilder.core.managedBuildNature
177                                 core.cnature
178                         """.split()
179                         for n in nature_list:
180                                 self.add(doc, natures, 'nature', oe_cdt + '.' + n)
181
182                 if haspython:
183                         self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature')
184                 if hasjava:
185                         self.add(doc, natures, 'nature', 'org.eclipse.jdt.core.javanature')
186
187                 doc.appendChild(projectDescription)
188                 return doc
189
190         def impl_create_cproject(self, executable, waf, appname, workspace_includes, cpppath, source_dirs=[]):
191                 doc = Document()
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})
198
199                 storageModule = self.add(doc, cconf, 'storageModule',
200                                 {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider',
201                                  'id': cconf_id,
202                                  'moduleId': cdt_core + '.settings',
203                                  'name': 'Default'})
204
205                 self.add(doc, storageModule, 'externalSettings')
206
207                 extensions = self.add(doc, storageModule, 'extensions')
208                 extension_list = """
209                         VCErrorParser
210                         MakeErrorParser
211                         GCCErrorParser
212                         GASErrorParser
213                         GLDErrorParser
214                 """.split()
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'})
218
219                 storageModule = self.add(doc, cconf, 'storageModule',
220                                 {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'})
221                 config = self.add(doc, storageModule, 'configuration',
222                                         {'artifactName': appname,
223                                          'id': cconf_id,
224                                          'name': 'Default',
225                                          'parent': cdt_bld + '.prefbase.cfg'})
226                 folderInfo = self.add(doc, config, 'folderInfo',
227                                                         {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''})
228
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'})
234
235                 self.add(doc, toolChain, 'targetPlatform', {'binaryParser': 'org.eclipse.cdt.core.ELF', 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''})
236
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'})
250
251                 tool_index = 1;
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),
255                                          'name': tool_name,
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',
266                                                                 {'builtIn': 'false',
267                                                                 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)})
268                                 for i in cpppath:
269                                         self.add(doc, option, 'listOptionValue',
270                                                                 {'builtIn': 'false',
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' })
277                         tool_index += 1
278
279                 if source_dirs:
280                         sourceEntries = self.add(doc, config, 'sourceEntries')
281                         for i in source_dirs:
282                                  self.add(doc, sourceEntries, 'entry',
283                                                         {'excluding': i,
284                                                         'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
285                                                         'kind': 'sourcePath',
286                                                         'name': ''})
287                                  self.add(doc, sourceEntries, 'entry',
288                                                         {
289                                                         'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
290                                                         'kind': 'sourcePath',
291                                                         'name': i})
292
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)
303
304                 storageModule = self.add(doc, cproject, 'storageModule',
305                                                         {'moduleId': 'cdtBuildSystem',
306                                                          'version': '4.0.0'})
307
308                 self.add(doc, storageModule, 'project', {'id': '%s.null.1'%appname, 'name': appname})
309
310                 doc.appendChild(cproject)
311                 return doc
312
313         def impl_create_pydevproject(self, system_path, user_path):
314                 # create a pydevproject file
315                 doc = Document()
316                 doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"'))
317                 pydevproject = doc.createElement('pydev_project')
318                 prop = self.add(doc, pydevproject,
319                                            'pydev_property',
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')
324                 # add waf's paths
325                 wafadmin = [p for p in system_path if p.find('wafadmin') != -1]
326                 if wafadmin:
327                         prop = self.add(doc, pydevproject, 'pydev_pathproperty',
328                                         {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'})
329                         for i in wafadmin:
330                                 self.add(doc, prop, 'path', i)
331                 if user_path:
332                         prop = self.add(doc, pydevproject, 'pydev_pathproperty',
333                                         {'name':'org.python.pydev.PROJECT_SOURCE_PATH'})
334                         for i in user_path:
335                                 self.add(doc, prop, 'path', '/${PROJECT_DIR_NAME}/'+i)
336
337                 doc.appendChild(pydevproject)
338                 return doc
339
340         def impl_create_javaproject(self, javasrcpath):
341                 # create a .classpath file for java usage
342                 doc = Document()
343                 javaproject = doc.createElement('classpath')
344                 if javasrcpath:
345                         for i in javasrcpath:
346                                 self.add(doc, javaproject, 'classpathentry',
347                                         {'kind': 'src', 'path': i})
348
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)
352                 return doc
353
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)
358                 return dictionary
359
360         def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True):
361                 target = self.add(doc, buildTargets, 'target',
362                                                 {'name': name,
363                                                  'path': '',
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())
371
372         def add(self, doc, parent, tag, value = None):
373                 el = doc.createElement(tag)
374                 if (value):
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)
380                 return el
381
382         def setAttributes(self, node, attrs):
383                 for k, v in attrs.items():
384                         node.setAttribute(k, v)
385