2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-19 16:32:16 +00:00
Files
python/SConscript

241 lines
9.2 KiB
Python

# -*- python -*-
# Copyright Jim Bosch 2010-2012.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
# Big thanks to Mike Jarvis for help with the configuration prescriptions below.
import os
import sys
import subprocess
from SCons.SConf import CheckContext
def setupPaths(env, prefix, include, lib):
if prefix is not None:
if include is None:
include = os.path.join(prefix, "include")
if lib is None:
lib = os.path.join(prefix, "lib")
if include:
env.PrependUnique(CPPPATH=[include])
if lib:
env.PrependUnique(LIBPATH=[lib])
AddMethod(Environment, setupPaths)
def checkLibs(context, try_libs, source_file):
init_libs = context.env.get('LIBS', [])
context.env.PrependUnique(LIBS=[try_libs])
result = context.TryLink(source_file, '.cpp')
if not result :
context.env.Replace(LIBS=init_libs)
return result
AddMethod(CheckContext, checkLibs)
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.'
return False
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 context.env["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)
return False
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."
return False
if context.env["PLATFORM"] == "darwin":
context.env["LDMODULESUFFIX"] = ".so"
context.Result(1)
return True
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.'
return False
context.env.Append(CPPPATH=numpy.get_include())
result = context.checkLibs([''],numpy_source_file)
if not result:
context.Result(0)
print "Cannot build against NumPy."
return False
result, output = context.TryRun(numpy_source_file,'.cpp')
if not result:
context.Result(0)
print "Cannot run program built with NumPy."
return False
context.Result(1)
return True
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... ')
context.env.setupPaths(
prefix = GetOption("boost_prefix"),
include = GetOption("boost_include"),
lib = GetOption("boost_lib")
)
result = (
context.checkLibs([''], bp_source_file) or
context.checkLibs(['boost_python'], bp_source_file) or
context.checkLibs(['boost_python-mt'], bp_source_file)
)
if not result:
context.Result(0)
print "Cannot build against Boost.Python."
return False
result, output = context.TryRun(bp_source_file, '.cpp')
if not result:
context.Result(0)
print "Cannot run program built against Boost.Python."
return False
context.Result(1)
return True
# Setup command-line options
def setupOptions():
AddOption("--prefix", dest="prefix", type="string", nargs=1, action="store",
metavar="DIR", default="/usr/local", help="installation prefix")
AddOption("--install-headers", dest="install_headers", type="string", nargs=1, action="store",
metavar="DIR", help="location to install header files (overrides --prefix for headers)")
AddOption("--install-lib", dest="install_lib", type="string", nargs=1, action="store",
metavar="DIR", help="location to install libraries (overrides --prefix for libraries)")
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")
AddOption("--rpath", dest="custom_rpath", type="string", action="append",
help="runtime link paths to add to libraries and executables; may be passed more than once")
variables = Variables()
variables.Add("CCFLAGS", default=os.environ.get("CCFLAGS", "-O2 -g"), help="compiler flags")
return variables
def makeEnvironment(variables):
shellEnv = {}
for key in ("PATH", "LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH", "PYTHONPATH"):
if key in os.environ:
shellEnv[key] = os.environ[key]
env = Environment(variables=variables, ENV=shellEnv)
if os.environ.has_key("CCFLAGS"):
env.AppendUnique(CCFLAGS = os.environ["CCFLAGS"])
custom_rpath = GetOption("custom_rpath")
if custom_rpath is not None:
env.AppendUnique(RPATH=custom_rpath)
boost_lib = GetOption ('boost_lib')
if boost_lib is not None:
env.PrependUnique(LIBPATH=boost_lib)
return env
def setupTargets(env, root="."):
lib = SConscript(os.path.join(root, "libs", "numpy", "src", "SConscript"), exports='env')
example = SConscript(os.path.join(root, "libs", "numpy", "example", "SConscript"), exports='env')
test = SConscript(os.path.join(root, "libs", "numpy", "test", "SConscript"), exports='env')
prefix = Dir(GetOption("prefix")).abspath
install_headers = GetOption('install_headers')
install_lib = GetOption('install_lib')
if not install_headers:
install_headers = os.path.join(prefix, "include")
if not install_lib:
install_lib = os.path.join(prefix, "lib")
env.Alias("install", env.Install(install_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(install_headers, "boost", "numpy"),
os.path.join(root, "boost", "numpy", header)))
env.Alias("install", env.Install(os.path.join(install_headers, "boost"),
os.path.join(root, "boost", "numpy.hpp")))
checks = {"CheckPython": CheckPython, "CheckNumPy": CheckNumPy, "CheckBoostPython": CheckBoostPython}
Return("setupOptions", "makeEnvironment", "setupTargets", "checks")