conf = env.Configure(
custom_tests = {
+ 'CheckC99Flags' : iotivityconfig.check_c99_flags,
'CheckCXX11Flags' : iotivityconfig.check_cxx11_flags
} )
+# IoTivity requires support for C99 for the C SDK.
+if not conf.CheckC99Flags():
+ print('C99 support is required!')
+ Exit(1)
+
# IoTivity requires support for C++11 for the C++ SDK.
#
# However, some platforms, such as Arduino, only support the C SDK.
# handle the issue in that case.
_check_for_broken_gcc_headers(context, flag)
+def check_c99_flags(context):
+ """
+ Check if command line flag is required to enable C99 support.
+
+ Returns 1 if no flag is required, 0 if no flag was found, or the
+ actual flag if one was found.
+ """
+
+ cc = context.env['CC']
+ context.Message('Checking for C99 flag for ' + cc + '... ')
+ config = factory.make_c_compiler_config(context)
+ ret = config.check_c99_flags()
+ context.Result(ret)
+
+ return ret
+
def check_cxx11_flags(context):
"""
Check if command line flag is required to enable C++11 support.
cxx = context.env['CXX']
context.Message('Checking for C++11 flag for ' + cxx + '... ')
- config = factory.make_compiler_config(context)
+ config = factory.make_cxx_compiler_config(context)
ret = config.check_cxx11_flags()
context.Result(ret)
self._context = context # scons configure context
self._env = context.env # scons environment
+ def check_c99_flags(self):
+ """
+ Check if command line flag is required to enable C99
+ support.
+
+ Returns 1 if no flag is required, 0 if no flag was
+ found, and the actual flag if one was found.
+
+ CFLAGS will be updated with appropriate C99 flag,
+ accordingly.
+ """
+
+ return self._check_flags(self._c99_flags(),
+ self._c99_test_program(),
+ '.c',
+ 'CFLAGS')
+
def check_cxx11_flags(self):
"""
Check if command line flag is required to enable C++11
return ret
# ------------------------------------------------------------
+ # Return test program to be used when checking for basic C99
+ # support.
+ #
+ # Subclasses should implement this template method or use the
+ # default test program found in the DefaultConfiguration class
+ # through composition.
+ # ------------------------------------------------------------
+ def _c99_test_program(self):
+ raise NotImplementedError('unimplemented method')
+
+ # --------------------------------------------------------------
+ # Get list of flags that could potentially enable C99 support.
+ #
+ # Subclasses should implement this template method if flags are
+ # needed to enable C99 support.
+ # --------------------------------------------------------------
+ def _c99_flags(self):
+ raise NotImplementedError('unimplemented method')
+
+ # ------------------------------------------------------------
# Return test program to be used when checking for basic C++11
# support.
#
# Subclasses should implement this template method or use the
# default test program found in the DefaultConfiguration class
- # through inheritance or composition.
+ # through composition.
# ------------------------------------------------------------
def _cxx11_test_program(self):
raise NotImplementedError('unimplemented method')
# Return test program to be used when checking for basic C++11
# support.
# ------------------------------------------------------------
+ def _c99_test_program(self):
+ return """
+// Some headers found in C99.
+#include <stdbool.h>
+#include <stdint.h>
+
+int main()
+{
+ struct foo
+ {
+ bool b; // C99 type
+ int i;
+ uint64_t q; // C99 type
+ };
+
+ // Designated initializer.
+ struct foo bar = { .b = false, .q = UINT64_MAX };
+
+ // Implicitly initialized field.
+ return bar.i != 0;
+}
+"""
+
+ # --------------------------------------------------------------
+ # Get list of flags that could potentially enable C99 support.
+ #
+ # The default configuration assumes that no flag is needed to
+ # enable C99 support.
+ # --------------------------------------------------------------
+ def _c99_flags(self):
+ return []
+
+ # ------------------------------------------------------------
+ # Return test program to be used when checking for basic C++11
+ # support.
+ # ------------------------------------------------------------
def _cxx11_test_program(self):
return """
int main()
from default_configuration import *
from gcc_configuration import *
-# Canonicalize the C++ compiler name to "g++" if gcc is being used to
-# simplify mapping to the appropriate C++11 flags since gcc may be
-# installed under a different name. This will be used when mapping
-# compiler name to configuration in the factory submodule.
-_GCC = 'g++'
+# Canonicalize the C or C++ compiler name to "gcc" if gcc is being
+# used to simplify mapping to the GCC compiler configuration since GCC
+# may be installed under a different name. This will be used when
+# mapping compiler name to configuration in the factory submodule.
+_GCC = 'gcc'
# Update this dictionary with new compiler configurations as needed.
_CONFIG_MAP = { _GCC : GccConfiguration }
-_compiler_config = None
+_c_compiler_config = None
+_cxx_compiler_config = None
+
+def check_for_gcc_c(context):
+ """
+ Check if the C compiler is GCC
+
+ Returns 1 if gcc, 0 otherwise
+ """
+
+ test_program = """
+#if !defined(__GNUC__)
+# error "Not the GCC C compiler."
+#endif
+
+int foo(void)
+{
+ return 0;
+}
+"""
+
+ return context.TryCompile(test_program, '.c')
def check_for_gcc_cxx(context):
"""
return context.TryCompile(test_program, '.cpp')
-def make_compiler_config(context):
+def make_c_compiler_config(context):
+ """
+ Create C compiler-specific configuration object.
+
+ Arguments:
+ context -- the scons configure context
+
+ The 'CC' key in the SCons environment will be mapped to the
+ appropriate supported compiler configuration. If no match is
+ found compiler configuration operations will simply be no-ops.
+ """
+
+ global _c_compiler_config
+
+ if _c_compiler_config is None:
+ cc = context.env['CC']
+
+ if check_for_gcc_c(context):
+ cc = _GCC
+
+ config = _CONFIG_MAP.get(cc, DefaultConfiguration)
+
+ _c_compiler_config = config(context)
+
+ return _c_compiler_config
+
+def make_cxx_compiler_config(context):
"""
- Create compiler-specific configuration object.
+ Create C++ compiler-specific configuration object.
Arguments:
context -- the scons configure context
found compiler configuration operations will simply be no-ops.
"""
- global _compiler_config
+ global _cxx_compiler_config
- if _compiler_config is None:
+ if _cxx_compiler_config is None:
cxx = context.env['CXX']
if check_for_gcc_cxx(context):
config = _CONFIG_MAP.get(cxx, DefaultConfiguration)
- _compiler_config = config(context)
+ _cxx_compiler_config = config(context)
- return _compiler_config
+ return _cxx_compiler_config
Configuration.__init__(self, context)
# ------------------------------------------------------------
+ # Return test program to be used when checking for basic C99
+ # support in GCC.
+ # ------------------------------------------------------------
+ def _c99_test_program(self):
+ # Use the default C99 test program but enable pedantic
+ # diagnostics specific to GCC to force errors to occur if a
+ # flag is required to compile C99 code without warning or
+ # error.
+
+ from default_configuration import DefaultConfiguration
+ def_config = DefaultConfiguration(self._context)
+
+ return """
+#pragma GCC diagnostic error "-Wall"
+#pragma GCC diagnostic error "-Werror"
+#pragma GCC diagnostic error "-pedantic"
+""" + def_config._c99_test_program()
+
+ # -------------------------------------------------------------
+ # Get flags known to enable C99 support for GCC C compiler.
+ # -------------------------------------------------------------
+ def _c99_flags(self):
+ # Favor flags that do not enable GNU extensions by default,
+ # e.g. '-std=c99'.
+ return [ '-std=c99',
+ '-std=iso9899:1999',
+ '-std=gnu99',
+ '-std=c9x',
+ '-std=iso9899:199x',
+ '-std=gnu9x' ]
+
+ # ------------------------------------------------------------
# Return test program to be used when checking for basic C++11
# support in GCC.
# ------------------------------------------------------------
if target_os not in ['arduino', 'windows', 'winrt']:
liboctbstack_env.AppendUnique(CPPDEFINES = ['WITH_POSIX'])
- liboctbstack_env.AppendUnique(CFLAGS = ['-std=c99'])
if target_os not in ['windows', 'winrt']:
liboctbstack_env.AppendUnique(CFLAGS = ['-Wall'])
])
if target_os not in ['arduino', 'windows', 'winrt']:
- libcoap_env.AppendUnique(CPPDEFINES = ['WITH_POSIX'])
- libcoap_env.AppendUnique(CFLAGS = ['-std=gnu99'])
+ libcoap_env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '_BSD_SOURCE'])
if target_os not in ['windows', 'winrt']:
libcoap_env.AppendUnique(CFLAGS = ['-Wall', '-ffunction-sections',
liboc_logger_env.AppendUnique(LIBS = ['gnustl_shared', 'log'])
if target_os not in ['arduino', 'windows', 'winrt']:
- liboc_logger_env.AppendUnique(CFLAGS = ['-std=c99'])
liboc_logger_env.AppendUnique(CCFLAGS = ['-Wall'])
######################################################################
examples_env.AppendUnique(LIBS = ['gnustl_shared'])
if target_os not in ['arduino', 'windows', 'winrt']:
- examples_env.AppendUnique(CFLAGS = Split('-Wall -std=c99 -Werror'))
+ examples_env.AppendUnique(CFLAGS = Split('-Wall -Werror'))
examples_env.AppendUnique(CXXFLAGS = '-Wall')
######################################################################
######################################################################
mosquitto_env.AppendUnique(CPPPATH = ['./'])
if target_os not in ['windows', 'winrt']:
+ # strdup() and pselect() require specific extensions to be enabled.
+ mosquitto_env.AppendUnique(CPPDEFINES = [('_XOPEN_SOURCE', 600)])
mosquitto_env.AppendUnique(CFLAGS = ['-Wall', '-ggdb', '-fPIC',
'-DWITH_TLS', '-DWITH_TLS_PSK', '-DWITH_THREADING'])
######################################################################
#include <stdio.h>
#include <string.h>
#ifndef WIN32
+#include <strings.h> /* for strcasecmp() */
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>