diff --git a/build/SConscript.configure b/build/SConscript.configure index 17e0dd1b..f8ced232 100644 --- a/build/SConscript.configure +++ b/build/SConscript.configure @@ -30,7 +30,7 @@ if needsBuildDependencies and not os.path.exists(GetBuildPath('#dependencies')): print 'at http://www.mitsuba-renderer.org/docs.html for details on how to get them.\n' Exit(1) -python_versions = ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3"] +python_versions = ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4"] # Parse configuration options vars = Variables(configFile) diff --git a/build/SConscript.install b/build/SConscript.install index 4b2db0b2..daede3df 100644 --- a/build/SConscript.install +++ b/build/SConscript.install @@ -1,6 +1,6 @@ import fnmatch -Import('env', 'os', 'sys', 'plugins', 'dist', +Import('env', 'os', 'sys', 'plugins', 'dist', 'MTS_VERSION', 'hasQt', 'hasCollada', 'hasPython', 'hasBreakpad') installTargets = [] @@ -73,7 +73,7 @@ if sys.platform == 'win32': install(distDir, ['libcore/libmitsuba-core.dll', 'libhw/libmitsuba-hw.dll', 'librender/libmitsuba-render.dll', 'libbidir/libmitsuba-bidir.dll']) install(sdkLibDir, ['libcore/mitsuba-core.lib', 'libhw/mitsuba-hw.lib', - 'librender/mitsuba-render.lib', 'libbidir/mitsuba-bidir.lib']) + 'librender/mitsuba-render.lib', 'libbidir/mitsuba-bidir.lib']) for entry in os.walk(os.path.join(basePath, "include")): includeDir = entry[0][len(basePath)+1:] installTargets += env.Install(os.path.join(sdkDir, includeDir), diff --git a/build/config-linux-gcc-debug.py b/build/config-linux-gcc-debug.py index b106d704..ccd1d7e4 100644 --- a/build/config-linux-gcc-debug.py +++ b/build/config-linux-gcc-debug.py @@ -23,20 +23,13 @@ COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4'] COLLADALIB = ['collada14dom', 'xml2'] FFTWLIB = ['fftw3_threads', 'fftw3'] -# The following assumes that the Mitsuba bindings should be built for the -# "default" Python version. It is also possible to build bindings for multiple -# versions at the same time by explicitly specifying e.g. PYTHON27INCLUDE, -# PYTHON27LIB, PYTHON27LIBDIR and PYTHON32INCLUDE, PYTHON32LIB, PYTHON32LIBDIR - -pyver = os.popen("python --version 2>&1 | grep -oE '([[:digit:]].[[:digit:]])'").read().strip().replace('.', '') -env = locals() - -env['PYTHON'+pyver+'INCLUDE'] = [] -env['PYTHON'+pyver+'LIB'] = ['boost_python-mt-py'+pyver] - -for entry in os.popen("python-config --cflags --libs").read().split(): - if entry[:2] == '-I': - env['PYTHON'+pyver+'INCLUDE'] += [entry[2:]] - if entry[:2] == '-l': - env['PYTHON'+pyver+'LIB'] += [entry[2:]] +# The following runs a helper script to search for installed Python +# packages that have a Boost Python library of matching version. +# A Mitsuba binding library will be compiled for each such pair. +# Alternatively, you could also specify the paths and libraries manually +# using the variables PYTHON27INCLUDE, PYTHON27LIB, PYTHON27LIBDIR etc. +import sys, os +sys.path.append(os.path.abspath('../data/scons')) +from detect_python import detect_python +locals().update(detect_python()) diff --git a/build/config-linux-gcc.py b/build/config-linux-gcc.py index 0d97a1be..5bc8b6ae 100644 --- a/build/config-linux-gcc.py +++ b/build/config-linux-gcc.py @@ -23,19 +23,14 @@ COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4'] COLLADALIB = ['collada14dom', 'xml2'] FFTWLIB = ['fftw3_threads', 'fftw3'] -# The following assumes that the Mitsuba bindings should be built for the -# "default" Python version. It is also possible to build bindings for multiple -# versions at the same time by explicitly specifying e.g. PYTHON27INCLUDE, -# PYTHON27LIB, PYTHON27LIBDIR and PYTHON32INCLUDE, PYTHON32LIB, PYTHON32LIBDIR +# The following runs a helper script to search for installed Python +# packages that have a Boost Python library of matching version. +# A Mitsuba binding library will be compiled for each such pair. +# Alternatively, you could also specify the paths and libraries manually +# using the variables PYTHON27INCLUDE, PYTHON27LIB, PYTHON27LIBDIR etc. -pyver = os.popen("python --version 2>&1 | grep -oE '([[:digit:]].[[:digit:]])'").read().strip().replace('.', '') -env = locals() +import sys, os +sys.path.append(os.path.abspath('../data/scons')) +from detect_python import detect_python +locals().update(detect_python()) -env['PYTHON'+pyver+'INCLUDE'] = [] -env['PYTHON'+pyver+'LIB'] = ['boost_python-mt-py'+pyver] - -for entry in os.popen("python-config --cflags --libs").read().split(): - if entry[:2] == '-I': - env['PYTHON'+pyver+'INCLUDE'] += [entry[2:]] - if entry[:2] == '-l': - env['PYTHON'+pyver+'LIB'] += [entry[2:]] diff --git a/build/config-linux-icl.py b/build/config-linux-icl.py index 65d5d4d7..78630802 100644 --- a/build/config-linux-icl.py +++ b/build/config-linux-icl.py @@ -23,19 +23,13 @@ COLLADAINCLUDE = ['/usr/include/collada-dom', '/usr/include/collada-dom/1.4'] COLLADALIB = ['collada14dom', 'xml2'] FFTWLIB = ['fftw3_threads', 'fftw3'] -# The following assumes that the Mitsuba bindings should be built for the -# "default" Python version. It is also possible to build bindings for multiple -# versions at the same time by explicitly specifying e.g. PYTHON27INCLUDE, -# PYTHON27LIB, PYTHON27LIBDIR and PYTHON32INCLUDE, PYTHON32LIB, PYTHON32LIBDIR +# The following runs a helper script to search for installed Python +# packages that have a Boost Python library of matching version. +# A Mitsuba binding library will be compiled for each such pair. +# Alternatively, you could also specify the paths and libraries manually +# using the variables PYTHON27INCLUDE, PYTHON27LIB, PYTHON27LIBDIR etc. -pyver = os.popen("python --version 2>&1 | grep -oE '([[:digit:]].[[:digit:]])'").read().strip().replace('.', '') -env = locals() - -env['PYTHON'+pyver+'INCLUDE'] = [] -env['PYTHON'+pyver+'LIB'] = ['boost_python-mt-py'+pyver] - -for entry in os.popen("python-config --cflags --libs").read().split(): - if entry[:2] == '-I': - env['PYTHON'+pyver+'INCLUDE'] += [entry[2:]] - if entry[:2] == '-l': - env['PYTHON'+pyver+'LIB'] += [entry[2:]] +import sys, os +sys.path.append(os.path.abspath('../data/scons')) +from detect_python import detect_python +locals().update(detect_python()) diff --git a/data/scons/detect_python.py b/data/scons/detect_python.py new file mode 100644 index 00000000..c5a9627b --- /dev/null +++ b/data/scons/detect_python.py @@ -0,0 +1,79 @@ +# Detect present Python & Boost-python libraries on Linux +import os + +class PkgConfig(dict): + _paths = ['/usr/lib/pkgconfig', '/usr/lib/x86_64-linux-gnu/pkgconfig'] + + def __init__(self, name): + for path in self._paths: + fn = os.path.join(path, '%s.pc' % name) + if os.path.exists(fn): + self._parse(fn) + break + + def _parse(self, filename): + from string import Template + + lines = open(filename).readlines() + localVariables = {} + + for line in lines: + line = line.strip() + if not line or line.startswith('#'): + continue + elif ':' in line: + name, val = line.split(':') + val = val.strip() + if '$' in val: + val = Template(val).substitute(localVariables) + self[name] = val + elif '=' in line: + name, val = line.split('=') + val = val.strip() + if '$' in val: + val = Template(val).substitute(localVariables) + localVariables[name] = val + +def find_boost_python(version): + libnames = [ + 'boost_python-mt-py%s' % version, + 'boost_python-py%s' % version, + 'boost_python' + ('3' if version.startswith('3') else '') + ] + basepaths = ['/lib', '/usr/lib'] + + for basepath in basepaths: + for libname in libnames: + if os.path.isfile(os.path.join(basepath, "lib" + libname + ".so")): + return libname + return None + +def detect_python(): + pyver = ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4'] + pyenv = {} + + for version in pyver: + pkgconfig = PkgConfig('python-%s' % version) + version = version.replace('.', '') + flags = [] + if 'Cflags' in pkgconfig: + flags += pkgconfig['Cflags'].split() + if 'Libs' in pkgconfig: + flags += pkgconfig['Libs'].split() + if len(flags) == 0: + continue + boost_libname = find_boost_python(version) + print(boost_libname) + if boost_libname == None: + continue + pyenv['PYTHON' + version + 'INCLUDE'] = [] + pyenv['PYTHON' + version + 'LIBDIR'] = [] + pyenv['PYTHON' + version + 'LIB'] = [ boost_libname ] + for flag in flags: + if flag.startswith('-I'): + pyenv['PYTHON' + version + 'INCLUDE'] += [flag[2:]] + elif flag.startswith('-L'): + pyenv['PYTHON' + version + 'LIBDIR'] += [flag[2:]] + elif flag.startswith('-l'): + pyenv['PYTHON' + version + 'LIB'] += [flag[2:]] + return pyenv