From 38e68fa2ae4e6051f158031d9e5b6905fb88cdae Mon Sep 17 00:00:00 2001 From: Jim Bosch Date: Sun, 18 Mar 2012 18:57:14 -0400 Subject: [PATCH] overhauled scons scripts --- SConscript | 237 +++++++++++++++++--- SConstruct | 7 +- libs/numpy/example/SConscript | 14 +- libs/numpy/src/SConscript | 6 +- libs/numpy/test/SConscript | 29 ++- site_scons/scons_tools.py | 369 ------------------------------- site_scons/site_tools/doxygen.py | 252 --------------------- 7 files changed, 250 insertions(+), 664 deletions(-) delete mode 100755 site_scons/scons_tools.py delete mode 100755 site_scons/site_tools/doxygen.py diff --git a/SConscript b/SConscript index 984a4351..c12e3641 100644 --- a/SConscript +++ b/SConscript @@ -1,34 +1,219 @@ -import scons_tools +# -*- python -*- + +# Big thanks to Mike Jarvis for help with the configuration prescriptions below. + import os +import sys -targets = {"boost.numpy":{}} +def CheckPython(context): + python_source_file = """ +#include "Python.h" +int main() +{ + Py_Initialize(); + Py_Finalize(); + return 0; +} +""" + context.Message('Checking if we can build against Python... ') + try: + import distutils.sysconfig + except ImportError: + context.Result(0) + print 'Failed to import distutils.sysconfig.' + Exit(1) + context.env.AppendUnique(CPPPATH=[distutils.sysconfig.get_python_inc()]) + libDir = distutils.sysconfig.get_config_var("LIBDIR") + context.env.AppendUnique(LIBPATH=[libDir]) + libfile = distutils.sysconfig.get_config_var("LIBRARY") + import re + match = re.search("(python.*)\.(a|so|dylib)", libfile) + if match: + context.env.AppendUnique(LIBS=[match.group(1)]) + flags = [f for f in " ".join(distutils.sysconfig.get_config_vars("MODLIBS", "SHLIBS")).split() + if f != "-L"] + context.env.MergeFlags(" ".join(flags)) + result, output = context.TryRun(python_source_file,'.cpp') + if not result and sys.platform == 'darwin': + # Sometimes we need some extra stuff on Mac OS + frameworkDir = libDir # search up the libDir tree for the proper home for frameworks + while frameworkDir and frameworkDir != "/": + frameworkDir, d2 = os.path.split(frameworkDir) + if d2 == "Python.framework": + if not "Python" in os.listdir(os.path.join(frameworkDir, d2)): + context.Result(0) + print ( + "Expected to find Python in framework directory %s, but it isn't there" + % frameworkDir) + Exit(1) + break + context.env.AppendUnique(LDFLAGS="-F%s" % frameworkDir) + result, output = context.TryRun(python_source_file,'.cpp') + if not result: + context.Result(0) + print "Cannot run program built with Python." + Exit(1) + context.Result(1) + return 1 -scons_tools.LocalConfiguration( - name="boost.numpy", - libraries=["boost_numpy"], - dependencies=("boost.python", "numpy") - ) -boost_numpy_env = scons_tools.GetEnvironment().Clone() -boost_numpy_env.Append(CPPPATH=[os.path.abspath(os.curdir)]) -libpath = os.path.abspath("libs/numpy/src") +def CheckNumPy(context): + numpy_source_file = """ +#include "Python.h" +#include "numpy/arrayobject.h" +void doImport() { + import_array(); +} +int main() +{ + int result = 0; + Py_Initialize(); + doImport(); + if (PyErr_Occurred()) { + result = 1; + } else { + npy_intp dims = 2; + PyObject * a = PyArray_SimpleNew(1, &dims, NPY_INT); + if (!a) result = 1; + Py_DECREF(a); + } + Py_Finalize(); + return result; +} +""" + context.Message('Checking if we can build against NumPy... ') + try: + import numpy + except ImportError: + context.Result(0) + print 'Failed to import numpy.' + print 'Things to try:' + print '1) Check that the command line python (with which you probably installed numpy):' + print ' ', + sys.stdout.flush() + subprocess.call('which python',shell=True) + print ' is the same as the one used by SCons:' + print ' ',sys.executable + print ' If not, then you probably need to reinstall numpy with %s.' % sys.executable + print ' Alternatively, you can reinstall SCons with your preferred python.' + print '2) Check that if you open a python session from the command line,' + print ' import numpy is successful there.' + Exit(1) + context.env.Append(CPPPATH=numpy.get_include()) + result = CheckLibs(context,[''],numpy_source_file) + if not result: + context.Result(0) + print "Cannot build against NumPy." + Exit(1) + result, output = context.TryRun(numpy_source_file,'.cpp') + if not result: + context.Result(0) + print "Cannot run program built with NumPy." + Exit(1) + context.Result(1) + return 1 + +def CheckLibs(context, try_libs, source_file): + init_libs = context.env['LIBS'] + context.env.PrependUnique(LIBS=[try_libs]) + result = context.TryLink(source_file, '.cpp') + if not result : + context.env.Replace(LIBS=init_libs) + return result + +def CheckBoostPython(context): + bp_source_file = """ +#include "boost/python.hpp" +class Foo { public: Foo() {} }; +int main() +{ + Py_Initialize(); + boost::python::object obj; + boost::python::class_< Foo >("Foo", boost::python::init<>()); + Py_Finalize(); + return 0; +} +""" + context.Message('Checking if we can build against Boost.Python... ') + boost_prefix = GetOption("boost_prefix") + boost_include = GetOption("boost_include") + boost_lib = GetOption("boost_lib") + if boost_prefix is not None: + if boost_include is None: + boost_include = os.path.join(boost_prefix, "include") + if boost_lib is None: + boost_lib = os.path.join(boost_prefix, "lib") + if boost_include: + context.env.AppendUnique(CPPPATH=[boost_include]) + if boost_lib: + context.env.AppendUnique(LIBPATH=[boost_lib]) + result = ( + CheckLibs(context, [''], bp_source_file) or + CheckLibs(context, ['boost_python'], bp_source_file) or + CheckLibs(context, ['boost_python-mt'], bp_source_file) + ) + if not result: + context.Result(0) + print "Cannot build against Boost.Python." + Exit(1) + result, output = context.TryRun(bp_source_file, '.cpp') + if not result: + context.Result(0) + print "Cannot build against Boost.Python." + Exit(1) + context.Result(1) + return 1 + +# Setup command-line options +AddOption("--prefix", dest="prefix", type="string", nargs=1, action="store", + metavar="DIR", default="/usr/local", help="installation prefix") +AddOption("--with-boost", dest="boost_prefix", type="string", nargs=1, action="store", + metavar="DIR", default=os.environ.get("BOOST_DIR"), + help="prefix for Boost libraries; should have 'include' and 'lib' subdirectories") +AddOption("--with-boost-include", dest="boost_include", type="string", nargs=1, action="store", + metavar="DIR", help="location of Boost header files") +AddOption("--with-boost-lib", dest="boost_lib", type="string", nargs=1, action="store", + metavar="DIR", help="location of Boost libraries") + +# Initialize environment +env = Environment() +env.AppendUnique(CPPPATH="#.") + +# Propogate external environment variables if os.environ.has_key("LD_LIBRARY_PATH"): - boost_numpy_env["ENV"]["LD_LIBRARY_PATH"] = "%s:%s" % (libpath, os.environ["LD_LIBRARY_PATH"]) -else: - boost_numpy_env["ENV"]["LD_LIBRARY_PATH"] = libpath -boost_numpy_env.Append(LIBPATH=[libpath]) -boost_numpy_env.SetupPackages(["boost.python", "numpy"]) -Export("boost_numpy_env") + env["ENV"]["LD_LIBRARY_PATH"] = os.environ["LD_LIBRARY_PATH"] +if os.environ.has_key("DYLD_LIBRARY_PATH"): + env["ENV"]["DYLD_LIBRARY_PATH"] = os.environ["DYLD_LIBRARY_PATH"] +if os.environ.has_key("PYTHONPATH"): + env["ENV"]["PYTHONPATH"] = os.environ["PYTHONPATH"] -targets["boost.numpy"]["lib"] = SConscript("libs/numpy/src/SConscript") -targets["boost.numpy"]["install"] = ( - boost_numpy_env.RecursiveInstall( - os.path.join(boost_numpy_env["INSTALL_HEADERS"], "boost"), - "boost", - regex="(.*\.hpp)") - + boost_numpy_env.Install(boost_numpy_env["INSTALL_LIB"], targets["boost.numpy"]["lib"]) +# Configure dependencies +if not GetOption("help") and not GetOption("clean"): + config = env.Configure( + custom_tests = { + "CheckPython": CheckPython, + "CheckNumPy": CheckNumPy, + "CheckBoostPython": CheckBoostPython, + } ) -targets["boost.numpy"]["test"] = SConscript("libs/numpy/test/SConscript") -targets["boost.numpy"]["example"] = SConscript("libs/numpy/example/SConscript") + config.CheckPython() + config.CheckNumPy() + config.CheckBoostPython() + env = config.Finish() +# Setup build targets +lib = SConscript(os.path.join("libs", "numpy", "src", "SConscript"), exports='env') +example = SConscript(os.path.join("libs", "numpy", "example", "SConscript"), exports='env') +test = SConscript(os.path.join("libs", "numpy", "test", "SConscript"), exports='env') -Return("targets") +prefix = Dir(GetOption("prefix")).abspath + +env.Alias("install", env.Install(os.path.join(prefix, "lib"), lib)) +for header in ("dtype.hpp", "invoke_matching.hpp", "matrix.hpp", + "ndarray.hpp", "numpy_object_mgr_traits.hpp", + "scalars.hpp", "ufunc.hpp",): + env.Alias("install", env.Install(os.path.join(prefix, "include", "boost", "numpy"), + os.path.join("boost", "numpy", header))) +env.Alias("install", env.Install(os.path.join(prefix, "include", "boost"), + os.path.join("boost", "numpy.hpp"))) + +Return("env") diff --git a/SConstruct b/SConstruct index f50f6e64..2654592a 100644 --- a/SConstruct +++ b/SConstruct @@ -1,6 +1 @@ -import scons_tools -import os - -base_env = scons_tools.MakeEnvironment() -targets = SConscript("SConscript") -scons_tools.MakeAliases(targets) +SConscript("SConscript") diff --git a/libs/numpy/example/SConscript b/libs/numpy/example/SConscript index 5fce67fc..3409bb1b 100644 --- a/libs/numpy/example/SConscript +++ b/libs/numpy/example/SConscript @@ -1,11 +1,19 @@ -Import("boost_numpy_env") +# -*- python -*- +Import("env") + +import os + +example_env = env.Clone() +lib_path = os.path.abspath(os.path.join("..", "src")) +example_env.Append(LIBPATH=[lib_path]) +example_env.Append(LIBS=["boost_numpy"]) example = [] for name in ("ufunc", "dtype", "fromdata", "ndarray", "simple"): - example.extend(boost_numpy_env.Program(name, "%s.cpp" % name, LIBS="boost_numpy")) + example.extend(example_env.Program(name, "%s.cpp" % name)) for name in ("gaussian",): - example.extend(boost_numpy_env.SharedLibrary(name, "%s.cpp" % name, SHLIBPREFIX="", LIBS="boost_numpy")) + example.extend(example_env.SharedLibrary(name, "%s.cpp" % name, SHLIBPREFIX="")) Return("example") diff --git a/libs/numpy/src/SConscript b/libs/numpy/src/SConscript index ce44eec5..92ab5306 100644 --- a/libs/numpy/src/SConscript +++ b/libs/numpy/src/SConscript @@ -1,4 +1,6 @@ -Import("boost_numpy_env") -lib = boost_numpy_env.SharedLibrary("boost_numpy", Glob("*.cpp")) +# -*- python -*- +Import("env") + +lib = env.SharedLibrary("boost_numpy", Glob("*.cpp")) Return("lib") diff --git a/libs/numpy/test/SConscript b/libs/numpy/test/SConscript index 860cbf65..808874b4 100644 --- a/libs/numpy/test/SConscript +++ b/libs/numpy/test/SConscript @@ -1,12 +1,29 @@ -Import("boost_numpy_env") +# -*- python -*- +Import("env") + +import os +import sys + +test_env = env.Clone() +lib_path = os.path.abspath(os.path.join("..", "src")) +test_env.AppendENVPath("PYTHONPATH", os.path.abspath(".")) +test_env.AppendENVPath("LD_LIBRARY_PATH", lib_path) +test_env.Append(LIBPATH=[lib_path]) +test_env.Append(LIBS=["boost_numpy"]) test = [] +def RunPythonUnitTest(target, source, env): + if not env.Execute('%s %s' % (sys.executable, source[0].abspath)): + env.Execute(Touch(target)) + +def PythonUnitTest(env, script, dependencies): + run = env.Command(".%s.succeeded" % str(script), script, RunPythonUnitTest) + env.Depends(run, dependencies) + return run + for name in ("ufunc", "templates", "ndarray", "indexing", "shapes"): - mod = boost_numpy_env.SharedLibrary("%s_mod" % name, "%s_mod.cpp" % name, SHLIBPREFIX="", - LIBS="boost_numpy") - test.extend( - boost_numpy_env.PythonUnitTest("%s.py" % name, mod) - ) + mod = test_env.SharedLibrary("%s_mod" % name, "%s_mod.cpp" % name, SHLIBPREFIX="") + test.extend(PythonUnitTest(test_env, "%s.py" % name, mod)) Return("test") diff --git a/site_scons/scons_tools.py b/site_scons/scons_tools.py deleted file mode 100755 index 8ccf2532..00000000 --- a/site_scons/scons_tools.py +++ /dev/null @@ -1,369 +0,0 @@ -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")] - 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) - - def require(self): - if not all(database[pkg].check() for pkg in self.dependencies): - print "Missing dependencies for required package '%s'." % self.name - scons.Exit(1) - - -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 = GetEnvironment().Clone() - 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) - context = scons.Configure(env) - if not context.CheckHeader(["Python.h"]): - context.Finish() - return False - context.Finish() - return True - -PythonConfiguration() - -class NumPyConfiguration(VariableConfiguration): - - name = "numpy" - dependencies = ("python",) - - def _check(self): - env = GetEnvironment().Clone() - self._apply_dependencies(env) - try: - import numpy.distutils.misc_util - self._variables = {"CPPPATH": numpy.distutils.misc_util.get_numpy_include_dirs()} - except ImportError: - print "numpy.distutils.misc_util not found" - return False - self._apply(env) - context = scons.Configure(env) - if not context.CheckHeader(["Python.h", "numpy/arrayobject.h"]): - context.Finish() - 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 = GetEnvironment().Clone() - self._apply_dependencies(env) - self._apply(env) - context = scons.Configure(env) - if self._headers: - if not context.CheckHeader(self._headers, language="C++"): - context.Finish() - return False - if self._libraries: - if not context.CheckLib(self._libraries, language="C++"): - context.Finish() - 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(target[0].abspath) - env["ENV"]["TESTPATH"] = path - env["ENV"]["PYTHONPATH"] = ":".join([path] + env["ENV"]["PYTHONPATH"].split(":")) - if not env.Execute('%s %s' % (sys.executable, source[0].abspath)): - env.Execute(scons.Touch(target)) - env["ENV"]["PYTHONPATH"] = ":".join(env["ENV"]["PYTHONPATH"].split(":")[1:]) - -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" % str(name), name, RunProgramUnitTest) - env.Depends(run, bin) - return run - -def PythonUnitTest(env, script, dependencies): - run = env.Command(".%s.succeeded" % str(script), script, RunPythonUnitTest) - env.Depends(run, dependencies) - return run - -def SetupPackages(env, packages): - for package in packages: - database[package].apply(env) - -def MakeAliases(targets): - env = GetEnvironment() - all_all = [] - build_all = [] - install_all = [] - example_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) - 'example' (builds examples; may require install) - 'test' (runs unit tests; may require 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","example")) - 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)) - example_all.extend(pkg_targets.get("example", 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.Alias("example", example_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'): - _environment.Append(LIBPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['LIBPATH'].split(":")]) - if scons.ARGUMENTS.has_key('RPATH'): - _environment.Append(RPATH=[os.path.abspath(s) for s in scons.ARGUMENTS['RPATH'].split(":")]) - if scons.ARGUMENTS.has_key('CPPPATH'): - _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): - _environment["ENV"][var] = os.environ[var] - else: - _environment["ENV"][var] = "" - debug = scons.ARGUMENTS.get('debug', 0) - if int(debug): - _environment.Replace(CCFLAGS=["-Wall","-g","-O0"]) - else: - _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" - diff --git a/site_scons/site_tools/doxygen.py b/site_scons/site_tools/doxygen.py deleted file mode 100755 index c60d940e..00000000 --- a/site_scons/site_tools/doxygen.py +++ /dev/null @@ -1,252 +0,0 @@ -# vim: set et sw=3 tw=0 fo=awqorc ft=python: -# -# Astxx, the Asterisk C++ API and Utility Library. -# Copyright (C) 2005, 2006 Matthew A. Nicholson -# Copyright (C) 2006 Tim Blechmann -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License version 2.1 as published by the Free Software Foundation. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import os -import os.path -import glob -from fnmatch import fnmatch - -def DoxyfileParse(file_contents): - """ - Parse a Doxygen source file and return a dictionary of all the values. - Values will be strings and lists of strings. - """ - data = {} - - import shlex - lex = shlex.shlex(instream = file_contents, posix = True) - lex.wordchars += "*+./-:" - lex.whitespace = lex.whitespace.replace("\n", "") - lex.escape = "" - - lineno = lex.lineno - token = lex.get_token() - key = token # the first token should be a key - last_token = "" - key_token = False - next_key = False - new_data = True - - def append_data(data, key, new_data, token): - if new_data or len(data[key]) == 0: - data[key].append(token) - else: - data[key][-1] += token - - while token: - if token in ['\n']: - if last_token not in ['\\']: - key_token = True - elif token in ['\\']: - pass - elif key_token: - key = token - key_token = False - else: - if token == "+=": - if not data.has_key(key): - data[key] = list() - elif token == "=": - if key == "TAGFILES" and data.has_key(key): - append_data( data, key, False, "=" ) - new_data=False - else: - data[key] = list() - else: - append_data( data, key, new_data, token ) - new_data = True - - last_token = token - token = lex.get_token() - - if last_token == '\\' and token != '\n': - new_data = False - append_data( data, key, new_data, '\\' ) - - # compress lists of len 1 into single strings - for (k, v) in data.items(): - if len(v) == 0: - data.pop(k) - - # items in the following list will be kept as lists and not converted to strings - if k in ["INPUT", "FILE_PATTERNS", "EXCLUDE_PATTERNS", "TAGFILES"]: - continue - - if len(v) == 1: - data[k] = v[0] - - return data - -def DoxySourceScan(node, env, path): - """ - Doxygen Doxyfile source scanner. This should scan the Doxygen file and add - any files used to generate docs to the list of source files. - """ - default_file_patterns = [ - '*.c', '*.cc', '*.cxx', '*.cpp', '*.c++', '*.java', '*.ii', '*.ixx', - '*.ipp', '*.i++', '*.inl', '*.h', '*.hh ', '*.hxx', '*.hpp', '*.h++', - '*.idl', '*.odl', '*.cs', '*.php', '*.php3', '*.inc', '*.m', '*.mm', - '*.py', - ] - - default_exclude_patterns = [ - '*~', - ] - - sources = [] - - data = DoxyfileParse(node.get_contents()) - - if data.get("RECURSIVE", "NO") == "YES": - recursive = True - else: - recursive = False - - file_patterns = data.get("FILE_PATTERNS", default_file_patterns) - exclude_patterns = data.get("EXCLUDE_PATTERNS", default_exclude_patterns) - - # We're running in the top-level directory, but the doxygen - # configuration file is in the same directory as node; this means - # that relative pathnames in node must be adjusted before they can - # go onto the sources list - conf_dir = os.path.dirname(str(node)) - - for node in data.get("INPUT", []): - if not os.path.isabs(node): - node = os.path.join(conf_dir, node) - if os.path.isfile(node): - sources.append(node) - elif os.path.isdir(node): - if recursive: - for root, dirs, files in os.walk(node): - for f in files: - filename = os.path.join(root, f) - - pattern_check = reduce(lambda x, y: x or bool(fnmatch(filename, y)), file_patterns, False) - exclude_check = reduce(lambda x, y: x and fnmatch(filename, y), exclude_patterns, True) - - if pattern_check and not exclude_check: - sources.append(filename) - else: - for pattern in file_patterns: - sources.extend(glob.glob("/".join([node, pattern]))) - - # Add tagfiles to the list of source files: - for node in data.get("TAGFILES", []): - file = node.split("=")[0] - if not os.path.isabs(file): - file = os.path.join(conf_dir, file) - sources.append(file) - - # Add additional files to the list of source files: - def append_additional_source(option): - file = data.get(option, "") - if file != "": - if not os.path.isabs(file): - file = os.path.join(conf_dir, file) - if os.path.isfile(file): - sources.append(file) - - append_additional_source("HTML_STYLESHEET") - append_additional_source("HTML_HEADER") - append_additional_source("HTML_FOOTER") - - sources = map( lambda path: env.File(path), sources ) - return sources - - -def DoxySourceScanCheck(node, env): - """Check if we should scan this file""" - return os.path.isfile(node.path) - -def DoxyEmitter(source, target, env): - """Doxygen Doxyfile emitter""" - # possible output formats and their default values and output locations - output_formats = { - "HTML": ("YES", "html"), - "LATEX": ("YES", "latex"), - "RTF": ("NO", "rtf"), - "MAN": ("YES", "man"), - "XML": ("NO", "xml"), - } - - data = DoxyfileParse(source[0].get_contents()) - - targets = [] - out_dir = data.get("OUTPUT_DIRECTORY", ".") - if not os.path.isabs(out_dir): - conf_dir = os.path.dirname(str(source[0])) - out_dir = os.path.join(conf_dir, out_dir) - - # add our output locations - for (k, v) in output_formats.items(): - if data.get("GENERATE_" + k, v[0]) == "YES": - targets.append(env.Dir( os.path.join(out_dir, data.get(k + "_OUTPUT", v[1]))) ) - - # add the tag file if neccessary: - tagfile = data.get("GENERATE_TAGFILE", "") - if tagfile != "": - if not os.path.isabs(tagfile): - conf_dir = os.path.dirname(str(source[0])) - tagfile = os.path.join(conf_dir, tagfile) - targets.append(env.File(tagfile)) - - # don't clobber targets - for node in targets: - env.Precious(node) - - # set up cleaning stuff - for node in targets: - env.Clean(node, node) - - return (targets, source) - -def generate(env): - """ - Add builders and construction variables for the - Doxygen tool. This is currently for Doxygen 1.4.6. - """ - doxyfile_scanner = env.Scanner( - DoxySourceScan, - "DoxySourceScan", - scan_check = DoxySourceScanCheck, - ) - - import SCons.Builder - doxyfile_builder = SCons.Builder.Builder( - action = "cd ${SOURCE.dir} && ${DOXYGEN} ${SOURCE.file}", - emitter = DoxyEmitter, - target_factory = env.fs.Entry, - single_source = True, - source_scanner = doxyfile_scanner, - ) - - env.Append(BUILDERS = { - 'Doxygen': doxyfile_builder, - }) - - env.AppendUnique( - DOXYGEN = 'doxygen', - ) - -def exists(env): - """ - Make sure doxygen exists. - """ - return env.Detect("doxygen")