diff --git a/SConscript b/SConscript new file mode 100644 index 00000000..7f5fe223 --- /dev/null +++ b/SConscript @@ -0,0 +1,39 @@ +import scons_tools +import os + +targets = {"boost.python.numpy":{}} + +scons_tools.LocalConfiguration( + name="boost.python.numpy", + libraries=["boost_python_numpy"], + dependencies=("boost.python", "numpy") + ) +bp_numpy_env = scons_tools.GetEnvironment().Clone() +bp_numpy_env.Append(CPPPATH=[os.path.abspath(os.curdir)]) +libpath = os.path.abspath("%s/python/numpy/src" % scons_tools.GetBuildDir()) +if os.environ.has_key("LD_LIBRARY_PATH"): + bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = "%s:%s" % (libpath, os.environ["LD_LIBRARY_PATH"]) +else: + bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = libpath +bp_numpy_env.Append(LIBPATH=[libpath]) +bp_numpy_env.SetupPackages(["boost.python", "numpy"]) +Export("bp_numpy_env") + +targets["boost.python.numpy"]["lib"] = ( + SConscript("libs/python/numpy/src/SConscript", + variant_dir="%s/python/numpy/src" % scons_tools.GetBuildDir(), + duplicate=False) + ) +targets["boost.python.numpy"]["install"] = ( + bp_numpy_env.RecursiveInstall( + os.path.join(bp_numpy_env["INSTALL_HEADERS"], "boost"), + "boost", + regex="(.*\.hpp)") + + bp_numpy_env.Install(bp_numpy_env["INSTALL_LIB"], targets["boost.python.numpy"]["lib"]) + ) +targets["boost.python.numpy"]["test"] = ( + SConscript("libs/python/numpy/test/SConscript", + variant_dir="%s/python/numpy/test" % scons_tools.GetBuildDir()) + ) + +Return("targets") diff --git a/SConstruct b/SConstruct index c748a50c..f50f6e64 100644 --- a/SConstruct +++ b/SConstruct @@ -1,25 +1,6 @@ import scons_tools import os -bp_numpy_env = scons_tools.MakeEnvironment() -bp_numpy_env.SetupPackages(["boost.python","numpy"]) -bp_numpy_env.Append(CPPPATH = "#") - -if ARGUMENTS.get("debug", 0): - build_dir = "build.debug" -else: - build_dir = "build" -Export("build_dir") - -Export("bp_numpy_env") -lib = SConscript("libs/python/numpy/src/SConscript", - variant_dir="%s/python/numpy/src" % build_dir, duplicate=False) -libpath = os.path.abspath("%s/python/numpy/src" % build_dir) -bp_numpy_env.Append(LIBPATH=[libpath]) -if os.environ.has_key("LD_LIBRARY_PATH"): - bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = "%s:%s" % (libpath, os.environ["LD_LIBRARY_PATH"]) -else: - bp_numpy_env["ENV"]["LD_LIBRARY_PATH"] = libpath -bp_numpy_env.Append(LIBPATH=libpath) - -SConscript("libs/python/numpy/test/SConscript", variant_dir="%s/python/numpy/test" % build_dir) +base_env = scons_tools.MakeEnvironment() +targets = SConscript("SConscript") +scons_tools.MakeAliases(targets) diff --git a/libs/python/numpy/src/SConscript b/libs/python/numpy/src/SConscript index 9084ae1c..88cdbfe1 100644 --- a/libs/python/numpy/src/SConscript +++ b/libs/python/numpy/src/SConscript @@ -1,5 +1,4 @@ Import("bp_numpy_env") - lib = bp_numpy_env.SharedLibrary("boost_python_numpy", Glob("*.cpp")) Return("lib") diff --git a/site_scons/scons_tools.py b/site_scons/scons_tools.py index 762b9a9a..2dc98a69 100755 --- a/site_scons/scons_tools.py +++ b/site_scons/scons_tools.py @@ -1,10 +1,24 @@ import SCons.Script as scons import re +import distutils.sysconfig import sys import os database = {} +_environment = None + +scons.AddOption("--prefix", dest="install_prefix", type="string", nargs=1, action="store", metavar="DIR", + help="installation prefix") +scons.AddOption("--home", dest="install_home", type="string", nargs=1, action="store", metavar="DIR", + help="home directory to install under") +scons.AddOption("--install-lib", dest="install_lib", type="string", nargs=1, action="store", metavar="DIR", + help="installation directory for libraries") +scons.AddOption("--install-headers", dest="install_headers", type="string", nargs=1, + action="store", metavar="DIR", help="installation directory for C++ header files") +scons.AddOption("--install-python", dest="install_python", type="string", nargs=1, + action="store", metavar="DIR", help="installation directory for Python modules") + def ApplyFlags(env, flags): flags = env.ParseFlags(flags) flags["CCFLAGS"] = [opt for opt in flags["CCFLAGS"] if not opt.startswith("-O")] @@ -88,7 +102,7 @@ class PythonConfiguration(FlagConfiguration): dependencies = () def _check(self): - env = MakeEnvironment() + env = GetEnvironment().Clone() try: from distutils.sysconfig import get_config_vars, get_python_inc except ImportError: @@ -119,7 +133,7 @@ class NumPyConfiguration(VariableConfiguration): dependencies = ("python",) def _check(self): - env = MakeEnvironment() + env = GetEnvironment().Clone() self._apply_dependencies(env) try: import numpy.distutils.misc_util @@ -147,7 +161,7 @@ class LibraryConfiguration(VariableConfiguration): return self def _check(self): - env = MakeEnvironment() + env = GetEnvironment().Clone() self._apply_dependencies(env) self._apply(env) context = scons.Configure(env) @@ -232,29 +246,120 @@ def SetupPackages(env, packages): for package in packages: database[package].apply(env) -def MakeEnvironment(): - env = scons.Environment(tools = ["default", "doxygen"]) +def MakeAliases(targets): + env = GetEnvironment() + all_all = [] + build_all = [] + install_all = [] + test_all = [] + scons.Help(""" +To specify additional directories to add to the include or library paths, specify them +with colon-separated lists on the command line. For example: + +scons CPPPATH="/home/me/include:/opt/include" LIBPATH="/home/me/lib" + +Supported variables are CPPPATH, LIBPATH and RPATH. + +Global targets: 'all' (builds everything) + 'build' (builds headers, libraries, and python wrappers) + 'install' (copies files to global bin, include and lib directories) + 'test' (runs unit tests; requires install) + +These targets can be built for individual packages with the syntax +'[package]-[target]'. Some packages support additional targets, given below. + +Packages: + +""" + ) + for pkg_name in sorted(targets.keys()): + pkg_targets = targets[pkg_name] + extra_targets = tuple(k for k in pkg_targets.keys() if k not in + ("all","build","install","test")) + if extra_targets: + scons.Help("%-25s %s\n" % (pkg_name, ", ".join("'%s'" % k for k in extra_targets))) + else: + scons.Help("%-25s (none)\n" % pkg_name) + pkg_all = pkg_targets.values() + pkg_build = [pkg_targets[k] for k in ("headers", "lib", "python") if k in pkg_targets] + env.Alias(pkg_name, pkg_all) + env.Alias("%s-all" % pkg_name, pkg_all) + env.Alias("%s-build" % pkg_name, pkg_build) + for target_name in pkg_targets: + env.Alias("%s-%s" % (pkg_name, target_name), pkg_targets[target_name]) + all_all.extend(pkg_all) + build_all.extend(pkg_build) + install_all.extend(pkg_targets.get("install", pkg_build)) + test_all.extend(pkg_targets.get("test", pkg_targets.get("install", pkg_build))) + env.Alias("all", all_all) + env.Alias("build", build_all) + env.Alias("install", install_all) + env.Alias("test", test_all) + env.Default("build") + + +def MakeEnvironment(default_prefix="/usr/local", prefix_is_home=False): + global _environment + _environment = scons.Environment(tools = ["default", "doxygen"]) if scons.ARGUMENTS.has_key('LIBPATH'): - env.Append(LIBPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['LIBPATH'].split(":")]) + _environment.Append(LIBPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['LIBPATH'].split(":")]) if scons.ARGUMENTS.has_key('RPATH'): - env.Append(RPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['RPATH'].split(":")]) + _environment.Append(RPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['RPATH'].split(":")]) if scons.ARGUMENTS.has_key('CPPPATH'): - env.Append(CPPPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['CPPPATH'].split(":")]) - env.Append(CPPPATH=["#include"]) - env.Append(LIBPATH=["#lib"]) - env.AddMethod(RecursiveInstall, "RecursiveInstall") - env.AddMethod(SetupPackages, "SetupPackages") - env.AddMethod(BoostUnitTest, "BoostUnitTest") - env.AddMethod(PythonUnitTest, "PythonUnitTest") + _environment.Append(CPPPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['CPPPATH'].split(":")]) + prefix = scons.GetOption("install_prefix") + if prefix is None: + prefix = scons.GetOption("install_home") + if prefix is None: + prefix = default_prefix + else: + preefix_is_home = True + install_lib = scons.GetOption("install_lib") + if install_lib is None: + install_lib = os.path.join(prefix, "lib") + install_headers = scons.GetOption("install_headers") + if install_headers is None: + install_headers = os.path.join(prefix, "include") + install_python = scons.GetOption("install_python") + if install_python is None: + if prefix_is_home: + install_python = os.path.join(install_lib, "python") + else: + python_lib = distutils.sysconfig.get_python_lib() + if python_lib.startswith(distutils.sysconfig.PREFIX): + install_python = os.path.join(prefix, python_lib[len(distutils.sysconfig.PREFIX)+1:]) + else: + print "Cannot determine default Python install directory." + print "Please specify --install-python on the command line." + scons.Exit(1) + _environment["INSTALL_LIB"] = install_lib + _environment["INSTALL_HEADERS"] = install_headers + _environment["INSTALL_PYTHON"] = install_python + _environment.AddMethod(RecursiveInstall, "RecursiveInstall") + _environment.AddMethod(SetupPackages, "SetupPackages") + _environment.AddMethod(BoostUnitTest, "BoostUnitTest") + _environment.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] + _environment["ENV"][var] = os.environ[var] else: - env["ENV"][var] = "" + _environment["ENV"][var] = "" debug = scons.ARGUMENTS.get('debug', 0) if int(debug): - env.Replace(CCFLAGS=["-Wall","-g","-O0"]) + _environment.Replace(CCFLAGS=["-Wall","-g","-O0"]) else: - env.Replace(CCFLAGS=["-Wall","-O2"]) - env.Append(CPPDEFINES=["NDEBUG"]) - return env + _environment.Replace(CCFLAGS=["-Wall","-O2"]) + _environment.Append(CPPDEFINES=["NDEBUG"]) + return _environment + +def GetEnvironment(): + if _environment is None: + raise LogicErrorException("scons_tools error: root environment not initialized") + return _environment + +def GetBuildDir(): + if scons.ARGUMENTS.get("debug", 0): + return "build.debug" + else: + return "build" +