+ main.Append(CCFLAGS="-Wno-uninitialized")
+
+# Check for SWIG
+if not main.has_key('SWIG'):
+ print 'Error: SWIG utility not found.'
+ print ' Please install (see http://www.swig.org) and retry.'
+ Exit(1)
+
+# Check for appropriate SWIG version
+swig_version = readCommand(('swig', '-version'), exception='').split()
+# First 3 words should be "SWIG Version x.y.z"
+if len(swig_version) < 3 or \
+ swig_version[0] != 'SWIG' or swig_version[1] != 'Version':
+ print 'Error determining SWIG version.'
+ Exit(1)
+
+min_swig_version = '1.3.28'
+if compareVersions(swig_version[2], min_swig_version) < 0:
+ print 'Error: SWIG version', min_swig_version, 'or newer required.'
+ print ' Installed version:', swig_version[2]
+ Exit(1)
+
+# Set up SWIG flags & scanner
+swig_flags=Split('-c++ -python -modern -templatereduce $_CPPINCFLAGS')
+main.Append(SWIGFLAGS=swig_flags)
+
+# filter out all existing swig scanners, they mess up the dependency
+# stuff for some reason
+scanners = []
+for scanner in main['SCANNERS']:
+ skeys = scanner.skeys
+ if skeys == '.i':
+ continue
+
+ if isinstance(skeys, (list, tuple)) and '.i' in skeys:
+ continue
+
+ scanners.append(scanner)
+
+# add the new swig scanner that we like better
+from SCons.Scanner import ClassicCPP as CPPScanner
+swig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
+scanners.append(CPPScanner("SwigScan", [ ".i" ], "CPPPATH", swig_inc_re))
+
+# replace the scanners list that has what we want
+main['SCANNERS'] = scanners
+
+# Add a custom Check function to the Configure context so that we can
+# figure out if the compiler adds leading underscores to global
+# variables. This is needed for the autogenerated asm files that we
+# use for embedding the python code.
+def CheckLeading(context):
+ context.Message("Checking for leading underscore in global variables...")
+ # 1) Define a global variable called x from asm so the C compiler
+ # won't change the symbol at all.
+ # 2) Declare that variable.
+ # 3) Use the variable
+ #
+ # If the compiler prepends an underscore, this will successfully
+ # link because the external symbol 'x' will be called '_x' which
+ # was defined by the asm statement. If the compiler does not
+ # prepend an underscore, this will not successfully link because
+ # '_x' will have been defined by assembly, while the C portion of
+ # the code will be trying to use 'x'
+ ret = context.TryLink('''
+ asm(".globl _x; _x: .byte 0");
+ extern int x;
+ int main() { return x; }
+ ''', extension=".c")
+ context.env.Append(LEADING_UNDERSCORE=ret)
+ context.Result(ret)
+ return ret
+
+# Platform-specific configuration. Note again that we assume that all
+# builds under a given build root run on the same host platform.
+conf = Configure(main,
+ conf_dir = joinpath(build_root, '.scons_config'),
+ log_file = joinpath(build_root, 'scons_config.log'),
+ custom_tests = { 'CheckLeading' : CheckLeading })
+
+# Check for leading underscores. Don't really need to worry either
+# way so don't need to check the return code.
+conf.CheckLeading()
+
+# Check if we should compile a 64 bit binary on Mac OS X/Darwin
+try:
+ import platform
+ uname = platform.uname()
+ if uname[0] == 'Darwin' and compareVersions(uname[2], '9.0.0') >= 0:
+ if int(readCommand('sysctl -n hw.cpu64bit_capable')[0]):
+ main.Append(CCFLAGS='-arch x86_64')
+ main.Append(CFLAGS='-arch x86_64')
+ main.Append(LINKFLAGS='-arch x86_64')
+ main.Append(ASFLAGS='-arch x86_64')
+except:
+ pass
+
+# Recent versions of scons substitute a "Null" object for Configure()
+# when configuration isn't necessary, e.g., if the "--help" option is
+# present. Unfortuantely this Null object always returns false,
+# breaking all our configuration checks. We replace it with our own
+# more optimistic null object that returns True instead.
+if not conf:
+ def NullCheck(*args, **kwargs):
+ return True
+
+ class NullConf:
+ def __init__(self, env):
+ self.env = env
+ def Finish(self):
+ return self.env
+ def __getattr__(self, mname):
+ return NullCheck
+
+ conf = NullConf(main)
+
+# Find Python include and library directories for embedding the
+# interpreter. For consistency, we will use the same Python
+# installation used to run scons (and thus this script). If you want
+# to link in an alternate version, see above for instructions on how
+# to invoke scons with a different copy of the Python interpreter.
+from distutils import sysconfig
+
+py_getvar = sysconfig.get_config_var
+
+py_version = 'python' + py_getvar('VERSION')
+
+py_general_include = sysconfig.get_python_inc()
+py_platform_include = sysconfig.get_python_inc(plat_specific=True)
+py_includes = [ py_general_include ]
+if py_platform_include != py_general_include:
+ py_includes.append(py_platform_include)
+
+py_lib_path = [ py_getvar('LIBDIR') ]
+# add the prefix/lib/pythonX.Y/config dir, but only if there is no
+# shared library in prefix/lib/.
+if not py_getvar('Py_ENABLE_SHARED'):
+ py_lib_path.append(py_getvar('LIBPL'))
+
+py_libs = []
+for lib in py_getvar('LIBS').split() + py_getvar('SYSLIBS').split():
+ assert lib.startswith('-l')
+ lib = lib[2:]
+ if lib not in py_libs:
+ py_libs.append(lib)
+py_libs.append(py_version)
+
+main.Append(CPPPATH=py_includes)
+main.Append(LIBPATH=py_lib_path)
+
+# verify that this stuff works
+if not conf.CheckHeader('Python.h', '<>'):
+ print "Error: can't find Python.h header in", py_includes
+ Exit(1)
+
+for lib in py_libs:
+ if not conf.CheckLib(lib):
+ print "Error: can't find library %s required by python" % lib
+ Exit(1)