1*10465441SEvalZero# 2*10465441SEvalZero# File : gcc.py 3*10465441SEvalZero# This file is part of RT-Thread RTOS 4*10465441SEvalZero# COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team 5*10465441SEvalZero# 6*10465441SEvalZero# This program is free software; you can redistribute it and/or modify 7*10465441SEvalZero# it under the terms of the GNU General Public License as published by 8*10465441SEvalZero# the Free Software Foundation; either version 2 of the License, or 9*10465441SEvalZero# (at your option) any later version. 10*10465441SEvalZero# 11*10465441SEvalZero# This program is distributed in the hope that it will be useful, 12*10465441SEvalZero# but WITHOUT ANY WARRANTY; without even the implied warranty of 13*10465441SEvalZero# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*10465441SEvalZero# GNU General Public License for more details. 15*10465441SEvalZero# 16*10465441SEvalZero# You should have received a copy of the GNU General Public License along 17*10465441SEvalZero# with this program; if not, write to the Free Software Foundation, Inc., 18*10465441SEvalZero# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19*10465441SEvalZero# 20*10465441SEvalZero# Change Logs: 21*10465441SEvalZero# Date Author Notes 22*10465441SEvalZero# 2018-05-22 Bernard The first version 23*10465441SEvalZero 24*10465441SEvalZeroimport os 25*10465441SEvalZeroimport re 26*10465441SEvalZeroimport platform 27*10465441SEvalZero 28*10465441SEvalZerodef GetGCCRoot(rtconfig): 29*10465441SEvalZero exec_path = rtconfig.EXEC_PATH 30*10465441SEvalZero prefix = rtconfig.PREFIX 31*10465441SEvalZero 32*10465441SEvalZero if prefix.endswith('-'): 33*10465441SEvalZero prefix = prefix[:-1] 34*10465441SEvalZero 35*10465441SEvalZero root_path = os.path.join(exec_path, '..', prefix) 36*10465441SEvalZero 37*10465441SEvalZero return root_path 38*10465441SEvalZero 39*10465441SEvalZerodef CheckHeader(rtconfig, filename): 40*10465441SEvalZero root = GetGCCRoot(rtconfig) 41*10465441SEvalZero 42*10465441SEvalZero fn = os.path.join(root, 'include', filename) 43*10465441SEvalZero if os.path.isfile(fn): 44*10465441SEvalZero return True 45*10465441SEvalZero 46*10465441SEvalZero return False 47*10465441SEvalZero 48*10465441SEvalZerodef GetNewLibVersion(rtconfig): 49*10465441SEvalZero version = 'unknown' 50*10465441SEvalZero root = GetGCCRoot(rtconfig) 51*10465441SEvalZero 52*10465441SEvalZero if CheckHeader(rtconfig, '_newlib_version.h'): # get version from _newlib_version.h file 53*10465441SEvalZero f = open(os.path.join(root, 'include', '_newlib_version.h'), 'r') 54*10465441SEvalZero if f: 55*10465441SEvalZero for line in f: 56*10465441SEvalZero if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1: 57*10465441SEvalZero version = re.search(r'\"([^"]+)\"', line).groups()[0] 58*10465441SEvalZero f.close() 59*10465441SEvalZero elif CheckHeader(rtconfig, 'newlib.h'): # get version from newlib.h 60*10465441SEvalZero f = open(os.path.join(root, 'include', 'newlib.h'), 'r') 61*10465441SEvalZero if f: 62*10465441SEvalZero for line in f: 63*10465441SEvalZero if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1: 64*10465441SEvalZero version = re.search(r'\"([^"]+)\"', line).groups()[0] 65*10465441SEvalZero f.close() 66*10465441SEvalZero return version 67*10465441SEvalZero 68*10465441SEvalZerodef GCCResult(rtconfig, str): 69*10465441SEvalZero import subprocess 70*10465441SEvalZero 71*10465441SEvalZero result = '' 72*10465441SEvalZero 73*10465441SEvalZero def checkAndGetResult(pattern, string): 74*10465441SEvalZero if re.search(pattern, string): 75*10465441SEvalZero return re.search(pattern, string).group(0) 76*10465441SEvalZero return None 77*10465441SEvalZero 78*10465441SEvalZero gcc_cmd = os.path.join(rtconfig.EXEC_PATH, rtconfig.CC) 79*10465441SEvalZero 80*10465441SEvalZero # use temp file to get more information 81*10465441SEvalZero f = open('__tmp.c', 'w') 82*10465441SEvalZero if f: 83*10465441SEvalZero f.write(str) 84*10465441SEvalZero f.close() 85*10465441SEvalZero 86*10465441SEvalZero # '-fdirectives-only', 87*10465441SEvalZero if(platform.system() == 'Windows'): 88*10465441SEvalZero child = subprocess.Popen([gcc_cmd, '-E', '-P', '__tmp.c'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 89*10465441SEvalZero else: 90*10465441SEvalZero child = subprocess.Popen(gcc_cmd + ' -E -P __tmp.c', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 91*10465441SEvalZero 92*10465441SEvalZero stdout, stderr = child.communicate() 93*10465441SEvalZero 94*10465441SEvalZero # print(stdout) 95*10465441SEvalZero if stderr != '': 96*10465441SEvalZero print(stderr) 97*10465441SEvalZero 98*10465441SEvalZero have_fdset = 0 99*10465441SEvalZero have_sigaction = 0 100*10465441SEvalZero have_sigevent = 0 101*10465441SEvalZero have_siginfo = 0 102*10465441SEvalZero have_sigval = 0 103*10465441SEvalZero version = None 104*10465441SEvalZero stdc = '1989' 105*10465441SEvalZero posix_thread = 0 106*10465441SEvalZero 107*10465441SEvalZero for line in stdout.split(b'\n'): 108*10465441SEvalZero line = line.decode() 109*10465441SEvalZero if re.search('fd_set', line): 110*10465441SEvalZero have_fdset = 1 111*10465441SEvalZero 112*10465441SEvalZero # check for sigal 113*10465441SEvalZero if re.search('struct[ \t]+sigaction', line): 114*10465441SEvalZero have_sigaction = 1 115*10465441SEvalZero if re.search('struct[ \t]+sigevent', line): 116*10465441SEvalZero have_sigevent = 1 117*10465441SEvalZero if re.search('siginfo_t', line): 118*10465441SEvalZero have_siginfo = 1 119*10465441SEvalZero if re.search('union[ \t]+sigval', line): 120*10465441SEvalZero have_sigval = 1 121*10465441SEvalZero 122*10465441SEvalZero if re.search('char\* version', line): 123*10465441SEvalZero version = re.search(r'\"([^"]+)\"', line).groups()[0] 124*10465441SEvalZero 125*10465441SEvalZero if re.findall('iso_c_visible = [\d]+', line): 126*10465441SEvalZero stdc = re.findall('[\d]+', line)[0] 127*10465441SEvalZero 128*10465441SEvalZero if re.findall('pthread_create', line): 129*10465441SEvalZero posix_thread = 1 130*10465441SEvalZero 131*10465441SEvalZero if have_fdset: 132*10465441SEvalZero result += '#define HAVE_FDSET 1\n' 133*10465441SEvalZero 134*10465441SEvalZero if have_sigaction: 135*10465441SEvalZero result += '#define HAVE_SIGACTION 1\n' 136*10465441SEvalZero if have_sigevent: 137*10465441SEvalZero result += '#define HAVE_SIGEVENT 1\n' 138*10465441SEvalZero if have_siginfo: 139*10465441SEvalZero result += '#define HAVE_SIGINFO 1\n' 140*10465441SEvalZero if have_sigval: 141*10465441SEvalZero result += '#define HAVE_SIGVAL 1\n' 142*10465441SEvalZero 143*10465441SEvalZero if version: 144*10465441SEvalZero result += '#define GCC_VERSION "%s"\n' % version 145*10465441SEvalZero 146*10465441SEvalZero result += '#define STDC "%s"\n' % stdc 147*10465441SEvalZero 148*10465441SEvalZero if posix_thread: 149*10465441SEvalZero result += '#define LIBC_POSIX_THREADS 1\n' 150*10465441SEvalZero 151*10465441SEvalZero os.remove('__tmp.c') 152*10465441SEvalZero return result 153*10465441SEvalZero 154*10465441SEvalZerodef GenerateGCCConfig(rtconfig): 155*10465441SEvalZero str = '' 156*10465441SEvalZero cc_header = '' 157*10465441SEvalZero cc_header += '#ifndef CCONFIG_H__\n' 158*10465441SEvalZero cc_header += '#define CCONFIG_H__\n' 159*10465441SEvalZero cc_header += '/* Automatically generated file; DO NOT EDIT. */\n' 160*10465441SEvalZero cc_header += '/* compiler configure file for RT-Thread in GCC*/\n\n' 161*10465441SEvalZero 162*10465441SEvalZero if CheckHeader(rtconfig, 'newlib.h'): 163*10465441SEvalZero str += '#include <newlib.h>\n' 164*10465441SEvalZero cc_header += '#define HAVE_NEWLIB_H 1\n' 165*10465441SEvalZero cc_header += '#define LIBC_VERSION "newlib %s"\n\n' % GetNewLibVersion(rtconfig) 166*10465441SEvalZero 167*10465441SEvalZero if CheckHeader(rtconfig, 'sys/signal.h'): 168*10465441SEvalZero str += '#include <sys/signal.h>\n' 169*10465441SEvalZero cc_header += '#define HAVE_SYS_SIGNAL_H 1\n' 170*10465441SEvalZero if CheckHeader(rtconfig, 'sys/select.h'): 171*10465441SEvalZero str += '#include <sys/select.h>\n' 172*10465441SEvalZero cc_header += '#define HAVE_SYS_SELECT_H 1\n' 173*10465441SEvalZero if CheckHeader(rtconfig, 'pthread.h'): 174*10465441SEvalZero str += "#include <pthread.h>\n" 175*10465441SEvalZero cc_header += '#define HAVE_PTHREAD_H 1\n' 176*10465441SEvalZero 177*10465441SEvalZero # if CheckHeader(rtconfig, 'sys/dirent.h'): 178*10465441SEvalZero # str += '#include <sys/dirent.h>\n' 179*10465441SEvalZero 180*10465441SEvalZero # add some common features 181*10465441SEvalZero str += 'const char* version = __VERSION__;\n' 182*10465441SEvalZero str += 'const int iso_c_visible = __ISO_C_VISIBLE;\n' 183*10465441SEvalZero str += '\n#ifdef HAVE_INITFINI_ARRAY\n' 184*10465441SEvalZero str += 'const int init_fini_array = HAVE_INITFINI_ARRAY;\n' 185*10465441SEvalZero str += '#endif\n' 186*10465441SEvalZero 187*10465441SEvalZero cc_header += '\n' 188*10465441SEvalZero cc_header += GCCResult(rtconfig, str) 189*10465441SEvalZero cc_header += '\n#endif\n' 190*10465441SEvalZero 191*10465441SEvalZero cc_file = open('cconfig.h', 'w') 192*10465441SEvalZero if cc_file: 193*10465441SEvalZero cc_file.write(cc_header) 194*10465441SEvalZero cc_file.close() 195