diff options
| author | Bernard Xiong <[email protected]> | 2018-05-14 21:37:11 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2018-05-14 21:37:11 +0800 |
| commit | 6ac213d62275676c1ba79039c6fd2683e2877662 (patch) | |
| tree | 0ddc8744bd9173c390a42456f78a6da50d3a313e /tools | |
| parent | ab33cd3110a4b303c7c934f3da84f9c64c4ebb73 (diff) | |
Add GCC version detection.
Add cconfig.h file for different version of GCC, which is automatically
detected and generated by scons script.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/building.py | 34 | ||||
| -rw-r--r-- | tools/gcc.py | 165 |
2 files changed, 194 insertions, 5 deletions
diff --git a/tools/building.py b/tools/building.py index 1a49d3c3a0..22350b28b7 100644 --- a/tools/building.py +++ b/tools/building.py @@ -74,7 +74,6 @@ PatchedPreProcessor = SCons.cpp.PreProcessor PatchedPreProcessor.start_handling_includes = start_handling_includes PatchedPreProcessor.stop_handling_includes = stop_handling_includes - class Win32Spawn: def spawn(self, sh, escape, cmd, args, env): # deal with the cmd build-in commands which cannot be used in @@ -141,10 +140,6 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ env['LIBLINKSUFFIX'] = '.lib' env['LIBDIRPREFIX'] = '--userlibpath ' - if rtconfig.PLATFORM == 'gcc': - if str(env['LINKFLAGS']).find('nano.specs'): - env.AppendUnique(CPPDEFINES = ['_REENT_SMALL']) - # patch for win32 spawn if env['PLATFORM'] == 'win32': win32_spawn = Win32Spawn() @@ -174,6 +169,31 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [ PreProcessor.process_contents(contents) BuildOptions = PreProcessor.cpp_namespace + if rtconfig.PLATFORM == 'gcc': + contents = '' + if not os.path.isfile('cconfig.h'): + import gcc + gcc.GenerateGCCConfig(rtconfig) + + # try again + if os.path.isfile('cconfig.h'): + f = file('cconfig.h', 'r') + if f: + contents = f.read() + f.close(); + + prep = PatchedPreProcessor() + prep.process_contents(contents) + options = prep.cpp_namespace + + BuildOptions.update(options) + + # add HAVE_CCONFIG_H definition + env.AppendUnique(CPPDEFINES = ['HAVE_CCONFIG_H']) + + if str(env['LINKFLAGS']).find('nano.specs') != -1: + env.AppendUnique(CPPDEFINES = ['_REENT_SMALL']) + # add copy option AddOption('--copy', dest='copy', @@ -673,6 +693,10 @@ def EndBuilding(target, program = None): import rtconfig Env.AddPostAction(target, rtconfig.POST_ACTION) + # Add addition clean files + Clean(target, 'cconfig.h') + Clean(target, 'rtua.py') + Clean(target, 'rtua.pyc') if GetOption('target') == 'mdk': from keil import MDKProject diff --git a/tools/gcc.py b/tools/gcc.py new file mode 100644 index 0000000000..bfa0ca4173 --- /dev/null +++ b/tools/gcc.py @@ -0,0 +1,165 @@ +import os +import re + +def GetGCCRoot(rtconfig): + exec_path = rtconfig.EXEC_PATH + prefix = rtconfig.PREFIX + + if prefix.endswith('-'): + prefix = prefix[:-1] + + root_path = os.path.join(exec_path, '..', prefix) + + return root_path + +def CheckHeader(rtconfig, filename): + root = GetGCCRoot(rtconfig) + + fn = os.path.join(root, 'include', filename) + if os.path.isfile(fn): + return True + + return False + +def GetNewLibVersion(rtconfig): + version = 'unknown' + root = GetGCCRoot(rtconfig) + + if CheckHeader(rtconfig, '_newlib_version.h'): # get version from _newlib_version.h file + f = file(os.path.join(root, 'include', '_newlib_version.h')) + if f: + for line in f: + if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1: + version = re.search(r'\"([^"]+)\"', line).groups()[0] + elif CheckHeader(rtconfig, 'newlib.h'): # get version from newlib.h + f = file(os.path.join(root, 'include', 'newlib.h')) + if f: + for line in f: + if line.find('_NEWLIB_VERSION') != -1 and line.find('"') != -1: + version = re.search(r'\"([^"]+)\"', line).groups()[0] + + return version + +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) + + # use temp file to get more information + f = file('__tmp.c', 'w') + if f: + f.write(str) + f.close() + + # '-fdirectives-only', + child = subprocess.Popen([gcc_cmd, '-E', '-P', '__tmp.c'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + stdout, stderr = child.communicate() + + print(stdout) + if stderr != '': + print(stderr) + + have_fdset = 0 + have_sigaction = 0 + have_sigevent = 0 + have_siginfo = 0 + have_sigval = 0 + version = None + stdc = '1989' + posix_thread = 0 + + for line in stdout.split('\n'): + if re.search('fd_set', line): + have_fdset = 1 + + # check for sigal + if re.search('struct[ \t]+sigaction', line): + have_sigaction = 1 + if re.search('struct[ \t]+sigevent', line): + have_sigevent = 1 + if re.search('siginfo_t', line): + have_siginfo = 1 + if re.search('union[ \t]+sigval', line): + have_sigval = 1 + + if re.search('char\* version', line): + version = re.search(r'\"([^"]+)\"', line).groups()[0] + + if re.findall('iso_c_visible = [\d]+', line): + stdc = re.findall('[\d]+', line)[0] + + if re.findall('pthread_create', line): + posix_thread = 1 + + 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: + result += '#define GCC_VERSION "%s"\n' % version + + result += '#define STDC "%s"\n' % stdc + + if posix_thread: + result += '#define LIBC_POSIX_THREADS 1\n' + + os.remove('__tmp.c') + + return result + +def GenerateGCCConfig(rtconfig): + str = '' + cc_header = '' + cc_header += '#ifndef CCONFIG_H__\n' + cc_header += '#define CCONFIG_H__\n' + cc_header += '/* Automatically generated file; DO NOT EDIT. */\n' + cc_header += '/* compiler configure file for RT-Thread in GCC*/\n\n' + + if CheckHeader(rtconfig, 'newlib.h'): + str += '#include <newlib.h>\n' + cc_header += '#define HAVE_NEWLIB_H 1\n' + cc_header += '#define LIBC_VERSION "newlib %s"\n\n' % GetNewLibVersion(rtconfig) + + if CheckHeader(rtconfig, 'sys/signal.h'): + str += '#include <sys/signal.h>\n' + cc_header += '#define HAVE_SYS_SIGNAL_H 1\n' + if CheckHeader(rtconfig, 'sys/select.h'): + str += '#include <sys/select.h>\n' + cc_header += '#define HAVE_SYS_SELECT_H 1\n' + if CheckHeader(rtconfig, 'pthread.h'): + str += "#include <pthread.h>\n" + cc_header += '#define HAVE_PTHREAD_H 1\n' + + # if CheckHeader(rtconfig, 'sys/dirent.h'): + # str += '#include <sys/dirent.h>\n' + + # add some common features + str += 'const char* version = __VERSION__;\n' + str += 'const int iso_c_visible = __ISO_C_VISIBLE;\n' + str += '\n#ifdef HAVE_INITFINI_ARRAY\n' + str += 'const int init_fini_array = HAVE_INITFINI_ARRAY;\n' + str += '#endif\n' + + cc_header += '\n' + cc_header += GCCResult(rtconfig, str) + cc_header += '\n#endif\n' + + cc_file = file('cconfig.h', 'w') + if cc_file: + cc_file.write(cc_header) + cc_file.close() |
