jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
11KB

  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. # Eclipse CDT 5.0 generator for Waf
  4. # Richard Quirk 2009-1011 (New BSD License)
  5. # Thomas Nagy 2011 (ported to Waf 1.6)
  6. """
  7. Usage:
  8. def options(opt):
  9. opt.load('eclipse')
  10. $ waf configure eclipse
  11. """
  12. import sys, os
  13. from waflib import Utils, Logs, Context, Options, Build, TaskGen, Scripting
  14. from xml.dom.minidom import Document
  15. STANDARD_INCLUDES = [ '/usr/local/include', '/usr/include' ]
  16. oe_cdt = 'org.eclipse.cdt'
  17. cdt_mk = oe_cdt + '.make.core'
  18. cdt_core = oe_cdt + '.core'
  19. cdt_bld = oe_cdt + '.build.core'
  20. class eclipse(Build.BuildContext):
  21. cmd = 'eclipse'
  22. fun = Scripting.default_cmd
  23. def execute(self):
  24. """
  25. Entry point
  26. """
  27. self.restore()
  28. if not self.all_envs:
  29. self.load_envs()
  30. self.recurse([self.run_dir])
  31. appname = getattr(Context.g_module, Context.APPNAME, os.path.basename(self.srcnode.abspath()))
  32. self.create_cproject(appname, pythonpath=self.env['ECLIPSE_PYTHON_PATH'])
  33. def create_cproject(self, appname, workspace_includes=[], pythonpath=[]):
  34. """
  35. Create the Eclipse CDT .project and .cproject files
  36. @param appname The name that will appear in the Project Explorer
  37. @param build The BuildContext object to extract includes from
  38. @param workspace_includes Optional project includes to prevent
  39. "Unresolved Inclusion" errors in the Eclipse editor
  40. @param pythonpath Optional project specific python paths
  41. """
  42. source_dirs = []
  43. cpppath = self.env['CPPPATH']
  44. if sys.platform != 'win32':
  45. cpppath += STANDARD_INCLUDES
  46. Logs.warn('Generating Eclipse CDT project files')
  47. for g in self.groups:
  48. for tg in g:
  49. if not isinstance(tg, TaskGen.task_gen):
  50. continue
  51. tg.post()
  52. if not getattr(tg, 'link_task', None):
  53. continue
  54. l = Utils.to_list(getattr(tg, "includes", ''))
  55. sources = Utils.to_list(getattr(tg, 'source', ''))
  56. features = Utils.to_list(getattr(tg, 'features', ''))
  57. is_cc = 'c' in features or 'cxx' in features
  58. bldpath = tg.path.bldpath()
  59. base = os.path.normpath(os.path.join(self.bldnode.name, tg.path.srcpath()))
  60. if is_cc:
  61. sources_dirs = set([src.parent for src in tg.to_nodes(sources)])
  62. incnodes = tg.to_incnodes(tg.to_list(getattr(tg, 'includes', [])) + tg.env['INCLUDES'])
  63. for p in incnodes:
  64. path = p.path_from(self.srcnode)
  65. workspace_includes.append(path)
  66. if is_cc and path not in source_dirs:
  67. source_dirs.append(path)
  68. project = self.impl_create_project(sys.executable, appname)
  69. self.srcnode.make_node('.project').write(project.toprettyxml())
  70. waf = os.path.abspath(sys.argv[0])
  71. project = self.impl_create_cproject(sys.executable, waf, appname, workspace_includes, cpppath, source_dirs)
  72. self.srcnode.make_node('.cproject').write(project.toprettyxml())
  73. project = self.impl_create_pydevproject(appname, sys.path, pythonpath)
  74. self.srcnode.make_node('.pydevproject').write(project.toprettyxml())
  75. def impl_create_project(self, executable, appname):
  76. doc = Document()
  77. projectDescription = doc.createElement('projectDescription')
  78. self.add(doc, projectDescription, 'name', appname)
  79. self.add(doc, projectDescription, 'comment')
  80. self.add(doc, projectDescription, 'projects')
  81. buildSpec = self.add(doc, projectDescription, 'buildSpec')
  82. buildCommand = self.add(doc, buildSpec, 'buildCommand')
  83. self.add(doc, buildCommand, 'name', oe_cdt + '.managedbuilder.core.genmakebuilder')
  84. self.add(doc, buildCommand, 'triggers', 'clean,full,incremental,')
  85. arguments = self.add(doc, buildCommand, 'arguments')
  86. # the default make-style targets are overwritten by the .cproject values
  87. dictionaries = {
  88. cdt_mk + '.contents': cdt_mk + '.activeConfigSettings',
  89. cdt_mk + '.enableAutoBuild': 'false',
  90. cdt_mk + '.enableCleanBuild': 'true',
  91. cdt_mk + '.enableFullBuild': 'true',
  92. }
  93. for k, v in dictionaries.items():
  94. self.addDictionary(doc, arguments, k, v)
  95. natures = self.add(doc, projectDescription, 'natures')
  96. nature_list = """
  97. core.ccnature
  98. managedbuilder.core.ScannerConfigNature
  99. managedbuilder.core.managedBuildNature
  100. core.cnature
  101. """.split()
  102. for n in nature_list:
  103. self.add(doc, natures, 'nature', oe_cdt + '.' + n)
  104. self.add(doc, natures, 'nature', 'org.python.pydev.pythonNature')
  105. doc.appendChild(projectDescription)
  106. return doc
  107. def impl_create_cproject(self, executable, waf, appname, workspace_includes, cpppath, source_dirs=[]):
  108. doc = Document()
  109. doc.appendChild(doc.createProcessingInstruction('fileVersion', '4.0.0'))
  110. cconf_id = cdt_core + '.default.config.1'
  111. cproject = doc.createElement('cproject')
  112. storageModule = self.add(doc, cproject, 'storageModule',
  113. {'moduleId': cdt_core + '.settings'})
  114. cconf = self.add(doc, storageModule, 'cconfiguration', {'id':cconf_id})
  115. storageModule = self.add(doc, cconf, 'storageModule',
  116. {'buildSystemId': oe_cdt + '.managedbuilder.core.configurationDataProvider',
  117. 'id': cconf_id,
  118. 'moduleId': cdt_core + '.settings',
  119. 'name': 'Default'})
  120. self.add(doc, storageModule, 'externalSettings')
  121. extensions = self.add(doc, storageModule, 'extensions')
  122. extension_list = """
  123. VCErrorParser
  124. MakeErrorParser
  125. GCCErrorParser
  126. GASErrorParser
  127. GLDErrorParser
  128. """.split()
  129. ext = self.add(doc, extensions, 'extension',
  130. {'id': cdt_core + '.ELF', 'point':cdt_core + '.BinaryParser'})
  131. for e in extension_list:
  132. ext = self.add(doc, extensions, 'extension',
  133. {'id': cdt_core + '.' + e, 'point':cdt_core + '.ErrorParser'})
  134. storageModule = self.add(doc, cconf, 'storageModule',
  135. {'moduleId': 'cdtBuildSystem', 'version': '4.0.0'})
  136. config = self.add(doc, storageModule, 'configuration',
  137. {'artifactName': appname,
  138. 'id': cconf_id,
  139. 'name': 'Default',
  140. 'parent': cdt_bld + '.prefbase.cfg'})
  141. folderInfo = self.add(doc, config, 'folderInfo',
  142. {'id': cconf_id+'.', 'name': '/', 'resourcePath': ''})
  143. toolChain = self.add(doc, folderInfo, 'toolChain',
  144. {'id': cdt_bld + '.prefbase.toolchain.1',
  145. 'name': 'No ToolChain',
  146. 'resourceTypeBasedDiscovery': 'false',
  147. 'superClass': cdt_bld + '.prefbase.toolchain'})
  148. targetPlatform = self.add(doc, toolChain, 'targetPlatform',
  149. { 'binaryParser': 'org.eclipse.cdt.core.ELF',
  150. 'id': cdt_bld + '.prefbase.toolchain.1', 'name': ''})
  151. waf_build = '"%s" %s'%(waf, eclipse.fun)
  152. waf_clean = '"%s" clean'%(waf)
  153. builder = self.add(doc, toolChain, 'builder',
  154. {'autoBuildTarget': waf_build,
  155. 'command': executable,
  156. 'enableAutoBuild': 'false',
  157. 'cleanBuildTarget': waf_clean,
  158. 'enableIncrementalBuild': 'true',
  159. 'id': cdt_bld + '.settings.default.builder.1',
  160. 'incrementalBuildTarget': waf_build,
  161. 'managedBuildOn': 'false',
  162. 'name': 'Gnu Make Builder',
  163. 'superClass': cdt_bld + '.settings.default.builder'})
  164. for tool_name in ("Assembly", "GNU C++", "GNU C"):
  165. tool = self.add(doc, toolChain, 'tool',
  166. {'id': cdt_bld + '.settings.holder.1',
  167. 'name': tool_name,
  168. 'superClass': cdt_bld + '.settings.holder'})
  169. if cpppath or workspace_includes:
  170. incpaths = cdt_bld + '.settings.holder.incpaths'
  171. option = self.add(doc, tool, 'option',
  172. {'id': incpaths+'.1',
  173. 'name': 'Include Paths',
  174. 'superClass': incpaths,
  175. 'valueType': 'includePath'})
  176. for i in workspace_includes:
  177. self.add(doc, option, 'listOptionValue',
  178. {'builtIn': 'false',
  179. 'value': '"${workspace_loc:/%s/%s}"'%(appname, i)})
  180. for i in cpppath:
  181. self.add(doc, option, 'listOptionValue',
  182. {'builtIn': 'false',
  183. 'value': '"%s"'%(i)})
  184. if tool_name == "GNU C++" or tool_name == "GNU C":
  185. self.add(doc,tool,'inputType',{ 'id':'org.eclipse.cdt.build.core.settings.holder.inType.1', \
  186. 'languageId':'org.eclipse.cdt.core.gcc','languageName':tool_name, \
  187. 'sourceContentType':'org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader', \
  188. 'superClass':'org.eclipse.cdt.build.core.settings.holder.inType' })
  189. if source_dirs:
  190. sourceEntries = self.add(doc, config, 'sourceEntries')
  191. for i in source_dirs:
  192. self.add(doc, sourceEntries, 'entry',
  193. {'excluding': i,
  194. 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
  195. 'kind': 'sourcePath',
  196. 'name': ''})
  197. self.add(doc, sourceEntries, 'entry',
  198. {
  199. 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED',
  200. 'kind': 'sourcePath',
  201. 'name': i})
  202. storageModule = self.add(doc, cconf, 'storageModule',
  203. {'moduleId': cdt_mk + '.buildtargets'})
  204. buildTargets = self.add(doc, storageModule, 'buildTargets')
  205. def addTargetWrap(name, runAll):
  206. return self.addTarget(doc, buildTargets, executable, name,
  207. '"%s" %s'%(waf, name), runAll)
  208. addTargetWrap('configure', True)
  209. addTargetWrap('dist', False)
  210. addTargetWrap('install', False)
  211. addTargetWrap('check', False)
  212. storageModule = self.add(doc, cproject, 'storageModule',
  213. {'moduleId': 'cdtBuildSystem',
  214. 'version': '4.0.0'})
  215. project = self.add(doc, storageModule, 'project',
  216. {'id': '%s.null.1'%appname, 'name': appname})
  217. doc.appendChild(cproject)
  218. return doc
  219. def impl_create_pydevproject(self, appname, system_path, user_path):
  220. # create a pydevproject file
  221. doc = Document()
  222. doc.appendChild(doc.createProcessingInstruction('eclipse-pydev', 'version="1.0"'))
  223. pydevproject = doc.createElement('pydev_project')
  224. prop = self.add(doc, pydevproject,
  225. 'pydev_property',
  226. 'python %d.%d'%(sys.version_info[0], sys.version_info[1]))
  227. prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_VERSION')
  228. prop = self.add(doc, pydevproject, 'pydev_property', 'Default')
  229. prop.setAttribute('name', 'org.python.pydev.PYTHON_PROJECT_INTERPRETER')
  230. # add waf's paths
  231. wafadmin = [p for p in system_path if p.find('wafadmin') != -1]
  232. if wafadmin:
  233. prop = self.add(doc, pydevproject, 'pydev_pathproperty',
  234. {'name':'org.python.pydev.PROJECT_EXTERNAL_SOURCE_PATH'})
  235. for i in wafadmin:
  236. self.add(doc, prop, 'path', i)
  237. if user_path:
  238. prop = self.add(doc, pydevproject, 'pydev_pathproperty',
  239. {'name':'org.python.pydev.PROJECT_SOURCE_PATH'})
  240. for i in user_path:
  241. self.add(doc, prop, 'path', '/'+appname+'/'+i)
  242. doc.appendChild(pydevproject)
  243. return doc
  244. def addDictionary(self, doc, parent, k, v):
  245. dictionary = self.add(doc, parent, 'dictionary')
  246. self.add(doc, dictionary, 'key', k)
  247. self.add(doc, dictionary, 'value', v)
  248. return dictionary
  249. def addTarget(self, doc, buildTargets, executable, name, buildTarget, runAllBuilders=True):
  250. target = self.add(doc, buildTargets, 'target',
  251. {'name': name,
  252. 'path': '',
  253. 'targetID': oe_cdt + '.build.MakeTargetBuilder'})
  254. self.add(doc, target, 'buildCommand', executable)
  255. self.add(doc, target, 'buildArguments', None)
  256. self.add(doc, target, 'buildTarget', buildTarget)
  257. self.add(doc, target, 'stopOnError', 'true')
  258. self.add(doc, target, 'useDefaultCommand', 'false')
  259. self.add(doc, target, 'runAllBuilders', str(runAllBuilders).lower())
  260. def add(self, doc, parent, tag, value = None):
  261. el = doc.createElement(tag)
  262. if (value):
  263. if type(value) == type(str()):
  264. el.appendChild(doc.createTextNode(value))
  265. elif type(value) == type(dict()):
  266. self.setAttributes(el, value)
  267. parent.appendChild(el)
  268. return el
  269. def setAttributes(self, node, attrs):
  270. for k, v in attrs.items():
  271. node.setAttribute(k, v)