keil.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #
  2. # File : keil.py
  3. # This file is part of RT-Thread RTOS
  4. # COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License along
  17. # with this program; if not, write to the Free Software Foundation, Inc.,
  18. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. #
  20. # Change Logs:
  21. # Date Author Notes
  22. # 2015-01-20 Bernard Add copyright information
  23. #
  24. import os
  25. import sys
  26. import string
  27. import xml.etree.ElementTree as etree
  28. from xml.etree.ElementTree import SubElement
  29. from utils import _make_path_relative
  30. from utils import xml_indent
  31. fs_encoding = sys.getfilesystemencoding()
  32. def _get_filetype(fn):
  33. if fn.rfind('.cpp') != -1 or fn.rfind('.cxx') != -1:
  34. return 8
  35. if fn.rfind('.c') != -1 or fn.rfind('.C') != -1:
  36. return 1
  37. # assemble file type
  38. if fn.rfind('.s') != -1 or fn.rfind('.S') != -1:
  39. return 2
  40. # header type
  41. if fn.rfind('.h') != -1:
  42. return 5
  43. if fn.rfind('.lib') != -1:
  44. return 4
  45. # other filetype
  46. return 5
  47. def MDK4AddGroupForFN(ProjectFiles, parent, name, filename, project_path):
  48. group = SubElement(parent, 'Group')
  49. group_name = SubElement(group, 'GroupName')
  50. group_name.text = name
  51. name = os.path.basename(filename)
  52. path = os.path.dirname (filename)
  53. basename = os.path.basename(path)
  54. path = _make_path_relative(project_path, path)
  55. path = os.path.join(path, name)
  56. files = SubElement(group, 'Files')
  57. file = SubElement(files, 'File')
  58. file_name = SubElement(file, 'FileName')
  59. name = os.path.basename(path)
  60. if name.find('.cpp') != -1:
  61. obj_name = name.replace('.cpp', '.o')
  62. elif name.find('.c') != -1:
  63. obj_name = name.replace('.c', '.o')
  64. elif name.find('.s') != -1:
  65. obj_name = name.replace('.s', '.o')
  66. elif name.find('.S') != -1:
  67. obj_name = name.replace('.s', '.o')
  68. else:
  69. obj_name = name
  70. if ProjectFiles.count(obj_name):
  71. name = basename + '_' + name
  72. ProjectFiles.append(obj_name)
  73. file_name.text = name.decode(fs_encoding)
  74. file_type = SubElement(file, 'FileType')
  75. file_type.text = '%d' % _get_filetype(name)
  76. file_path = SubElement(file, 'FilePath')
  77. file_path.text = path.decode(fs_encoding)
  78. def MDK4AddLibToGroup(ProjectFiles, group, name, filename, project_path):
  79. name = os.path.basename(filename)
  80. path = os.path.dirname (filename)
  81. basename = os.path.basename(path)
  82. path = _make_path_relative(project_path, path)
  83. path = os.path.join(path, name)
  84. files = SubElement(group, 'Files')
  85. file = SubElement(files, 'File')
  86. file_name = SubElement(file, 'FileName')
  87. name = os.path.basename(path)
  88. if name.find('.cpp') != -1:
  89. obj_name = name.replace('.cpp', '.o')
  90. elif name.find('.c') != -1:
  91. obj_name = name.replace('.c', '.o')
  92. elif name.find('.s') != -1:
  93. obj_name = name.replace('.s', '.o')
  94. elif name.find('.S') != -1:
  95. obj_name = name.replace('.s', '.o')
  96. else:
  97. obj_name = name
  98. if ProjectFiles.count(obj_name):
  99. name = basename + '_' + name
  100. ProjectFiles.append(obj_name)
  101. file_name.text = name.decode(fs_encoding)
  102. file_type = SubElement(file, 'FileType')
  103. file_type.text = '%d' % _get_filetype(name)
  104. file_path = SubElement(file, 'FilePath')
  105. file_path.text = path.decode(fs_encoding)
  106. def MDK4AddGroup(ProjectFiles, parent, name, files, project_path):
  107. # don't add an empty group
  108. if len(files) == 0:
  109. return
  110. group = SubElement(parent, 'Group')
  111. group_name = SubElement(group, 'GroupName')
  112. group_name.text = name
  113. for f in files:
  114. fn = f.rfile()
  115. name = fn.name
  116. path = os.path.dirname(fn.abspath)
  117. basename = os.path.basename(path)
  118. path = _make_path_relative(project_path, path)
  119. path = os.path.join(path, name)
  120. files = SubElement(group, 'Files')
  121. file = SubElement(files, 'File')
  122. file_name = SubElement(file, 'FileName')
  123. name = os.path.basename(path)
  124. if name.find('.cpp') != -1:
  125. obj_name = name.replace('.cpp', '.o')
  126. elif name.find('.c') != -1:
  127. obj_name = name.replace('.c', '.o')
  128. elif name.find('.s') != -1:
  129. obj_name = name.replace('.s', '.o')
  130. elif name.find('.S') != -1:
  131. obj_name = name.replace('.s', '.o')
  132. if ProjectFiles.count(obj_name):
  133. name = basename + '_' + name
  134. ProjectFiles.append(obj_name)
  135. file_name.text = name.decode(fs_encoding)
  136. file_type = SubElement(file, 'FileType')
  137. file_type.text = '%d' % _get_filetype(name)
  138. file_path = SubElement(file, 'FilePath')
  139. file_path.text = path.decode(fs_encoding)
  140. return group
  141. # The common part of making MDK4/5 project
  142. def MDK45Project(tree, target, script):
  143. project_path = os.path.dirname(os.path.abspath(target))
  144. root = tree.getroot()
  145. out = file(target, 'wb')
  146. out.write('<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n')
  147. CPPPATH = []
  148. CPPDEFINES = []
  149. LINKFLAGS = ''
  150. CCFLAGS = ''
  151. ProjectFiles = []
  152. # add group
  153. groups = tree.find('Targets/Target/Groups')
  154. if groups is None:
  155. groups = SubElement(tree.find('Targets/Target'), 'Groups')
  156. groups.clear() # clean old groups
  157. for group in script:
  158. group_tree = MDK4AddGroup(ProjectFiles, groups, group['name'], group['src'], project_path)
  159. # for local CPPPATH/CPPDEFINES
  160. if (group_tree != None) and (group.has_key('LOCAL_CPPPATH') or group.has_key('LOCAL_CCFLAGS')):
  161. GroupOption = SubElement(group_tree, 'GroupOption')
  162. GroupArmAds = SubElement(GroupOption, 'GroupArmAds')
  163. Cads = SubElement(GroupArmAds, 'Cads')
  164. VariousControls = SubElement(Cads, 'VariousControls')
  165. MiscControls = SubElement(VariousControls, 'MiscControls')
  166. if group.has_key('LOCAL_CCFLAGS'):
  167. MiscControls.text = group['LOCAL_CCFLAGS']
  168. else:
  169. MiscControls.text = ' '
  170. Define = SubElement(VariousControls, 'Define')
  171. if group.has_key('LOCAL_CPPDEFINES'):
  172. Define.text = ', '.join(set(group['LOCAL_CPPDEFINES']))
  173. else:
  174. Define.text = ' '
  175. Undefine = SubElement(VariousControls, 'Undefine')
  176. Undefine.text = ' '
  177. IncludePath = SubElement(VariousControls, 'IncludePath')
  178. if group.has_key('LOCAL_CPPPATH'):
  179. IncludePath.text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in group['LOCAL_CPPPATH']])
  180. else:
  181. IncludePath.text = ' '
  182. # get each include path
  183. if group.has_key('CPPPATH') and group['CPPPATH']:
  184. if CPPPATH:
  185. CPPPATH += group['CPPPATH']
  186. else:
  187. CPPPATH += group['CPPPATH']
  188. # get each group's definitions
  189. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  190. if CPPDEFINES:
  191. CPPDEFINES += group['CPPDEFINES']
  192. else:
  193. CPPDEFINES = group['CPPDEFINES']
  194. # get each group's link flags
  195. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  196. if LINKFLAGS:
  197. LINKFLAGS += ' ' + group['LINKFLAGS']
  198. else:
  199. LINKFLAGS += group['LINKFLAGS']
  200. if group.has_key('LIBS') and group['LIBS']:
  201. for item in group['LIBS']:
  202. lib_path = ''
  203. for path_item in group['LIBPATH']:
  204. full_path = os.path.join(path_item, item + '.lib')
  205. if os.path.isfile(full_path): # has this library
  206. lib_path = full_path
  207. if lib_path != '':
  208. if (group_tree != None):
  209. MDK4AddLibToGroup(ProjectFiles, group_tree, group['name'], lib_path, project_path)
  210. else:
  211. MDK4AddGroupForFN(ProjectFiles, groups, group['name'], lib_path, project_path)
  212. # write include path, definitions and link flags
  213. IncludePath = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/IncludePath')
  214. IncludePath.text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in CPPPATH])
  215. Define = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/Define')
  216. Define.text = ', '.join(set(CPPDEFINES))
  217. Misc = tree.find('Targets/Target/TargetOption/TargetArmAds/LDads/Misc')
  218. Misc.text = LINKFLAGS
  219. xml_indent(root)
  220. out.write(etree.tostring(root, encoding='utf-8'))
  221. out.close()
  222. def MDK4Project(target, script):
  223. template_tree = etree.parse('template.uvproj')
  224. MDK45Project(template_tree, target, script)
  225. # remove project.uvopt file
  226. project_uvopt = os.path.abspath(target).replace('uvproj', 'uvopt')
  227. if os.path.isfile(project_uvopt):
  228. os.unlink(project_uvopt)
  229. # copy uvopt file
  230. if os.path.exists('template.uvopt'):
  231. import shutil
  232. shutil.copy2('template.uvopt', 'project.uvopt')
  233. def MDK5Project(target, script):
  234. template_tree = etree.parse('template.uvprojx')
  235. MDK45Project(template_tree, target, script)
  236. # remove project.uvopt file
  237. project_uvopt = os.path.abspath(target).replace('uvprojx', 'uvoptx')
  238. if os.path.isfile(project_uvopt):
  239. os.unlink(project_uvopt)
  240. # copy uvopt file
  241. if os.path.exists('template.uvoptx'):
  242. import shutil
  243. shutil.copy2('template.uvoptx', 'project.uvoptx')
  244. def MDKProject(target, script):
  245. template = file('template.Uv2', "rb")
  246. lines = template.readlines()
  247. project = file(target, "wb")
  248. project_path = os.path.dirname(os.path.abspath(target))
  249. line_index = 5
  250. # write group
  251. for group in script:
  252. lines.insert(line_index, 'Group (%s)\r\n' % group['name'])
  253. line_index += 1
  254. lines.insert(line_index, '\r\n')
  255. line_index += 1
  256. # write file
  257. ProjectFiles = []
  258. CPPPATH = []
  259. CPPDEFINES = []
  260. LINKFLAGS = ''
  261. CCFLAGS = ''
  262. # number of groups
  263. group_index = 1
  264. for group in script:
  265. # print group['name']
  266. # get each include path
  267. if group.has_key('CPPPATH') and group['CPPPATH']:
  268. if CPPPATH:
  269. CPPPATH += group['CPPPATH']
  270. else:
  271. CPPPATH += group['CPPPATH']
  272. # get each group's definitions
  273. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  274. if CPPDEFINES:
  275. CPPDEFINES += group['CPPDEFINES']
  276. else:
  277. CPPDEFINES = group['CPPDEFINES']
  278. # get each group's link flags
  279. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  280. if LINKFLAGS:
  281. LINKFLAGS += ' ' + group['LINKFLAGS']
  282. else:
  283. LINKFLAGS += group['LINKFLAGS']
  284. # generate file items
  285. for node in group['src']:
  286. fn = node.rfile()
  287. name = fn.name
  288. path = os.path.dirname(fn.abspath)
  289. basename = os.path.basename(path)
  290. path = _make_path_relative(project_path, path)
  291. path = os.path.join(path, name)
  292. if ProjectFiles.count(name):
  293. name = basename + '_' + name
  294. ProjectFiles.append(name)
  295. lines.insert(line_index, 'File %d,%d,<%s><%s>\r\n'
  296. % (group_index, _get_filetype(name), path, name))
  297. line_index += 1
  298. group_index = group_index + 1
  299. lines.insert(line_index, '\r\n')
  300. line_index += 1
  301. # remove repeat path
  302. paths = set()
  303. for path in CPPPATH:
  304. inc = _make_path_relative(project_path, os.path.normpath(path))
  305. paths.add(inc) #.replace('\\', '/')
  306. paths = [i for i in paths]
  307. CPPPATH = string.join(paths, ';')
  308. definitions = [i for i in set(CPPDEFINES)]
  309. CPPDEFINES = string.join(definitions, ', ')
  310. while line_index < len(lines):
  311. if lines[line_index].startswith(' ADSCINCD '):
  312. lines[line_index] = ' ADSCINCD (' + CPPPATH + ')\r\n'
  313. if lines[line_index].startswith(' ADSLDMC ('):
  314. lines[line_index] = ' ADSLDMC (' + LINKFLAGS + ')\r\n'
  315. if lines[line_index].startswith(' ADSCDEFN ('):
  316. lines[line_index] = ' ADSCDEFN (' + CPPDEFINES + ')\r\n'
  317. line_index += 1
  318. # write project
  319. for line in lines:
  320. project.write(line)
  321. project.close()