keil.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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('.c') != -1 or fn.rfind('.C') != -1 or fn.rfind('.cpp') != -1:
  34. return 1
  35. # assemble file type
  36. if fn.rfind('.s') != -1 or fn.rfind('.S') != -1:
  37. return 2
  38. # header type
  39. if fn.rfind('.h') != -1:
  40. return 5
  41. if fn.rfind('.lib') != -1:
  42. return 4
  43. # other filetype
  44. return 5
  45. def MDK4AddGroupForFN(ProjectFiles, parent, name, filename, project_path):
  46. group = SubElement(parent, 'Group')
  47. group_name = SubElement(group, 'GroupName')
  48. group_name.text = name
  49. name = os.path.basename(filename)
  50. path = os.path.dirname (filename)
  51. basename = os.path.basename(path)
  52. path = _make_path_relative(project_path, path)
  53. path = os.path.join(path, name)
  54. files = SubElement(group, 'Files')
  55. file = SubElement(files, 'File')
  56. file_name = SubElement(file, 'FileName')
  57. name = os.path.basename(path)
  58. if ProjectFiles.count(name):
  59. name = basename + '_' + name
  60. ProjectFiles.append(name)
  61. file_name.text = name.decode(fs_encoding)
  62. file_type = SubElement(file, 'FileType')
  63. file_type.text = '%d' % _get_filetype(name)
  64. file_path = SubElement(file, 'FilePath')
  65. file_path.text = path.decode(fs_encoding)
  66. def MDK4AddGroup(ProjectFiles, parent, name, files, project_path):
  67. # don't add an empty group
  68. if len(files) == 0:
  69. return
  70. group = SubElement(parent, 'Group')
  71. group_name = SubElement(group, 'GroupName')
  72. group_name.text = name
  73. for f in files:
  74. fn = f.rfile()
  75. name = fn.name
  76. path = os.path.dirname(fn.abspath)
  77. basename = os.path.basename(path)
  78. path = _make_path_relative(project_path, path)
  79. path = os.path.join(path, name)
  80. files = SubElement(group, 'Files')
  81. file = SubElement(files, 'File')
  82. file_name = SubElement(file, 'FileName')
  83. name = os.path.basename(path)
  84. if ProjectFiles.count(name):
  85. name = basename + '_' + name
  86. ProjectFiles.append(name)
  87. file_name.text = name.decode(fs_encoding)
  88. file_type = SubElement(file, 'FileType')
  89. file_type.text = '%d' % _get_filetype(name)
  90. file_path = SubElement(file, 'FilePath')
  91. file_path.text = path.decode(fs_encoding)
  92. def MDK4Project(target, script):
  93. project_path = os.path.dirname(os.path.abspath(target))
  94. project_uvopt = os.path.abspath(target).replace('uvproj', 'uvopt')
  95. if os.path.isfile(project_uvopt):
  96. os.unlink(project_uvopt)
  97. tree = etree.parse('template.uvproj')
  98. root = tree.getroot()
  99. out = file(target, 'wb')
  100. out.write('<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n')
  101. CPPPATH = []
  102. CPPDEFINES = []
  103. LINKFLAGS = ''
  104. CCFLAGS = ''
  105. ProjectFiles = []
  106. # add group
  107. groups = tree.find('Targets/Target/Groups')
  108. if groups is None:
  109. groups = SubElement(tree.find('Targets/Target'), 'Groups')
  110. groups.clear() # clean old groups
  111. for group in script:
  112. group_xml = MDK4AddGroup(ProjectFiles, groups, group['name'], group['src'], project_path)
  113. # get each include path
  114. if group.has_key('CPPPATH') and group['CPPPATH']:
  115. if CPPPATH:
  116. CPPPATH += group['CPPPATH']
  117. else:
  118. CPPPATH += group['CPPPATH']
  119. # get each group's definitions
  120. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  121. if CPPDEFINES:
  122. CPPDEFINES += group['CPPDEFINES']
  123. else:
  124. CPPDEFINES += group['CPPDEFINES']
  125. # get each group's link flags
  126. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  127. if LINKFLAGS:
  128. LINKFLAGS += ' ' + group['LINKFLAGS']
  129. else:
  130. LINKFLAGS += group['LINKFLAGS']
  131. if group.has_key('LIBS') and group['LIBS']:
  132. for item in group['LIBS']:
  133. lib_path = ''
  134. for path_item in group['LIBPATH']:
  135. full_path = os.path.join(path_item, item + '.lib')
  136. if os.path.isfile(full_path): # has this library
  137. lib_path = full_path
  138. if lib_path != '':
  139. MDK4AddGroupForFN(ProjectFiles, groups, group['name'], lib_path, project_path)
  140. # write include path, definitions and link flags
  141. IncludePath = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/IncludePath')
  142. IncludePath.text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in CPPPATH])
  143. Define = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/Define')
  144. Define.text = ', '.join(set(CPPDEFINES))
  145. Misc = tree.find('Targets/Target/TargetOption/TargetArmAds/LDads/Misc')
  146. Misc.text = LINKFLAGS
  147. xml_indent(root)
  148. out.write(etree.tostring(root, encoding='utf-8'))
  149. out.close()
  150. # copy uvopt file
  151. if os.path.exists('template.uvopt'):
  152. import shutil
  153. shutil.copy2('template.uvopt', 'project.uvopt')
  154. def MDK5AddGroupForFN(ProjectFiles, parent, name, filename, project_path):
  155. group = SubElement(parent, 'Group')
  156. group_name = SubElement(group, 'GroupName')
  157. group_name.text = name
  158. name = os.path.basename(filename)
  159. path = os.path.dirname (filename)
  160. basename = os.path.basename(path)
  161. path = _make_path_relative(project_path, path)
  162. path = os.path.join(path, name)
  163. files = SubElement(group, 'Files')
  164. file = SubElement(files, 'File')
  165. file_name = SubElement(file, 'FileName')
  166. name = os.path.basename(path)
  167. if ProjectFiles.count(name):
  168. name = basename + '_' + name
  169. ProjectFiles.append(name)
  170. file_name.text = name.decode(fs_encoding)
  171. file_type = SubElement(file, 'FileType')
  172. file_type.text = '%d' % _get_filetype(name)
  173. file_path = SubElement(file, 'FilePath')
  174. file_path.text = path.decode(fs_encoding)
  175. def MDK5AddGroup(ProjectFiles, parent, name, files, project_path):
  176. # don't add an empty group
  177. if len(files) == 0:
  178. return
  179. group = SubElement(parent, 'Group')
  180. group_name = SubElement(group, 'GroupName')
  181. group_name.text = name
  182. for f in files:
  183. fn = f.rfile()
  184. name = fn.name
  185. path = os.path.dirname(fn.abspath)
  186. basename = os.path.basename(path)
  187. path = _make_path_relative(project_path, path)
  188. path = os.path.join(path, name)
  189. files = SubElement(group, 'Files')
  190. file = SubElement(files, 'File')
  191. file_name = SubElement(file, 'FileName')
  192. name = os.path.basename(path)
  193. if ProjectFiles.count(name):
  194. name = basename + '_' + name
  195. ProjectFiles.append(name)
  196. file_name.text = name.decode(fs_encoding)
  197. file_type = SubElement(file, 'FileType')
  198. file_type.text = '%d' % _get_filetype(name)
  199. file_path = SubElement(file, 'FilePath')
  200. file_path.text = path.decode(fs_encoding)
  201. def MDK5Project(target, script):
  202. project_path = os.path.dirname(os.path.abspath(target))
  203. project_uvopt = os.path.abspath(target).replace('uvprojx', 'uvoptx')
  204. if os.path.isfile(project_uvopt):
  205. os.unlink(project_uvopt)
  206. tree = etree.parse('template.uvprojx')
  207. root = tree.getroot()
  208. out = file(target, 'wb')
  209. out.write('<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n')
  210. CPPPATH = []
  211. CPPDEFINES = []
  212. LINKFLAGS = ''
  213. CCFLAGS = ''
  214. ProjectFiles = []
  215. # add group
  216. groups = tree.find('Targets/Target/Groups')
  217. if groups is None:
  218. groups = SubElement(tree.find('Targets/Target'), 'Groups')
  219. for group in script:
  220. group_xml = MDK4AddGroup(ProjectFiles, groups, group['name'], group['src'], project_path)
  221. # get each include path
  222. if group.has_key('CPPPATH') and group['CPPPATH']:
  223. if CPPPATH:
  224. CPPPATH += group['CPPPATH']
  225. else:
  226. CPPPATH += group['CPPPATH']
  227. # get each group's definitions
  228. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  229. if CPPDEFINES:
  230. CPPDEFINES += group['CPPDEFINES']
  231. else:
  232. CPPDEFINES += group['CPPDEFINES']
  233. # get each group's link flags
  234. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  235. if LINKFLAGS:
  236. LINKFLAGS += ' ' + group['LINKFLAGS']
  237. else:
  238. LINKFLAGS += group['LINKFLAGS']
  239. if group.has_key('LIBS') and group['LIBS']:
  240. for item in group['LIBS']:
  241. lib_path = ''
  242. for path_item in group['LIBPATH']:
  243. full_path = os.path.join(path_item, item + '.lib')
  244. if os.path.isfile(full_path): # has this library
  245. lib_path = full_path
  246. if lib_path != '':
  247. MDK4AddGroupForFN(ProjectFiles, groups, group['name'], lib_path, project_path)
  248. # remove repeat path
  249. paths = set()
  250. for path in CPPPATH:
  251. inc = _make_path_relative(project_path, os.path.normpath(path))
  252. paths.add(inc) #.replace('\\', '/')
  253. paths = [i for i in paths]
  254. paths.sort()
  255. CPPPATH = string.join(paths, ';')
  256. definitions = [i for i in set(CPPDEFINES)]
  257. CPPDEFINES = string.join(definitions, ', ')
  258. # write include path, definitions and link flags
  259. IncludePath = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/IncludePath')
  260. IncludePath.text = CPPPATH
  261. Define = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/Define')
  262. Define.text = CPPDEFINES
  263. Misc = tree.find('Targets/Target/TargetOption/TargetArmAds/LDads/Misc')
  264. Misc.text = LINKFLAGS
  265. xml_indent(root)
  266. out.write(etree.tostring(root, encoding='utf-8'))
  267. out.close()
  268. # copy uvopt file
  269. if os.path.exists('template.uvoptx'):
  270. import shutil
  271. shutil.copy2('template.uvoptx', 'project.uvoptx')
  272. def MDKProject(target, script):
  273. template = file('template.Uv2', "rb")
  274. lines = template.readlines()
  275. project = file(target, "wb")
  276. project_path = os.path.dirname(os.path.abspath(target))
  277. line_index = 5
  278. # write group
  279. for group in script:
  280. lines.insert(line_index, 'Group (%s)\r\n' % group['name'])
  281. line_index += 1
  282. lines.insert(line_index, '\r\n')
  283. line_index += 1
  284. # write file
  285. ProjectFiles = []
  286. CPPPATH = []
  287. CPPDEFINES = []
  288. LINKFLAGS = ''
  289. CCFLAGS = ''
  290. # number of groups
  291. group_index = 1
  292. for group in script:
  293. # print group['name']
  294. # get each include path
  295. if group.has_key('CPPPATH') and group['CPPPATH']:
  296. if CPPPATH:
  297. CPPPATH += group['CPPPATH']
  298. else:
  299. CPPPATH += group['CPPPATH']
  300. # get each group's definitions
  301. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  302. if CPPDEFINES:
  303. CPPDEFINES += ';' + group['CPPDEFINES']
  304. else:
  305. CPPDEFINES += group['CPPDEFINES']
  306. # get each group's link flags
  307. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  308. if LINKFLAGS:
  309. LINKFLAGS += ' ' + group['LINKFLAGS']
  310. else:
  311. LINKFLAGS += group['LINKFLAGS']
  312. # generate file items
  313. for node in group['src']:
  314. fn = node.rfile()
  315. name = fn.name
  316. path = os.path.dirname(fn.abspath)
  317. basename = os.path.basename(path)
  318. path = _make_path_relative(project_path, path)
  319. path = os.path.join(path, name)
  320. if ProjectFiles.count(name):
  321. name = basename + '_' + name
  322. ProjectFiles.append(name)
  323. lines.insert(line_index, 'File %d,%d,<%s><%s>\r\n'
  324. % (group_index, _get_filetype(name), path, name))
  325. line_index += 1
  326. group_index = group_index + 1
  327. lines.insert(line_index, '\r\n')
  328. line_index += 1
  329. # remove repeat path
  330. paths = set()
  331. for path in CPPPATH:
  332. inc = _make_path_relative(project_path, os.path.normpath(path))
  333. paths.add(inc) #.replace('\\', '/')
  334. paths = [i for i in paths]
  335. CPPPATH = string.join(paths, ';')
  336. definitions = [i for i in set(CPPDEFINES)]
  337. CPPDEFINES = string.join(definitions, ', ')
  338. while line_index < len(lines):
  339. if lines[line_index].startswith(' ADSCINCD '):
  340. lines[line_index] = ' ADSCINCD (' + CPPPATH + ')\r\n'
  341. if lines[line_index].startswith(' ADSLDMC ('):
  342. lines[line_index] = ' ADSLDMC (' + LINKFLAGS + ')\r\n'
  343. if lines[line_index].startswith(' ADSCDEFN ('):
  344. lines[line_index] = ' ADSCDEFN (' + CPPDEFINES + ')\r\n'
  345. line_index += 1
  346. # write project
  347. for line in lines:
  348. project.write(line)
  349. project.close()