xref: /nrf52832-nimble/rt-thread/tools/gcc.py (revision 104654410c56c573564690304ae786df310c91fc)
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