gcc.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import os
  2. import re
  3. import platform
  4. def GetGCCRoot(rtconfig):
  5. exec_path = rtconfig.EXEC_PATH
  6. prefix = rtconfig.PREFIX
  7. if prefix.endswith('-'):
  8. prefix = prefix[:-1]
  9. root_path = os.path.join(exec_path, '..', prefix)
  10. return root_path
  11. def CheckHeader(rtconfig, filename):
  12. root = GetGCCRoot(rtconfig)
  13. fn = os.path.join(root, 'include', filename)
  14. if os.path.isfile(fn):
  15. return True
  16. return False
  17. def GetNewLibVersion(rtconfig):
  18. version = 'unknown'
  19. root = GetGCCRoot(rtconfig)
  20. if CheckHeader(rtconfig, '_newlib_version.h'): # get version from _newlib_version.h file
  21. f = file(os.path.join(root, 'include', '_newlib_version.h'))
  22. if f:
  23. for line in f:
  24. if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1:
  25. version = re.search(r'\"([^"]+)\"', line).groups()[0]
  26. elif CheckHeader(rtconfig, 'newlib.h'): # get version from newlib.h
  27. f = file(os.path.join(root, 'include', 'newlib.h'))
  28. if f:
  29. for line in f:
  30. if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1:
  31. version = re.search(r'\"([^"]+)\"', line).groups()[0]
  32. return version
  33. def GCCResult(rtconfig, str):
  34. import subprocess
  35. result = ''
  36. def checkAndGetResult(pattern, string):
  37. if re.search(pattern, string):
  38. return re.search(pattern, string).group(0)
  39. return None
  40. gcc_cmd = os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)
  41. # use temp file to get more information
  42. f = file('__tmp.c', 'w')
  43. if f:
  44. f.write(str)
  45. f.close()
  46. # '-fdirectives-only',
  47. if(platform.system() == 'Windows'):
  48. child = subprocess.Popen([gcc_cmd, '-E', '-P', '__tmp.c'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  49. else:
  50. child = subprocess.Popen(gcc_cmd + ' -E -P __tmp.c', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  51. stdout, stderr = child.communicate()
  52. print(stdout)
  53. if stderr != '':
  54. print(stderr)
  55. have_fdset = 0
  56. have_sigaction = 0
  57. have_sigevent = 0
  58. have_siginfo = 0
  59. have_sigval = 0
  60. version = None
  61. stdc = '1989'
  62. posix_thread = 0
  63. for line in stdout.split('\n'):
  64. if re.search('fd_set', line):
  65. have_fdset = 1
  66. # check for sigal
  67. if re.search('struct[ \t]+sigaction', line):
  68. have_sigaction = 1
  69. if re.search('struct[ \t]+sigevent', line):
  70. have_sigevent = 1
  71. if re.search('siginfo_t', line):
  72. have_siginfo = 1
  73. if re.search('union[ \t]+sigval', line):
  74. have_sigval = 1
  75. if re.search('char\* version', line):
  76. version = re.search(r'\"([^"]+)\"', line).groups()[0]
  77. if re.findall('iso_c_visible = [\d]+', line):
  78. stdc = re.findall('[\d]+', line)[0]
  79. if re.findall('pthread_create', line):
  80. posix_thread = 1
  81. if have_fdset:
  82. result += '#define HAVE_FDSET 1\n'
  83. if have_sigaction:
  84. result += '#define HAVE_SIGACTION 1\n'
  85. if have_sigevent:
  86. result += '#define HAVE_SIGEVENT 1\n'
  87. if have_siginfo:
  88. result += '#define HAVE_SIGINFO 1\n'
  89. if have_sigval:
  90. result += '#define HAVE_SIGVAL 1\n'
  91. if version:
  92. result += '#define GCC_VERSION "%s"\n' % version
  93. result += '#define STDC "%s"\n' % stdc
  94. if posix_thread:
  95. result += '#define LIBC_POSIX_THREADS 1\n'
  96. os.remove('__tmp.c')
  97. return result
  98. def GenerateGCCConfig(rtconfig):
  99. str = ''
  100. cc_header = ''
  101. cc_header += '#ifndef CCONFIG_H__\n'
  102. cc_header += '#define CCONFIG_H__\n'
  103. cc_header += '/* Automatically generated file; DO NOT EDIT. */\n'
  104. cc_header += '/* compiler configure file for RT-Thread in GCC*/\n\n'
  105. if CheckHeader(rtconfig, 'newlib.h'):
  106. str += '#include <newlib.h>\n'
  107. cc_header += '#define HAVE_NEWLIB_H 1\n'
  108. cc_header += '#define LIBC_VERSION "newlib %s"\n\n' % GetNewLibVersion(rtconfig)
  109. if CheckHeader(rtconfig, 'sys/signal.h'):
  110. str += '#include <sys/signal.h>\n'
  111. cc_header += '#define HAVE_SYS_SIGNAL_H 1\n'
  112. if CheckHeader(rtconfig, 'sys/select.h'):
  113. str += '#include <sys/select.h>\n'
  114. cc_header += '#define HAVE_SYS_SELECT_H 1\n'
  115. if CheckHeader(rtconfig, 'pthread.h'):
  116. str += "#include <pthread.h>\n"
  117. cc_header += '#define HAVE_PTHREAD_H 1\n'
  118. # if CheckHeader(rtconfig, 'sys/dirent.h'):
  119. # str += '#include <sys/dirent.h>\n'
  120. # add some common features
  121. str += 'const char* version = __VERSION__;\n'
  122. str += 'const int iso_c_visible = __ISO_C_VISIBLE;\n'
  123. str += '\n#ifdef HAVE_INITFINI_ARRAY\n'
  124. str += 'const int init_fini_array = HAVE_INITFINI_ARRAY;\n'
  125. str += '#endif\n'
  126. cc_header += '\n'
  127. cc_header += GCCResult(rtconfig, str)
  128. cc_header += '\n#endif\n'
  129. cc_file = file('cconfig.h', 'w')
  130. if cc_file:
  131. cc_file.write(cc_header)
  132. cc_file.close()