keil.py 15 KB

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