Browse Source

Merge pull request #1434 from RT-Thread/gcc_detection

Add GCC version detection.
Bernard Xiong 7 years ago
parent
commit
352b31a9dc

+ 0 - 14
components/dfs/Kconfig

@@ -103,20 +103,6 @@ if RT_USING_DFS
         help
         help
             Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
             Let BSD socket operated by file system API, such as read/write and involveed in select/poll POSIX APIs.
 
 
-    if RT_USING_DFS_NET
-        config HAVE_SYS_SELECT_H
-            bool "Toolchains/libc have provided sys/select.h"
-            default n
-            help
-                Toolchains/libc have provided sys/select.h file, therefore, disable the sys/select.h in RT-Thread.
-
-        config HAVE_SYS_SOCKET_H
-            bool "Toolchains/libc have provided sys/socket.h"
-            default n
-            help
-                Toolchains/libc have provided sys/socket.h file, therefore, disable the sys/socket.h in RT-Thread.
-    endif
-
     config RT_USING_DFS_ROMFS
     config RT_USING_DFS_ROMFS
         bool "Enable ReadOnly file system on flash"
         bool "Enable ReadOnly file system on flash"
         default n
         default n

+ 0 - 6
components/libc/Kconfig

@@ -35,10 +35,4 @@ if RT_USING_LIBC && RT_USING_DFS
     endif
     endif
 endif
 endif
 
 
-config HAVE_SYS_SIGNALS
-    bool "Toolchains/libc has sigval/sigevent structure definitions"
-    default n
-    help
-        Toolchains/libc has sigval/sigevent/siginfo_t definitions.
-
 endmenu
 endmenu

+ 6 - 0
components/libc/compilers/armlibc/SConscript

@@ -8,6 +8,12 @@ group = []
 CPPPATH = [cwd]
 CPPPATH = [cwd]
 CPPDEFINES = ['RT_USING_ARM_LIBC']
 CPPDEFINES = ['RT_USING_ARM_LIBC']
 
 
+if GetDepend('RT_USING_DFS') == False:
+    SrcRemove(src, ['stdio.c'])
+
+if GetDepend('RT_USING_MODULE') == False:
+    SrcRemove(src, ['libc_syms.c'])
+
 if rtconfig.PLATFORM == 'armcc':
 if rtconfig.PLATFORM == 'armcc':
     group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], 
     group = DefineGroup('libc', src, depend = ['RT_USING_LIBC'], 
         CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
         CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)

+ 11 - 5
include/libc/libc_signal.h

@@ -25,12 +25,15 @@
 #ifndef LIBC_SIGNAL_H__
 #ifndef LIBC_SIGNAL_H__
 #define LIBC_SIGNAL_H__
 #define LIBC_SIGNAL_H__
 
 
-
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
 #endif
 #endif
 
 
-#ifndef HAVE_SYS_SIGNALS
+#ifdef HAVE_CCONFIG_H
+#include <cconfig.h>
+#endif
+
+#ifndef HAVE_SIGVAL
 /*  Signal Generation and Delivery, P1003.1b-1993, p. 63
 /*  Signal Generation and Delivery, P1003.1b-1993, p. 63
     NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
     NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and
           sigev_notify_attributes to the sigevent structure.  */
           sigev_notify_attributes to the sigevent structure.  */
@@ -40,7 +43,9 @@ union sigval
     int    sival_int;    /* Integer signal value */
     int    sival_int;    /* Integer signal value */
     void  *sival_ptr;    /* Pointer signal value */
     void  *sival_ptr;    /* Pointer signal value */
 };
 };
+#endif
 
 
+#ifndef HAVE_SIGEVENT
 struct sigevent
 struct sigevent
 {
 {
     int          sigev_notify;               /* Notification type */
     int          sigev_notify;               /* Notification type */
@@ -50,12 +55,13 @@ struct sigevent
                                              /* Notification function */
                                              /* Notification function */
     void         *sigev_notify_attributes;   /* Notification Attributes, really pthread_attr_t */
     void         *sigev_notify_attributes;   /* Notification Attributes, really pthread_attr_t */
 };
 };
+#endif
 
 
+#ifndef HAVE_SIGINFO
 struct siginfo
 struct siginfo
 {
 {
-    rt_uint8_t si_signo;
-    rt_uint8_t si_code;
-    rt_int16_t si_errno;
+    rt_uint16_t si_signo;
+    rt_uint16_t si_code;
 
 
     union sigval si_value;
     union sigval si_value;
 };
 };

+ 2 - 3
src/signal.c

@@ -45,7 +45,7 @@
 
 
 struct siginfo_node
 struct siginfo_node
 {
 {
-    struct siginfo si;
+    siginfo_t si;
     struct rt_slist_node list;
     struct rt_slist_node list;
 };
 };
 
 
@@ -339,7 +339,7 @@ void rt_thread_handle_sig(rt_bool_t clean_state)
 
 
                 level = rt_hw_interrupt_disable();
                 level = rt_hw_interrupt_disable();
                 tid->sig_pending &= ~sig_mask(signo);
                 tid->sig_pending &= ~sig_mask(signo);
-                error = si_node->si.si_errno;
+                error = -RT_EINTR;
 
 
                 rt_mp_free(si_node); /* release this siginfo node */
                 rt_mp_free(si_node); /* release this siginfo node */
                 /* set errno in thread tcb */
                 /* set errno in thread tcb */
@@ -419,7 +419,6 @@ int rt_thread_kill(rt_thread_t tid, int sig)
     if (!sig_valid(sig)) return -RT_EINVAL;
     if (!sig_valid(sig)) return -RT_EINVAL;
 
 
     dbg_log(DBG_INFO, "send signal: %d\n", sig);
     dbg_log(DBG_INFO, "send signal: %d\n", sig);
-    si.si_errno = RT_EINTR;
     si.si_signo = sig;
     si.si_signo = sig;
     si.si_code  = SI_USER;
     si.si_code  = SI_USER;
     si.si_value.sival_ptr = RT_NULL;
     si.si_value.sival_ptr = RT_NULL;

+ 29 - 5
tools/building.py

@@ -74,7 +74,6 @@ PatchedPreProcessor = SCons.cpp.PreProcessor
 PatchedPreProcessor.start_handling_includes = start_handling_includes
 PatchedPreProcessor.start_handling_includes = start_handling_includes
 PatchedPreProcessor.stop_handling_includes = stop_handling_includes
 PatchedPreProcessor.stop_handling_includes = stop_handling_includes
 
 
-
 class Win32Spawn:
 class Win32Spawn:
     def spawn(self, sh, escape, cmd, args, env):
     def spawn(self, sh, escape, cmd, args, env):
         # deal with the cmd build-in commands which cannot be used in
         # 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['LIBLINKSUFFIX']   = '.lib'
         env['LIBDIRPREFIX'] = '--userlibpath '
         env['LIBDIRPREFIX'] = '--userlibpath '
 
 
-    if rtconfig.PLATFORM == 'gcc':
-        if str(env['LINKFLAGS']).find('nano.specs'):
-            env.AppendUnique(CPPDEFINES = ['_REENT_SMALL'])
-
     # patch for win32 spawn
     # patch for win32 spawn
     if env['PLATFORM'] == 'win32':
     if env['PLATFORM'] == 'win32':
         win32_spawn = Win32Spawn()
         win32_spawn = Win32Spawn()
@@ -174,6 +169,31 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
     PreProcessor.process_contents(contents)
     PreProcessor.process_contents(contents)
     BuildOptions = PreProcessor.cpp_namespace
     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
     # add copy option
     AddOption('--copy',
     AddOption('--copy',
                       dest='copy',
                       dest='copy',
@@ -673,6 +693,10 @@ def EndBuilding(target, program = None):
     import rtconfig
     import rtconfig
 
 
     Env.AddPostAction(target, rtconfig.POST_ACTION)
     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':
     if GetOption('target') == 'mdk':
         from keil import MDKProject
         from keil import MDKProject

+ 165 - 0
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()