2018-05-30 20:58:04 +08:00
|
|
|
#
|
|
|
|
# File : gcc.py
|
|
|
|
# This file is part of RT-Thread RTOS
|
|
|
|
# COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along
|
|
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
#
|
|
|
|
# Change Logs:
|
|
|
|
# Date Author Notes
|
|
|
|
# 2018-05-22 Bernard The first version
|
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
import os
|
|
|
|
import re
|
2020-02-07 15:55:53 +08:00
|
|
|
import platform
|
2018-05-14 21:37:11 +08:00
|
|
|
|
|
|
|
def GetGCCRoot(rtconfig):
|
|
|
|
exec_path = rtconfig.EXEC_PATH
|
|
|
|
prefix = rtconfig.PREFIX
|
|
|
|
|
|
|
|
if prefix.endswith('-'):
|
|
|
|
prefix = prefix[:-1]
|
|
|
|
|
2019-08-28 16:52:58 +08:00
|
|
|
if exec_path == '/usr/bin':
|
|
|
|
root_path = os.path.join('/usr/lib', prefix)
|
|
|
|
else:
|
|
|
|
root_path = os.path.join(exec_path, '..', prefix)
|
2018-05-14 21:37:11 +08:00
|
|
|
|
2019-09-11 09:53:38 +08:00
|
|
|
return root_path
|
|
|
|
|
|
|
|
def CheckHeader(rtconfig, filename):
|
|
|
|
root = GetGCCRoot(rtconfig)
|
|
|
|
|
|
|
|
fn = os.path.join(root, 'include', filename)
|
|
|
|
if os.path.isfile(fn):
|
|
|
|
return True
|
|
|
|
|
2019-09-11 09:03:59 +08:00
|
|
|
# Usually the cross compiling gcc toolchain has directory as:
|
|
|
|
#
|
|
|
|
# bin
|
|
|
|
# lib
|
|
|
|
# share
|
|
|
|
# arm-none-eabi
|
|
|
|
# bin
|
|
|
|
# include
|
|
|
|
# lib
|
|
|
|
# share
|
|
|
|
prefix = rtconfig.PREFIX
|
|
|
|
if prefix.endswith('-'):
|
|
|
|
prefix = prefix[:-1]
|
|
|
|
|
|
|
|
fn = os.path.join(root, prefix, 'include', filename)
|
|
|
|
if os.path.isfile(fn):
|
|
|
|
return True
|
2020-02-07 15:55:53 +08:00
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
return False
|
|
|
|
|
2023-08-21 01:26:39 +08:00
|
|
|
# GCC like means the toolchains which are compatible with GCC
|
|
|
|
def GetGCCLikePLATFORM():
|
|
|
|
return ['gcc', 'armclang', 'llvm-arm']
|
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
def GetNewLibVersion(rtconfig):
|
2023-04-30 12:19:57 +08:00
|
|
|
version = None
|
2023-09-15 09:45:39 +08:00
|
|
|
|
|
|
|
try:
|
|
|
|
rtconfig.PREFIX
|
|
|
|
except:
|
|
|
|
return version
|
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
root = GetGCCRoot(rtconfig)
|
|
|
|
if CheckHeader(rtconfig, '_newlib_version.h'): # get version from _newlib_version.h file
|
2018-11-07 13:38:57 +08:00
|
|
|
f = open(os.path.join(root, 'include', '_newlib_version.h'), 'r')
|
2018-05-14 21:37:11 +08:00
|
|
|
if f:
|
|
|
|
for line in f:
|
|
|
|
if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1:
|
|
|
|
version = re.search(r'\"([^"]+)\"', line).groups()[0]
|
2018-11-07 13:40:41 +08:00
|
|
|
f.close()
|
2018-05-14 21:37:11 +08:00
|
|
|
elif CheckHeader(rtconfig, 'newlib.h'): # get version from newlib.h
|
2018-11-07 13:38:57 +08:00
|
|
|
f = open(os.path.join(root, 'include', 'newlib.h'), 'r')
|
2018-05-14 21:37:11 +08:00
|
|
|
if f:
|
|
|
|
for line in f:
|
|
|
|
if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1:
|
|
|
|
version = re.search(r'\"([^"]+)\"', line).groups()[0]
|
2018-11-07 13:40:41 +08:00
|
|
|
f.close()
|
2018-05-14 21:37:11 +08:00
|
|
|
return version
|
|
|
|
|
2022-11-23 10:40:50 +08:00
|
|
|
# FIXME: there is no musl version or musl macros can be found officially
|
|
|
|
def GetMuslVersion(rtconfig):
|
2023-04-30 12:19:57 +08:00
|
|
|
version = None
|
2023-09-15 09:45:39 +08:00
|
|
|
|
|
|
|
try:
|
|
|
|
rtconfig.PREFIX
|
|
|
|
except:
|
|
|
|
return version
|
|
|
|
|
2023-04-30 12:19:57 +08:00
|
|
|
if 'musl' in rtconfig.PREFIX:
|
|
|
|
version = 'unknown'
|
2022-11-23 10:40:50 +08:00
|
|
|
return version
|
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
def GCCResult(rtconfig, str):
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
result = ''
|
|
|
|
|
|
|
|
def checkAndGetResult(pattern, string):
|
|
|
|
if re.search(pattern, string):
|
|
|
|
return re.search(pattern, string).group(0)
|
|
|
|
return None
|
|
|
|
|
|
|
|
gcc_cmd = os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)
|
|
|
|
|
2020-02-07 15:55:53 +08:00
|
|
|
# use temp file to get more information
|
2018-11-07 13:38:57 +08:00
|
|
|
f = open('__tmp.c', 'w')
|
2018-05-14 21:37:11 +08:00
|
|
|
if f:
|
|
|
|
f.write(str)
|
|
|
|
f.close()
|
|
|
|
|
2020-02-07 15:55:53 +08:00
|
|
|
# '-fdirectives-only',
|
2018-05-17 16:45:16 +08:00
|
|
|
if(platform.system() == 'Windows'):
|
|
|
|
child = subprocess.Popen([gcc_cmd, '-E', '-P', '__tmp.c'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
|
|
else:
|
|
|
|
child = subprocess.Popen(gcc_cmd + ' -E -P __tmp.c', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
2020-02-07 15:55:53 +08:00
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
stdout, stderr = child.communicate()
|
|
|
|
|
2018-05-22 11:32:48 +08:00
|
|
|
# print(stdout)
|
2022-02-23 20:45:27 +08:00
|
|
|
if stderr != '' and stderr != b'':
|
2018-05-14 21:37:11 +08:00
|
|
|
print(stderr)
|
|
|
|
|
|
|
|
have_fdset = 0
|
|
|
|
have_sigaction = 0
|
|
|
|
have_sigevent = 0
|
|
|
|
have_siginfo = 0
|
|
|
|
have_sigval = 0
|
|
|
|
version = None
|
|
|
|
stdc = '1989'
|
|
|
|
posix_thread = 0
|
|
|
|
|
2018-11-07 13:38:57 +08:00
|
|
|
for line in stdout.split(b'\n'):
|
2018-11-10 18:29:08 +08:00
|
|
|
line = line.decode()
|
|
|
|
if re.search('fd_set', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
have_fdset = 1
|
|
|
|
|
|
|
|
# check for sigal
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.search('struct[ \t]+sigaction', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
have_sigaction = 1
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.search('struct[ \t]+sigevent', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
have_sigevent = 1
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.search('siginfo_t', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
have_siginfo = 1
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.search('union[ \t]+sigval', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
have_sigval = 1
|
|
|
|
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.search('char\* version', line):
|
|
|
|
version = re.search(r'\"([^"]+)\"', line).groups()[0]
|
2018-05-14 21:37:11 +08:00
|
|
|
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.findall('iso_c_visible = [\d]+', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
stdc = re.findall('[\d]+', line)[0]
|
|
|
|
|
2018-11-10 18:29:08 +08:00
|
|
|
if re.findall('pthread_create', line):
|
2018-05-14 21:37:11 +08:00
|
|
|
posix_thread = 1
|
2020-02-07 15:55:53 +08:00
|
|
|
|
2018-05-14 21:37:11 +08:00
|
|
|
if have_fdset:
|
|
|
|
result += '#define HAVE_FDSET 1\n'
|
|
|
|
|
|
|
|
if have_sigaction:
|
|
|
|
result += '#define HAVE_SIGACTION 1\n'
|
|
|
|
if have_sigevent:
|
|
|
|
result += '#define HAVE_SIGEVENT 1\n'
|
|
|
|
if have_siginfo:
|
|
|
|
result += '#define HAVE_SIGINFO 1\n'
|
|
|
|
if have_sigval:
|
|
|
|
result += '#define HAVE_SIGVAL 1\n'
|
|
|
|
|
|
|
|
if version:
|
2020-02-07 15:55:53 +08:00
|
|
|
result += '#define GCC_VERSION_STR "%s"\n' % version
|
2018-05-14 21:37:11 +08:00
|
|
|
|
|
|
|
result += '#define STDC "%s"\n' % stdc
|
|
|
|
|
|
|
|
if posix_thread:
|
|
|
|
result += '#define LIBC_POSIX_THREADS 1\n'
|
|
|
|
|
|
|
|
os.remove('__tmp.c')
|
|
|
|
return result
|