Rework configure stuff
g0dil [Wed, 11 Aug 2010 12:18:53 +0000 (12:18 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1672 270642c3-0616-0410-b53a-bc976706d245

SConstruct
senf/Scheduler/Scheduler.cc
senf/Scheduler/Scheduler.cci
senf/Scheduler/TimerSource.cc
senf/Scheduler/TimerSource.hh
senf/config.hh
site_scons/senfconf.py
site_scons/senfutil.py

index ec88386..584c321 100644 (file)
@@ -176,14 +176,12 @@ def CheckValgrindWildcards(context):
     context.Result( ret[0] )
     return ret[0]
 
-# Default configuration (boost stuff)
-senfutil.Configure(env)
+def customChecks(conf):
+    conf.env.Replace(
+        HAVE_VALGRIND  = conf.CheckValgrind() and conf.CheckValgrindWildcards()
+        )
 
-conf = env.Configure(clean=False, help=False, custom_tests = senfconf.Tests())
-env.Replace(
-    HAVE_VALGRIND  = conf.CheckValgrind() and conf.CheckValgrindWildcards()
-)
-conf.Finish()
+senfutil.Configure(env, customChecks)
 
 # Only add this here, after all configure checks have run
 
index fe32596..b90ef66 100644 (file)
@@ -149,7 +149,7 @@ prefix_ bool senf::scheduler::empty()
 
 prefix_ void senf::scheduler::hiresTimers()
 {
-#ifdef HAVE_TIMERFD
+#ifdef HAVE_TIMERFD_CREATE
     if (haveScalableHiresTimers())
         detail::TimerDispatcher::instance().timerSource(
             std::auto_ptr<detail::TimerSource>(new detail::TimerFDTimerSource()));
index 873b64f..eba3cb3 100644 (file)
@@ -72,7 +72,7 @@ prefix_ void senf::scheduler::loresTimers()
 
 prefix_ bool senf::scheduler::haveScalableHiresTimers()
 {
-#ifndef HAVE_TIMERFD
+#ifndef HAVE_TIMERFD_CREATE
     return false;
 #else
     return detail::TimerFDTimerSource::haveTimerFD();
index 55d6216..dea043b 100644 (file)
@@ -28,7 +28,7 @@
 
 // Custom includes
 #include "IdleEvent.hh"
-#ifdef HAVE_TIMERFD
+#ifdef HAVE_TIMERFD_CREATE
 #include <sys/timerfd.h>
 #endif
 #include "senf/Utils/IgnoreValue.hh"
@@ -178,7 +178,7 @@ prefix_ void senf::scheduler::detail::PollTimerSource::disable()
 ///////////////////////////////////////////////////////////////////////////
 // senf::scheduler::detail::TimerFDTimerSource
 
-#ifdef HAVE_TIMERFD
+#ifdef HAVE_TIMERFD_CREATE
 prefix_ senf::scheduler::detail::TimerFDTimerSource::TimerFDTimerSource()
     : timerfd_ (-1), timeoutEnabled_ (false), timeout_ (0)
 {
index 8c4cbef..2acdce3 100644 (file)
@@ -92,7 +92,7 @@ namespace detail {
         virtual void disable();
     };
 
-#ifdef HAVE_TIMERFD
+#ifdef HAVE_TIMERFD_CREATE
     class TimerFDTimerSource
         : public detail::FdManager::Event, public TimerSource
     {
index 31c1b45..1c6122f 100644 (file)
@@ -47,36 +47,22 @@ namespace config {
 # endif
 #
 # ifndef SENF_copy_n
-#     include <algorithm>
-#     if defined(__GNUC__) && ! defined(_STLP_ALGORITHM) && (__GNUC__>=4 || (__GNUC__==3 && __GNUC_MINOR__>=4))
+#     ifdef HAVE_GNUCXX_COPYN
 #         include <ext/algorithm>
 #         define SENF_copy_n __gnu_cxx::copy_n
-#     else
+#     endif
+#     ifdef HAVE_STD_COPYN
+#         include <algorithm>
 #         define SENF_copy_n std::copy_n
 #     endif
-# endif
+#  endif
 #
 # ifndef SENF_MPL_RV_ALIGNMENT
 #     define SENF_MPL_RV_ALIGNMENT 16
 # endif
 #
 # if !defined(SENF_BUFFER_USE_LOCALS) && !defined(SENF_BUFFER_USE_ALLOCA) && !defined(SENF_BUFFER_USE_NEW)
-#
-#     if defined(__GNUC__)
-#         define SENF_BUFFER_USE_LOCALS 1
-#
-#     // Add other compilers here ...
-#
-#     // dynamic arrays are part of C99. Which is NOT part of C++
-#     // but lets try nonetheless ...
-#     elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#         define SENF_BUFFER_USE_LOCALS 1
-#     endif
-#
-#     if !defined(SENF_BUFFER_USE_LOCALS) && !defined(SENF_BUFFER_USE_ALLOCA)
-#         define SENF_BUFFER_USE_NEW 1
-#     endif
-#
+#     define SENF_BUFFER_USE_NEW 1
 # endif
 #
 # ifndef SENF_SENFLOG_LIMIT
@@ -99,9 +85,12 @@ namespace config {
 #     define PHOENIX_LIMIT 6
 # endif
 #
-# if __GLIBC__>=2 && __GLIBC_MINOR__>=8
-#     define HAVE_TIMERFD 1
+# ifndef SENF_PACKET_ANNOTATION_SLOTS
+#     define SENF_PACKET_ANNOTATION_SLOTS 8
 # endif
+#
+//# define SENF_PACKET_NO_COMPLEX_ANNOTATIONS
+
 
 ///////////////////////////////hh.e////////////////////////////////////////
 #endif
index 28d4b31..49169fe 100644 (file)
@@ -29,7 +29,7 @@ def CheckBoostVersion(context):
     ret = context.TryRun("#include <boost/version.hpp>\n"
                          "#include <iostream>\n"
                          "int main(int, char **) { std::cout << BOOST_LIB_VERSION << std::endl; }",
-                         ".cc")[1].strip()
+                         ".cc")[-1].strip()
     if not ret:
         context.Result("no boost includes found")
         return None
@@ -62,4 +62,5 @@ def CheckBoostVariants(context, *variants):
     if useVariant is not None and not context.env.GetOption('no_progress'):
         print  "Using %s boost variant." % (
             useVariant and "'%s'" % useVariant or "default")
+    context.env.Replace( BOOST_VARIANT = useVariant )
     return useVariant
index 7a2eb98..def4697 100644 (file)
@@ -257,20 +257,86 @@ def Glob(env, exclude=[], subdirs=[]):
     return (sources, testSources)
 
 
-def Configure(env):
+@senfconf.Test
+def CheckSTLCopyN(context):
+    context.Message("Checking for 'copy_n' implementation... ")
+    versions = [ ('<algorithm>',     'std::copy_n',       'STD'),
+                 ('<ext/algorithm>', '__gnu_cxx::copy_n', 'GNUCXX') ]
+    for include, name, define in versions:
+        ret = context.TryCompile("#include %s\n"
+                                 "int main(int,char**) { int *a,*b; %s(a,0,b); }\n"
+                                 % (include, name),
+                                 ".cc")
+        if ret:
+            context.Result(name)
+            context.sconf.Define("HAVE_%s_COPYN" % define,
+                                 1,
+                                 "Define one of " 
+                                 + ", ".join(("HAVE_%s_COPYN" % elt[2] for elt in versions)))
+            return ret
+
+    context.Result(False)
+    return False
+
+
+@senfconf.Test
+def CheckTempBufferStrategy(context):
+    context.Message("Checking for optimal temporary buffer strategy... ")
+
+    def check():
+      # locals
+      ret = context.TryCompile("void test(int n){int a[n];}",".cc")
+      if ret: return "locals"
+
+      # alloca
+      ret = context.TryCompile("#include <alloca.h>\n"
+                               "void test(int a){void *b(alloca(a));}"
+                               ".cc")
+      if ret: return "alloca"
+      
+      # fallback: new
+      return "new"
+
+    ret = check()
+    context.Result(ret)
+    context.sconf.Define("SENF_BUFFER_USE_%s" % ret.upper(),
+                         1,
+                         "Define one of SENF_BUFFER_USE_LOCALS, SENF_BUFFER_USE_ALLOCA, "
+                         "SENF_BUFFER_USE_NEW")
+    return ret
+
+
+def Fail(msg):
+    SCons.Util.display("scons: *** %s" % msg)
+    Exit(1)
+
+
+def Configure(env, customChecks=None):
     conf = env.Configure(clean=False, 
                          help=False, 
                          custom_tests=senfconf.Tests(), 
                          config_h="#/senf/autoconf.hh")
-    env.SetDefault(
-        BOOST_VERSION  = conf.CheckBoostVersion(),
-        BOOST_VARIANT  = conf.CheckBoostVariants( '', 'mt' ),
-        NEED_BOOST_EXT = not conf.CheckCXXHeader("boost/bimap.hpp"),
-        HAVE_BOOST_SPIRIT_INCLUDE_CLASSIC_HPP = conf.CheckCXXHeader(
-            "boost/spirit/include/classic.hpp"),
-    )
-    conf.Finish()
 
+    # Boost
+    if not conf.CheckBoostVersion():
+        Fail("Boost includes not found")
+    if not conf.env['ARGUMENT_VARIABLES'].has_key('BOOST_VARIANT'): conf.CheckBoostVariants( '', 'mt' )
+    conf.env.Replace(NEED_BOOST_EXT = not conf.CheckCXXHeader("boost/bimap.hpp"))
+    conf.CheckCXXHeader("boost/spirit/include/classic.hpp")
+        
+    # Compiler support
+    conf.CheckTempBufferStrategy()
+
+    # Standard library stuff
+    if not conf.CheckSTLCopyN():
+        Fail("No 'copy_n' implementation found")
+    conf.CheckFunc("timerfd_create")
+
+    # User checks
+    if customChecks:
+        customChecks(conf)
+
+    conf.Finish()
 
 tagfiles = None