mdk.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import os
  2. import string
  3. import SCons.Script
  4. def _get_filetype(fn):
  5. if fn.rfind('.c') or fn.rfind('.C') or fn.rfind('.cpp'):
  6. return 1
  7. # assimble file type
  8. if fn.rfind('.s') or fn.rfind('.S'):
  9. return 2
  10. # header type
  11. if fn.rfind('.h'):
  12. return 5
  13. # other filetype
  14. return 5
  15. def splitall(loc):
  16. """
  17. Return a list of the path components in loc. (Used by relpath_).
  18. The first item in the list will be either ``os.curdir``, ``os.pardir``, empty,
  19. or the root directory of loc (for example, ``/`` or ``C:\\).
  20. The other items in the list will be strings.
  21. Adapted from *path.py* by Jason Orendorff.
  22. """
  23. parts = []
  24. while loc != os.curdir and loc != os.pardir:
  25. prev = loc
  26. loc, child = os.path.split(prev)
  27. if loc == prev:
  28. break
  29. parts.append(child)
  30. parts.append(loc)
  31. parts.reverse()
  32. return parts
  33. def _make_path_relative(origin, dest):
  34. """
  35. Return the relative path between origin and dest.
  36. If it's not possible return dest.
  37. If they are identical return ``os.curdir``
  38. Adapted from `path.py <http://www.jorendorff.com/articles/python/path/>`_ by Jason Orendorff.
  39. """
  40. origin = os.path.abspath(origin).replace('\\', '/')
  41. dest = os.path.abspath(dest).replace('\\', '/')
  42. #
  43. orig_list = splitall(os.path.normcase(origin))
  44. # Don't normcase dest! We want to preserve the case.
  45. dest_list = splitall(dest)
  46. #
  47. if orig_list[0] != os.path.normcase(dest_list[0]):
  48. # Can't get here from there.
  49. return dest
  50. #
  51. # Find the location where the two paths start to differ.
  52. i = 0
  53. for start_seg, dest_seg in zip(orig_list, dest_list):
  54. if start_seg != os.path.normcase(dest_seg):
  55. break
  56. i += 1
  57. #
  58. # Now i is the point where the two paths diverge.
  59. # Need a certain number of "os.pardir"s to work up
  60. # from the origin to the point of divergence.
  61. segments = [os.pardir] * (len(orig_list) - i)
  62. # Need to add the diverging part of dest_list.
  63. segments += dest_list[i:]
  64. if len(segments) == 0:
  65. # If they happen to be identical, use os.curdir.
  66. return os.curdir
  67. else:
  68. # return os.path.join(*segments).replace('\\', '/')
  69. return os.path.join(*segments)
  70. def MDKProject(target, script):
  71. template = file('template.uV2', "rb")
  72. lines = template.readlines()
  73. project = file(target, "wb")
  74. project_path = os.path.dirname(os.path.abspath(target))
  75. line_index = 5
  76. # write group
  77. for group in script:
  78. lines.insert(line_index, 'Group (%s)\r\n' % group['name'])
  79. line_index += 1
  80. lines.insert(line_index, '\r\n')
  81. line_index += 1
  82. # write file
  83. CPPPATH = []
  84. CPPDEFINES = []
  85. LINKFLAGS = ''
  86. CCFLAGS = ''
  87. # number of groups
  88. group_index = 1
  89. for group in script:
  90. # print group['name']
  91. # get each include path
  92. if group.has_key('CPPPATH') and group['CPPPATH']:
  93. if CPPPATH:
  94. CPPPATH += group['CPPPATH']
  95. else:
  96. CPPPATH += group['CPPPATH']
  97. # get each group's definitions
  98. if group.has_key('CPPDEFINES') and group['CPPDEFINES']:
  99. if CPPDEFINES:
  100. CPPDEFINES += ';' + group['CPPDEFINES']
  101. else:
  102. CPPDEFINES += group['CPPDEFINES']
  103. # get each group's link flags
  104. if group.has_key('LINKFLAGS') and group['LINKFLAGS']:
  105. if LINKFLAGS:
  106. LINKFLAGS += ' ' + group['LINKFLAGS']
  107. else:
  108. LINKFLAGS += group['LINKFLAGS']
  109. # generate file items
  110. for node in group['src']:
  111. fn = node.rfile()
  112. name = fn.name
  113. path = os.path.dirname(fn.abspath)
  114. path = _make_path_relative(project_path, path)
  115. path = os.path.join(path, name)
  116. lines.insert(line_index, 'File %d,%d<%s><%s>\r\n'
  117. % (group_index, _get_filetype(name), path, name))
  118. line_index += 1
  119. group_index = group_index + 1
  120. lines.insert(line_index, '\r\n')
  121. line_index += 1
  122. # remove repeat path
  123. paths = set()
  124. for path in CPPPATH:
  125. inc = _make_path_relative(project_path, os.path.normpath(path))
  126. paths.add(inc) #.replace('\\', '/')
  127. paths = [i for i in paths]
  128. CPPPATH = string.join(paths, ';')
  129. definitions = [i for i in set(CPPDEFINES)]
  130. CPPDEFINES = string.join(definitions, ', ')
  131. while line_index < len(lines):
  132. if lines[line_index].startswith(' ADSCINCD '):
  133. lines[line_index] = ' ADSCINCD (' + CPPPATH + ')\r\n'
  134. if lines[line_index].startswith(' ADSLDMC ('):
  135. lines[line_index] = ' ADSLDMC (' + LINKFLAGS + ')\r\n'
  136. if lines[line_index].startswith(' ADSCDEFN ('):
  137. lines[line_index] = ' ADSCDEFN (' + CPPDEFINES + ')\r\n'
  138. line_index += 1
  139. # write project
  140. for line in lines:
  141. project.write(line)
  142. project.close()