2011-03-01 22:03:37 +08:00
|
|
|
import multiprocessing
|
|
|
|
|
2011-06-01 08:20:53 +08:00
|
|
|
Import('sys', 'os', 'SCons', 'resources')
|
2011-02-03 16:15:25 +08:00
|
|
|
|
|
|
|
AddOption("--cfg", dest="cfg", type="string", nargs=1, action='store', help='Manually specify a configuration file')
|
|
|
|
configFile = GetOption('cfg')
|
|
|
|
if configFile == None:
|
|
|
|
configFile = "config.py"
|
|
|
|
|
|
|
|
configFile = os.path.normpath(os.path.join(os.path.dirname(os.getcwd()), configFile))
|
|
|
|
|
2011-03-01 22:03:37 +08:00
|
|
|
AddOption("--parallelize", dest="parallelize", action='store_true', help='Parallelize to the available number of cores?')
|
|
|
|
parallelize = GetOption('parallelize')
|
|
|
|
|
|
|
|
if parallelize == True:
|
|
|
|
SetOption('num_jobs', multiprocessing.cpu_count())
|
|
|
|
|
2011-02-03 16:15:25 +08:00
|
|
|
if not os.path.exists(configFile):
|
2011-06-01 08:20:53 +08:00
|
|
|
print 'A configuration file must be selected! Have a look at http://www.mitsuba-renderer.org/docs.html'
|
2011-02-03 16:15:25 +08:00
|
|
|
Exit(1)
|
|
|
|
|
|
|
|
if (sys.platform == 'win32' or sys.platform == 'darwin') and not os.path.exists(GetBuildPath('#dependencies')):
|
|
|
|
print 'The dependencies are missing -- see http://www.mitsuba-renderer.org/devblog/archives/11-Build-system-changes.html'
|
|
|
|
Exit(1)
|
|
|
|
|
|
|
|
# Parse configuration options
|
|
|
|
vars = Variables(configFile)
|
2011-06-01 08:20:53 +08:00
|
|
|
vars.Add('BUILDDIR', 'Target directory for intermediate files')
|
2011-02-03 16:15:25 +08:00
|
|
|
vars.Add('CXX', 'C++ compiler')
|
|
|
|
vars.Add('CC', 'C compiler')
|
|
|
|
vars.Add('CXXFLAGS', 'C++ flags')
|
|
|
|
vars.Add('CCFLAGS', 'C compiler flags')
|
|
|
|
vars.Add('SHCXXFLAGS', 'C++ flags (for shared libraries)')
|
|
|
|
vars.Add('LINK', 'Linker')
|
|
|
|
vars.Add('LINKFLAGS', 'Linker flags')
|
|
|
|
vars.Add('SHLINKFLAGS', 'Linker flags (dynamic libraries)')
|
|
|
|
vars.Add('BASEINCLUDE', 'Base include path')
|
|
|
|
vars.Add('BASELIB', 'Base libraries')
|
|
|
|
vars.Add('BASELIBDIR', 'Base library search path')
|
|
|
|
vars.Add('XERCESINCLUDE', 'Xerces-C include path')
|
|
|
|
vars.Add('XERCESLIB', 'Xerces-C libraries')
|
|
|
|
vars.Add('XERCESLIBDIR', 'Xerces-C library path')
|
|
|
|
vars.Add('OEXRINCLUDE', 'OpenEXR include path')
|
|
|
|
vars.Add('OEXRLIB', 'OpenEXR libraries')
|
|
|
|
vars.Add('OEXRFLAGS', 'OpenEXR-related compiler flags')
|
|
|
|
vars.Add('OEXRLIBDIR', 'OpenEXR library path')
|
|
|
|
vars.Add('PNGINCLUDE', 'libpng include path')
|
|
|
|
vars.Add('PNGLIB', 'libpng libraries')
|
|
|
|
vars.Add('PNGLIBDIR', 'libpng library path')
|
|
|
|
vars.Add('JPEGINCLUDE', 'libjpeg include path')
|
|
|
|
vars.Add('JPEGLIB', 'libjpeg libraries')
|
|
|
|
vars.Add('JPEGLIBDIR', 'libjpeg library path')
|
|
|
|
vars.Add('COLLADAINCLUDE','COLLADA DOM include path')
|
|
|
|
vars.Add('COLLADALIB', 'COLLADA DOM libraries')
|
|
|
|
vars.Add('COLLADALIBDIR', 'COLLADA DOM library path')
|
|
|
|
vars.Add('SHLIBPREFIX', 'Prefix for shared libraries')
|
|
|
|
vars.Add('SHLIBSUFFIX', 'Suffix for shared libraries')
|
|
|
|
vars.Add('PROGSUFFIX', 'Suffix for executables')
|
|
|
|
vars.Add('GLLIB', 'OpenGL+GLEW libraries')
|
|
|
|
vars.Add('GLINCLUDE', 'OpenGL+GLEW include path')
|
|
|
|
vars.Add('GLFLAGS', 'OpenGL+GLEW-related compiler flags')
|
|
|
|
vars.Add('GLLIBDIR', 'OpenGL+GLEW library path')
|
|
|
|
vars.Add('BOOSTINCLUDE', 'Boost include path')
|
|
|
|
vars.Add('BOOSTLIB', 'Boost libraries')
|
|
|
|
vars.Add('BOOSTLIBDIR', 'Boost library path')
|
|
|
|
vars.Add('TARGET_ARCH', 'Target architecture')
|
|
|
|
vars.Add('MSVC_VERSION', 'MS Visual C++ compiler version')
|
|
|
|
vars.Add('QTDIR', 'Qt installation directory')
|
2011-06-02 00:46:00 +08:00
|
|
|
vars.Add('INTEL_COMPILER','Should the Intel C++ compiler be used?')
|
2011-02-03 16:15:25 +08:00
|
|
|
|
|
|
|
try:
|
2011-06-02 00:32:55 +08:00
|
|
|
env = Environment(options=vars, ENV = os.environ, tools=['default', 'qt4', 'icl12'], toolpath=['#data/scons'])
|
2011-02-03 16:15:25 +08:00
|
|
|
print 'Checking for Qt 4.x... yes'
|
|
|
|
hasQt = True
|
|
|
|
except Exception:
|
2011-06-02 00:32:55 +08:00
|
|
|
env = Environment(options=vars, ENV = os.environ, tools=['default', 'icl12'], toolpath=['#data/scons'])
|
2011-02-03 16:15:25 +08:00
|
|
|
print 'Unable to detect a Qt installation -- not building the GUI!'
|
|
|
|
hasQt = False
|
|
|
|
|
|
|
|
hasCollada=True
|
|
|
|
env.Append(CPPPATH=env['BASEINCLUDE'])
|
|
|
|
env.Append(CPPFLAGS=[])
|
|
|
|
env.Append(LIBPATH=[])
|
|
|
|
env.Append(LIBS=env['BASELIB'])
|
|
|
|
if env.has_key('BOOSTINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['BOOSTINCLUDE'])
|
|
|
|
if env.has_key('BOOSTLIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['BOOSTLIBDIR'])
|
|
|
|
if env.has_key('BOOSTLIB'):
|
|
|
|
env.Prepend(LIBS=env['BOOSTLIB'])
|
|
|
|
if env.has_key('BASELIBDIR'):
|
|
|
|
env.Append(LIBPATH=env['BASELIBDIR'])
|
|
|
|
|
|
|
|
env.Decider('MD5-timestamp')
|
|
|
|
|
2011-03-01 22:03:37 +08:00
|
|
|
AddOption("--dist", dest="dist", action="store_true", help='Make an official release')
|
2011-02-03 16:15:25 +08:00
|
|
|
|
|
|
|
# Check whether everything important is available
|
|
|
|
def CheckCXX(context):
|
|
|
|
context.Message('Checking for ' + env['CXX'] + ' ...')
|
|
|
|
ret = context.TryLink("#include <sstream>\n int main(int argc, char **argv) {\n std::ostringstream oss;\n return 0;\n }", '.cpp')
|
|
|
|
context.Result(ret)
|
|
|
|
return ret
|
|
|
|
|
|
|
|
conf = Configure(env, custom_tests = { 'CheckCXX' : CheckCXX })
|
|
|
|
cppPathPrevious = SCons.Util.semi_deepcopy(env['CPPPATH'])
|
|
|
|
libPathPrevious = SCons.Util.semi_deepcopy(env['LIBPATH'])
|
|
|
|
cppFlagsPrevious = SCons.Util.semi_deepcopy(env['CPPFLAGS'])
|
|
|
|
cxxFlagsPrevious = SCons.Util.semi_deepcopy(env['CXXFLAGS'])
|
|
|
|
|
|
|
|
if env.has_key('PNGINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['PNGINCLUDE'])
|
|
|
|
if env.has_key('PNGLIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['PNGLIBDIR'])
|
|
|
|
if env.has_key('JPEGINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['JPEGINCLUDE'])
|
|
|
|
if env.has_key('JPEGLIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['JPEGLIBDIR'])
|
|
|
|
if env.has_key('OEXRFLAGS'):
|
|
|
|
env.Prepend(CPPFLAGS=env['OEXRFLAGS'])
|
|
|
|
if env.has_key('OEXRINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['OEXRINCLUDE'])
|
|
|
|
if env.has_key('OEXRLIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['OEXRLIBDIR'])
|
|
|
|
if env.has_key('XERCESINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['XERCESINCLUDE'])
|
|
|
|
if env.has_key('XERCESLIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['XERCESLIBDIR'])
|
|
|
|
if env.has_key('GLINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['GLINCLUDE'])
|
|
|
|
if env.has_key('GLFLAGS'):
|
|
|
|
env.Prepend(CPPFLAGS=env['GLFLAGS'])
|
|
|
|
if env.has_key('COLLADAINCLUDE'):
|
|
|
|
env.Prepend(CPPPATH=env['COLLADAINCLUDE'])
|
|
|
|
if env.has_key('COLLADALIBDIR'):
|
|
|
|
env.Prepend(LIBPATH=env['COLLADALIBDIR'])
|
|
|
|
|
|
|
|
if not conf.CheckCXX():
|
|
|
|
print 'Could not compile a simple C++ fragment, verify that ' + \
|
|
|
|
env['CXX'] + ' is installed! This could also mean that the ' + \
|
|
|
|
'Boost libraries are missing. The file "config.log" should ' + \
|
|
|
|
'contain more information.'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCHeader(['png.h']):
|
|
|
|
print 'libpng is missing (install libpng12-dev)'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCHeader(['stdio.h', 'jpeglib.h']):
|
|
|
|
print 'libjpeg is missing (install libjpeg62-dev)'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCXXHeader('ImfRgba.h'):
|
|
|
|
print 'OpenEXR is missing (install libopenexr-dev)'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCXXHeader('xercesc/dom/DOMLSParser.hpp'):
|
|
|
|
print 'Xerces-C++ 3.x must be installed (install libxerces-c-dev)!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCXXHeader('dae.h'):
|
|
|
|
hasCollada = False
|
|
|
|
print 'COLLADA DOM is missing: not building the COLLADA importer'
|
|
|
|
if not conf.CheckCXXHeader('boost/math/distributions/students_t.hpp'):
|
|
|
|
print 'Boost is missing (install libboost-dev)!'
|
|
|
|
Exit(1)
|
|
|
|
if sys.platform == 'win32':
|
|
|
|
if not (conf.CheckCHeader(['windows.h', 'GL/gl.h']) \
|
|
|
|
and conf.CheckCHeader(['windows.h', 'GL/glu.h']) \
|
|
|
|
and conf.CheckCHeader(['windows.h', 'GL/gl.h', 'GL/glext.h'])):
|
|
|
|
print 'OpenGL headers are missing!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCHeader('GL/glew.h'):
|
|
|
|
print 'GLEW headers are missing!'
|
|
|
|
Exit(1)
|
|
|
|
elif sys.platform == 'linux2':
|
|
|
|
if not (conf.CheckCHeader('GL/gl.h') and conf.CheckCHeader('GL/glu.h') and conf.CheckCHeader(['GL/gl.h', 'GL/glext.h'])):
|
|
|
|
print 'OpenGL headers are missing!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCHeader('GL/glew.h'):
|
|
|
|
print 'GLEW headers are missing (install libglewmx1.5-dev)!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckType('GLEWContext', '#include <GL/glew.h>'):
|
|
|
|
print 'GLEW-MX must be present!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.TryCompile("#include <GL/glew.h>\n int i = GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV;", '.cpp'):
|
|
|
|
print 'Your version of GLEW-MX seems to be outdated!'
|
|
|
|
Exit(1)
|
|
|
|
elif sys.platform == 'darwin':
|
|
|
|
if not (conf.CheckCHeader('OpenGL/gl.h') and conf.CheckCHeader('OpenGL/glu.h') and conf.CheckCHeader(['OpenGL/gl.h', 'OpenGL/glext.h'])):
|
|
|
|
print 'OpenGL headers are missing!'
|
|
|
|
Exit(1)
|
|
|
|
if not conf.CheckCHeader('OpenGL/glew.h'):
|
|
|
|
print 'GLEW headers are missing!'
|
|
|
|
Exit(1)
|
|
|
|
if sys.platform == 'linux2':
|
|
|
|
if not (conf.CheckCHeader(['X11/Xlib.h', 'X11/extensions/xf86vmode.h'])):
|
|
|
|
print 'X Video Mode selection library headers are missing! (Install libxxf86vm-dev)'
|
|
|
|
Exit(1)
|
|
|
|
|
|
|
|
env.Replace(CPPPATH=cppPathPrevious)
|
|
|
|
env.Replace(LIBPATH=libPathPrevious)
|
|
|
|
env.Replace(CPPFLAGS=cppFlagsPrevious)
|
|
|
|
env.Replace(CXXFLAGS=cxxFlagsPrevious)
|
|
|
|
sys.stdout.write("Checking for Mitsuba version .. ")
|
|
|
|
|
|
|
|
file = open(env.GetBuildPath('#include/mitsuba/mitsuba.h'), 'r')
|
|
|
|
MTS_VERSION=""
|
|
|
|
for line in file:
|
|
|
|
if line.startswith("#define MTS_VERSION "):
|
|
|
|
MTS_VERSION = line[21:len(line)-2]
|
|
|
|
if MTS_VERSION == "":
|
|
|
|
print 'could not be determined!'
|
|
|
|
Exit(1)
|
|
|
|
else:
|
|
|
|
print MTS_VERSION
|
|
|
|
Export('MTS_VERSION')
|
|
|
|
|
|
|
|
env = conf.Finish()
|
2011-06-01 08:20:53 +08:00
|
|
|
|
2011-02-03 16:15:25 +08:00
|
|
|
dist = GetOption('dist') != None
|
|
|
|
Export('dist')
|
|
|
|
|
|
|
|
def osxlibinst_build_function(self, target, source, pkgname = None, use_own = None):
|
|
|
|
inst = self.Install(target, source)
|
|
|
|
prefix, name = os.path.split(source)
|
|
|
|
self.AddPostAction(inst, 'install_name_tool -id @executable_path/../Frameworks/' + name + ' $TARGET')
|
|
|
|
return inst
|
|
|
|
|
|
|
|
env.__class__.OSXLibInst = osxlibinst_build_function
|
|
|
|
|
|
|
|
if hasCollada:
|
|
|
|
env.Append(CPPDEFINES = [['MTS_HAS_COLLADA', 1]] )
|
|
|
|
|
|
|
|
env.SConsignFile()
|
|
|
|
|
|
|
|
# MSVC: Embed the manifest into libraries and executables
|
|
|
|
if sys.platform == 'win32':
|
|
|
|
env['LINKCOM'] = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1']
|
|
|
|
env['SHLINKCOM'] = [env['SHLINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2']
|
|
|
|
|
2011-06-01 08:20:53 +08:00
|
|
|
env.Export('hasQt', 'hasCollada', 'resources')
|
2011-02-03 16:15:25 +08:00
|
|
|
|
|
|
|
Return('env')
|