$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r62075 - in sandbox/python_extensions: . boost/python/to_python libs/python/test site_scons
From: talljimbo_at_[hidden]
Date: 2010-05-18 02:57:50
Author: jbosch
Date: 2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
New Revision: 62075
URL: http://svn.boost.org/trac/boost/changeset/62075
Log:
python_extensions - improvements to build system
Added:
   sandbox/python_extensions/site_scons/
   sandbox/python_extensions/site_scons/scons_tools.py   (contents, props changed)
Properties modified: 
   sandbox/python_extensions/   (props changed)
   sandbox/python_extensions/libs/python/test/   (props changed)
Text files modified: 
   sandbox/python_extensions/SConstruct                          |    39 +++++---------------------------------- 
   sandbox/python_extensions/boost/python/to_python/implicit.hpp |     6 +++---                                  
   sandbox/python_extensions/boost/python/to_python/std_pair.hpp |     4 +---                                    
   sandbox/python_extensions/libs/python/test/SConscript         |    12 +++++-------                            
   sandbox/python_extensions/libs/python/test/test_mod.cpp       |    12 ++++++------                            
   sandbox/python_extensions/libs/python/test/test_script.py     |     2 +-                                      
   6 files changed, 21 insertions(+), 54 deletions(-)
Modified: sandbox/python_extensions/SConstruct
==============================================================================
--- sandbox/python_extensions/SConstruct	(original)
+++ sandbox/python_extensions/SConstruct	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -1,37 +1,8 @@
-import distutils.sysconfig
-import re
-import os
+import scons_tools
 
-def ApplyFlags(env, flags):
-    flags = env.ParseFlags(flags)
-    flags["CCFLAGS"] = [opt for opt in flags["CCFLAGS"] if not opt.startswith("-O")]
-    flags["CFLAGS"] = [opt for opt in flags["CFLAGS"] if not opt.startswith("-O")]
-    debug = ARGUMENTS.get('debug', 0)
-    if int(debug):
-        try:
-            flags["CPPDEFINES"].remove("NDEBUG")
-        except: pass
-    env.MergeFlags(flags)
+bp_extensions_env = scons_tools.MakeEnvironment()
+bp_extensions_env.SetupPackages(["boost.python"])
+bp_extensions_env.Append(CPPPATH = "#")
 
-def ConfigurePython(env):
-    cflags = " ".join(v for v in distutils.sysconfig.get_config_vars("BASECFLAGS","OPT")
-                      if v is not None).split()
-    libs = " ".join(v for v in distutils.sysconfig.get_config_vars("BLDLIBRARY","LIBS")
-                    if v is not None).split()
-    try: # not valid for C++
-        cflags.remove("-Wstrict-prototypes")
-    except ValueError: pass
-    cflags = [f for f in cflags if not f.startswith("-O")]
-    try:
-        libs.remove("-L.")
-    except ValueError: pass
-    cflags.append("-I%s" % distutils.sysconfig.get_python_inc())
-    ApplyFlags(env, cflags + libs)
-
-env = Environment()
-ConfigurePython(env)
-env.Append(LIBS = "boost_python")
-env.Append(CPPPATH = "#")
-
-Export("env")
+Export("bp_extensions_env")
 SConscript("libs/python/test/SConscript")
Modified: sandbox/python_extensions/boost/python/to_python/implicit.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/implicit.hpp	(original)
+++ sandbox/python_extensions/boost/python/to_python/implicit.hpp	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -32,9 +32,9 @@
         return converter.get_pytype();
     }
 
-    implicit_to_python() {
-        boost::python::to_python_converter<Source,implicit_to_python,true>();
-    }
+    implicit_to_python() { declare(); }
+
+    static void declare() { boost::python::to_python_converter<Source,implicit_to_python,true>(); }
 
 };
 
Modified: sandbox/python_extensions/boost/python/to_python/std_pair.hpp
==============================================================================
--- sandbox/python_extensions/boost/python/to_python/std_pair.hpp	(original)
+++ sandbox/python_extensions/boost/python/to_python/std_pair.hpp	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -20,9 +20,7 @@
     : public boost_fusion_to_python< std::pair<T1,T2> > 
 {
 
-    std_pair_to_python() {
-        boost::python::to_python_converter<std::pair<T1,T2>,std_pair_to_python,true>();
-    }
+    std_pair_to_python() {}
 
 };
 
Modified: sandbox/python_extensions/libs/python/test/SConscript
==============================================================================
--- sandbox/python_extensions/libs/python/test/SConscript	(original)
+++ sandbox/python_extensions/libs/python/test/SConscript	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -1,8 +1,6 @@
-Import("env")
-import os
+Import("bp_extensions_env")
 
-module = env.SharedLibrary("test_mod", "test_mod.cpp", SHLIBPREFIX="")
-path = os.path.abspath(os.curdir)
-runs = [env.Command(".%s" % script, [module, script], "python %s" % os.path.join(path,script)) 
-        for script in ("test_script.py",)]
-test = Alias("test", [runs])
+test_mod = bp_extensions_env.SharedLibrary("test_mod", "test_mod.cpp", SHLIBPREFIX="")
+test = bp_extensions_env.PythonUnitTest("test_script.py", test_mod)
+
+Return("test")
Modified: sandbox/python_extensions/libs/python/test/test_mod.cpp
==============================================================================
--- sandbox/python_extensions/libs/python/test/test_mod.cpp	(original)
+++ sandbox/python_extensions/libs/python/test/test_mod.cpp	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -71,15 +71,15 @@
 }
 
 
-typedef std::pair<int,std::string> test_pair;
+typedef std::pair<int,double> test_pair;
 
 static test_pair return_pair() {
-    return test_pair(3, "test string");
+    return test_pair(3, 5.0);
 }
 
 static bool accept_pair(test_pair const & pair) {
     return pair.first == 3 
-        && pair.second == "test string";
+        && pair.second == 5.0;
 }
 
 
@@ -124,9 +124,9 @@
     bp::def("return_tuple", &return_tuple);
     bp::def("accept_tuple", &accept_tuple);
 
-
-    bp::std_pair_to_python<int,std::string>();
-    bp::std_pair_from_python<int,std::string>();
+    
+    bp::std_pair_to_python<int,double>();
+    bp::std_pair_from_python<int,double>();
 
     bp::def("return_pair", &return_pair);
     bp::def("accept_pair", &accept_pair);
Modified: sandbox/python_extensions/libs/python/test/test_script.py
==============================================================================
--- sandbox/python_extensions/libs/python/test/test_script.py	(original)
+++ sandbox/python_extensions/libs/python/test/test_script.py	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -53,7 +53,7 @@
     def testPair(self):
         v = test_mod.return_pair()
         self.assertEqual(type(v), tuple)
-        self.assertEqual(v, (3, "test string"))
+        self.assertEqual(v, (3, 5.0))
         self.assert_(test_mod.accept_pair(v))
 
 class TestConstSharedPtr(unittest.TestCase):
Added: sandbox/python_extensions/site_scons/scons_tools.py
==============================================================================
--- (empty file)
+++ sandbox/python_extensions/site_scons/scons_tools.py	2010-05-18 02:57:48 EDT (Tue, 18 May 2010)
@@ -0,0 +1,236 @@
+import SCons.Script as scons
+import re
+import os
+
+database = {}
+
+def ApplyFlags(env, flags):
+    flags = env.ParseFlags(flags)
+    flags["CCFLAGS"] = [opt for opt in flags["CCFLAGS"] if not opt.startswith("-O")]
+    flags["CFLAGS"] = [opt for opt in flags["CFLAGS"] if not opt.startswith("-O")]
+    debug = scons.ARGUMENTS.get('debug', 0)
+    if int(debug):
+        try:
+            flags["CPPDEFINES"].remove("NDEBUG")
+        except: pass
+    env.MergeFlags(flags)
+
+class Configuration(object):
+
+    def __new__(cls, name=None, dependencies=None):
+        if name is None:
+            name = cls.name
+        if dependencies is None:
+            dependencies = cls.dependencies
+        if database.has_key(name):
+            return database[name]
+        else:
+            self = object.__new__(cls)
+            self._checked = False
+            if not hasattr(cls, "dependencies"):
+                self.dependencies = dependencies
+            if not hasattr(cls, "name"):
+                self.name = name
+            database[name] = self
+            return self
+
+    def check(self):
+        if scons.GetOption("help") or scons.GetOption("clean"):
+            return True
+        if not self._checked:
+            self._available = self._check_dependencies() and self._check()
+            self._checked = True
+        return self._available
+
+    def _check(self):
+        return True
+
+    def _check_dependencies(self):
+        for dependency in self.dependencies:
+            if not database[dependency].check():
+                return False
+        return True
+
+    def apply(self, environment):
+        if scons.GetOption("help") or scons.GetOption("clean"):
+            return
+        if self.check():
+            self._apply_dependencies(environment)
+            self._apply(environment)
+
+    def _apply(self, environment):
+        pass
+
+    def _apply_dependencies(self, environment):
+        for dependency in self.dependencies:
+            database[dependency].apply(environment)
+
+class FlagConfiguration(Configuration):
+
+    def _apply(self, environment):
+        ApplyFlags(environment, self._flags)
+
+class VariableConfiguration(Configuration):
+
+    def _apply(self, environment):
+        environment.Append(**self._variables)
+
+class PythonConfiguration(FlagConfiguration):
+
+    name = "python"
+    dependencies = ()
+
+    def _check(self):
+        env = MakeEnvironment()
+        context = scons.Configure(env)
+        try:
+            from distutils.sysconfig import get_config_vars, get_python_inc
+        except ImportError:
+            return False
+        self._flags = " ".join(v for v in get_config_vars("BASECFLAGS", "OPT", "BLDLIBRARY", "LIBS")
+                               if v is not None).split()
+        try: # not valid for C++
+            self._flags.remove("-Wstrict-prototypes")
+        except ValueError: pass
+        try:
+            self._flags.remove("-L.")
+        except ValueError: pass
+        self._flags = [f for f in self._flags if not f.startswith("-O")]
+        self._flags.append("-I%s" % get_python_inc())
+        self._apply(env)
+        if not context.CheckHeader(["Python.h"]):
+            return False
+        context.Finish()
+        return True
+
+PythonConfiguration()
+
+class NumPyConfiguration(VariableConfiguration):
+
+    name = "numpy"
+    dependencies = ("python",)
+
+    def _check(self):
+        env = MakeEnvironment()
+        context = scons.Configure(env)
+        self._apply_dependencies(context.env)
+        try:
+            import numpy.distutils.misc_util
+            self._variables = {"CPPPATH": numpy.distutils.misc_util.get_numpy_include_dirs()}
+        except ImportError:
+            context.Result(False)
+            return False
+        self._apply(context.env)
+        if not context.CheckHeader(["Python.h", "numpy/arrayobject.h"]):
+            return False
+        context.Finish()
+        return True
+
+NumPyConfiguration()
+
+class LibraryConfiguration(VariableConfiguration):
+
+    def __new__(cls, name, headers=None, libraries=None, dependencies=()):
+        self = VariableConfiguration.__new__(cls, name, dependencies)
+        self._headers = headers
+        self._libraries = libraries
+        self._variables = {}
+        return self
+
+    def _check(self):
+        env = MakeEnvironment()
+        context = scons.Configure(env)
+        self._apply_dependencies(context.env)
+        self._apply(context.env)
+        if self._headers:
+            if not context.CheckHeader(self._headers, language="C++"):
+                return False
+        if self._libraries:
+            if not context.CheckLib(self._libraries, language="C++"):
+                return False
+            self._variables = {"LIBS": self._libraries}
+        context.Finish()
+        return True
+
+LibraryConfiguration(name="boost.python",
+                     headers=["boost/python.hpp"], 
+                     libraries=["boost_python"],
+                     dependencies=("python",)
+                     )
+
+class LocalConfiguration(VariableConfiguration):
+
+    def __new__(cls, name, libraries=None, dependencies=()):
+        self = VariableConfiguration.__new__(cls, name, dependencies)
+        self._libraries = libraries
+        self._variables = {}
+        return self
+
+    def _check(self):
+        if self._libraries:
+            self._variables["LIBS"] = self._libraries
+        return True
+
+def RecursiveInstall(env, target, source, regex):
+    regex = re.compile(regex)
+    source = scons.Dir(source)
+    target = scons.Dir(target)
+    result = []
+    for dirpath, dirnames, filenames in os.walk(source.abspath):
+        try:
+            dirnames.remove(".svn")
+        except ValueError:
+            pass
+        relpath = dirpath[len(source.abspath)+1:]
+        for filename in filenames:
+            m = regex.match(filename)
+            if m:
+                result.extend(env.InstallAs(os.path.join(target.abspath, relpath, m.group(1)), 
+                                            os.path.join(dirpath, m.group(1))))
+    return result
+
+def RunProgramUnitTest(target, source, env):
+    path, filename = os.path.split(source[0].abspath)
+    if not env.Execute("cd %s; ./%s" % (path, filename)):
+        env.Execute(scons.Touch(target))
+
+def RunPythonUnitTest(target, source, env):
+    path, filename = os.path.split(source[0].abspath)
+    if not env.Execute("cd %s; python %s" % (path, filename)):
+        env.Execute(scons.Touch(target))
+
+def BoostUnitTest(env, name, source):
+    try:
+        libs = env["LIBS"] + ["boost_unit_test_framework"]
+    except KeyError:
+        libs = "boost_unit_test_framework"
+    bin = env.Program(name, source, LIBS=libs)
+    run = env.Command(".%s.succeeded" % name, name, RunProgramUnitTest)
+    env.Depends(run, bin)
+    return run
+
+def PythonUnitTest(env, script, dependencies):
+    run = env.Command(".%s.succeeded" % script, script, RunPythonUnitTest)
+    env.Depends(run, dependencies)
+    return run
+
+def SetupPackages(env, packages):
+    for package in packages:
+        database[package].apply(env)
+
+def MakeEnvironment():
+    env = scons.Environment()
+    env.AddMethod(RecursiveInstall, "RecursiveInstall")
+    env.AddMethod(SetupPackages, "SetupPackages")
+    env.AddMethod(BoostUnitTest, "BoostUnitTest")
+    env.AddMethod(PythonUnitTest, "PythonUnitTest")
+    for var in ("PATH", "LD_LIBRARY_PATH", "PYTHONPATH", "PKG_CONFIG_PATH"):
+        if os.environ.has_key(var):
+            env["ENV"][var] = os.environ[var]
+    debug = scons.ARGUMENTS.get('debug', 0)
+    if int(debug):
+        env.Replace(CCFLAGS=["-Wall","-g","-O0"])
+    else:
+        env.Replace(CCFLAGS=["-Wall","-O2"])
+        env.Append(CPPDEFINES="NDEBUG")
+    return env