mirror of
https://github.com/boostorg/python.git
synced 2026-01-30 20:12:37 +00:00
boost.python numpy support - improvements to build system
This commit is contained in:
52
SConstruct
52
SConstruct
@@ -1,51 +1,17 @@
|
||||
import distutils.sysconfig
|
||||
import numpy.distutils.misc_util
|
||||
import re
|
||||
import scons_tools
|
||||
import os
|
||||
|
||||
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_numpy_env = scons_tools.MakeEnvironment()
|
||||
bp_numpy_env.SetupPackages(["boost.python","numpy"])
|
||||
bp_numpy_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)
|
||||
|
||||
def ConfigureNumpy(env):
|
||||
folders = numpy.distutils.misc_util.get_numpy_include_dirs()
|
||||
env.Append(CPPPATH=folders)
|
||||
|
||||
env = Environment()
|
||||
ConfigurePython(env)
|
||||
ConfigureNumpy(env)
|
||||
env.Append(LIBS = "boost_python")
|
||||
env.Append(CPPPATH = "#")
|
||||
|
||||
Export("env")
|
||||
Export("bp_numpy_env")
|
||||
lib = SConscript("libs/python/numpy/src/SConscript")
|
||||
libpath = os.path.abspath("libs/python/numpy/src")
|
||||
if os.environ.has_key("LD_LIBRARY_PATH"):
|
||||
env["ENV"]["LD_LIBRARY_PATH"] = "%s:%s" % (libpath, os.environ["LD_LIBRARY_PATH"])
|
||||
bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = "%s:%s" % (libpath, os.environ["LD_LIBRARY_PATH"])
|
||||
else:
|
||||
env["ENV"]["LD_LIBRARY_PATH"] = libpath
|
||||
env.Append(LIBPATH=libpath)
|
||||
Export("lib")
|
||||
bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = libpath
|
||||
bp_numpy_env.Append(LIBPATH="#libs/python/numpy/src")
|
||||
|
||||
SConscript("libs/python/numpy/test/SConscript")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Import("env")
|
||||
Import("bp_numpy_env")
|
||||
|
||||
lib = env.SharedLibrary("boost_python_numpy", Glob("*.cpp"))
|
||||
lib = bp_numpy_env.SharedLibrary("boost_python_numpy", Glob("*.cpp"))
|
||||
|
||||
Return("lib")
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
Import("env")
|
||||
import os
|
||||
Import("bp_numpy_env")
|
||||
|
||||
test_env = env.Clone()
|
||||
test_env.Append(LIBS="boost_python_numpy")
|
||||
|
||||
tests = ("ufunc",)
|
||||
test_mods = [test_env.SharedLibrary("%s_mod" % k, "%s_mod.cpp" % k, SHLIBPREFIX="")
|
||||
for k in tests]
|
||||
os.path.abspath(".")
|
||||
test_runs = [test_env.Command(".%s" % name, [mod,"%s.py" % name],
|
||||
"cd %s; python %s.py" % (os.path.abspath("."), name))
|
||||
for name, mod in zip(tests, test_mods)]
|
||||
|
||||
test = Alias("test",[test_runs])
|
||||
ufunc_mod = bp_numpy_env.SharedLibrary("ufunc_mod", "ufunc_mod.cpp", SHLIBPREFIX="",
|
||||
LIBS="boost_python_numpy")
|
||||
ufunc_test = bp_numpy_env.PythonUnitTest("ufunc.py", ufunc_mod)
|
||||
|
||||
test = ufunc_test
|
||||
Return("test")
|
||||
|
||||
236
site_scons/scons_tools.py
Executable file
236
site_scons/scons_tools.py
Executable file
@@ -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
|
||||
Reference in New Issue
Block a user