utils.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. #
  2. # File : utils.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 sys
  25. import os
  26. def splitall(loc):
  27. """
  28. Return a list of the path components in loc. (Used by relpath_).
  29. The first item in the list will be either ``os.curdir``, ``os.pardir``, empty,
  30. or the root directory of loc (for example, ``/`` or ``C:\\).
  31. The other items in the list will be strings.
  32. Adapted from *path.py* by Jason Orendorff.
  33. """
  34. parts = []
  35. while loc != os.curdir and loc != os.pardir:
  36. prev = loc
  37. loc, child = os.path.split(prev)
  38. if loc == prev:
  39. break
  40. parts.append(child)
  41. parts.append(loc)
  42. parts.reverse()
  43. return parts
  44. def _make_path_relative(origin, dest):
  45. """
  46. Return the relative path between origin and dest.
  47. If it's not possible return dest.
  48. If they are identical return ``os.curdir``
  49. Adapted from `path.py <http://www.jorendorff.com/articles/python/path/>`_ by Jason Orendorff.
  50. """
  51. origin = os.path.abspath(origin).replace('\\', '/')
  52. dest = os.path.abspath(dest).replace('\\', '/')
  53. #
  54. orig_list = splitall(os.path.normcase(origin))
  55. # Don't normcase dest! We want to preserve the case.
  56. dest_list = splitall(dest)
  57. #
  58. if orig_list[0] != os.path.normcase(dest_list[0]):
  59. # Can't get here from there.
  60. return dest
  61. #
  62. # Find the location where the two paths start to differ.
  63. i = 0
  64. for start_seg, dest_seg in zip(orig_list, dest_list):
  65. if start_seg != os.path.normcase(dest_seg):
  66. break
  67. i += 1
  68. #
  69. # Now i is the point where the two paths diverge.
  70. # Need a certain number of "os.pardir"s to work up
  71. # from the origin to the point of divergence.
  72. segments = [os.pardir] * (len(orig_list) - i)
  73. # Need to add the diverging part of dest_list.
  74. segments += dest_list[i:]
  75. if len(segments) == 0:
  76. # If they happen to be identical, use os.curdir.
  77. return os.curdir
  78. else:
  79. # return os.path.join(*segments).replace('\\', '/')
  80. return os.path.join(*segments)
  81. def xml_indent(elem, level=0):
  82. i = "\n" + level*" "
  83. if len(elem):
  84. if not elem.text or not elem.text.strip():
  85. elem.text = i + " "
  86. if not elem.tail or not elem.tail.strip():
  87. elem.tail = i
  88. for elem in elem:
  89. xml_indent(elem, level+1)
  90. if not elem.tail or not elem.tail.strip():
  91. elem.tail = i
  92. else:
  93. if level and (not elem.tail or not elem.tail.strip()):
  94. elem.tail = i
  95. source_ext = ["c", "h", "s", "S", "cpp", "xpm"]
  96. source_list = []
  97. def walk_children(child):
  98. global source_list
  99. global source_ext
  100. # print child
  101. full_path = child.rfile().abspath
  102. file_type_list = full_path.rsplit('.',1)
  103. #print file_type
  104. if (len(file_type_list) > 1):
  105. file_type = full_path.rsplit('.',1)[1]
  106. if file_type in source_ext:
  107. if full_path not in source_list:
  108. source_list.append(full_path)
  109. children = child.all_children()
  110. if children != []:
  111. for item in children:
  112. walk_children(item)
  113. def PrefixPath(prefix, path):
  114. path = os.path.abspath(path)
  115. prefix = os.path.abspath(prefix)
  116. if sys.platform == 'win32':
  117. prefix = prefix.lower()
  118. path = path.lower()
  119. if path.startswith(prefix):
  120. return True
  121. return False
  122. def ListMap(l):
  123. ret_list = []
  124. for item in l:
  125. if type(item) == type(()):
  126. ret = ListMap(item)
  127. ret_list += ret
  128. elif type(item) == type([]):
  129. ret = ListMap(item)
  130. ret_list += ret
  131. else:
  132. ret_list.append(item)
  133. return ret_list
  134. def TargetGetList(env, postfix):
  135. global source_ext
  136. global source_list
  137. target = env['target']
  138. source_ext = postfix
  139. for item in target:
  140. walk_children(item)
  141. source_list.sort()
  142. return source_list
  143. def ProjectInfo(env):
  144. project = env['project']
  145. RTT_ROOT = env['RTT_ROOT']
  146. BSP_ROOT = env['BSP_ROOT']
  147. FILES = []
  148. DIRS = []
  149. HEADERS = []
  150. CPPPATH = []
  151. CPPDEFINES = []
  152. for group in project:
  153. # get each files
  154. if 'src' in group and group['src']:
  155. FILES += group['src']
  156. # get each include path
  157. if 'CPPPATH' in group and group['CPPPATH']:
  158. CPPPATH += group['CPPPATH']
  159. if 'CPPDEFINES' in env:
  160. CPPDEFINES = env['CPPDEFINES']
  161. CPPDEFINES = ListMap(CPPDEFINES)
  162. # process FILES and DIRS
  163. if len(FILES):
  164. # use absolute path
  165. for i in range(len(FILES)):
  166. FILES[i] = os.path.abspath(str(FILES[i]))
  167. DIRS.append(os.path.dirname(FILES[i]))
  168. FILES.sort()
  169. DIRS = list(set(DIRS))
  170. DIRS.sort()
  171. # process HEADERS
  172. HEADERS = TargetGetList(env, ['h'])
  173. # process CPPPATH
  174. if len(CPPPATH):
  175. # use absolute path
  176. for i in range(len(CPPPATH)):
  177. CPPPATH[i] = os.path.abspath(CPPPATH[i])
  178. # remove repeat path
  179. paths = [i for i in set(CPPPATH)]
  180. CPPPATH = []
  181. for path in paths:
  182. if PrefixPath(RTT_ROOT, path):
  183. CPPPATH += [os.path.abspath(path).replace('\\', '/')]
  184. elif PrefixPath(BSP_ROOT, path):
  185. CPPPATH += [os.path.abspath(path).replace('\\', '/')]
  186. else:
  187. CPPPATH += ['"%s",' % path.replace('\\', '/')]
  188. CPPPATH.sort()
  189. # process CPPDEFINES
  190. if len(CPPDEFINES):
  191. CPPDEFINES = [i for i in set(CPPDEFINES)]
  192. CPPDEFINES.sort()
  193. proj = {}
  194. proj['FILES'] = FILES
  195. proj['DIRS'] = DIRS
  196. proj['HEADERS'] = HEADERS
  197. proj['CPPPATH'] = CPPPATH
  198. proj['CPPDEFINES'] = CPPDEFINES
  199. return proj
  200. def VersionCmp(ver1, ver2):
  201. la=[];
  202. if ver1:
  203. la = ver1.split('.')
  204. lb = ver2.split('.')
  205. f = 0
  206. if len(la) > len(lb):
  207. f = len(la)
  208. else:
  209. f = len(lb)
  210. for i in range(f):
  211. try:
  212. if int(la[i]) > int(lb[i]):
  213. return 1
  214. elif int(la[i]) == int(lb[i]):
  215. continue
  216. else:
  217. return -1
  218. except IndexError as e:
  219. if len(la) > len(lb):
  220. return 1
  221. else:
  222. return -1
  223. return 0
  224. def GCCC99Patch(cflags):
  225. import building
  226. gcc_version = building.GetDepend('GCC_VERSION')
  227. if gcc_version:
  228. gcc_version = gcc_version.replace('"', '')
  229. if VersionCmp(gcc_version, "4.8.0"):
  230. # remove -std=c99 after GCC 4.8.x
  231. cflags = cflags.replace('-std=c99', '')
  232. return cflags
  233. def ReloadModule(module):
  234. import sys
  235. if sys.version_info.major >= 3:
  236. import importlib
  237. importlib.reload(module)
  238. else:
  239. reload(module)
  240. return