def GetVersionAndDirectory(noexc=False): verexp = re.compile(r"\d+\.\d+\.\d+(\.\d+)?") hspec = excons.GetArgument("with-houdini") if hspec is None: msg = "Please set Houdini version or directory using with-houdini=" if not noexc: raise Exception(msg) else: excons.WarnOnce(msg, tool="houdini") return (None, None) if not os.path.isdir(hspec): ver = hspec if not verexp.match(ver): msg = "Invalid Houdini version format: \"%s\"" % ver if not noexc: raise Exception(msg) else: excons.WarnOnce(msg, tool="houdini") return (None, None) if sys.platform == "win32": if excons.arch_dir == "x64": hfs = "C:/Program Files/Side Effects Software/Houdini %s" % ver else: hfs = "C:/Program Files (x86)/Side Effects Software/Houdini %s" % ver elif sys.platform == "darwin": hfs = "/Library/Frameworks/Houdini.framework/Versions/%s/Resources" % ver else: hfs = "/opt/hfs%s" % ver else: # retrive version from hfs hfs = hspec m = verexp.search(hfs) if not m: msg = "Could not figure out houdini version from path \"%s\". Please provide it using houdini-ver=" % hfs if not noexc: raise Exception(msg) else: excons.WarnOnce(msg, tool="houdini") return (None, None) else: ver = m.group(0) if sys.platform == "darwin": # Path specified by with-houdini should point the the version folder # Append the "Resources" as is expected in HFS environment variable hfs += "/Resources" if not os.path.isdir(hfs): msg = "Invalid Houdini directory: %s" % hfs if not noexc: raise Exception(msg) else: excons.WarnOnce(msg, tool="houdini") return (None, None) return (ver, hfs)
def Require(env): nukespec = excons.GetArgument("with-nuke") if nukespec is None: excons.WarnOnce("Please set Nuke version or directory using with-nuke=", tool="nuke") return idn = ("Contents/MacOS/include" if sys.platform == "darwin" else "include") ldn = ("Contents/MacOS" if sys.platform == "darwin" else "") if os.path.isdir(nukespec): if sys.platform == "darwin": bn = os.path.basename(nukespec) _, ext = os.path.splitext(bn) if ext != ".app": nukespec += "/%s.app" % bn excons.SetArgument("with-nuke", nukespec) ndkinc, ndklib = excons.GetDirs("nuke", incdirname=idn, libdirname=ldn, libdirarch="none") else: if not re.match(r"\d+\.\d+v\d+", nukespec): excons.WarnOnce("Invalid Nuke version format: \"%s\"" % nukespec, tool="nuke") return if sys.platform == "win32": ndkbase = "C:/Program Files/Nuke%s" % nukespec elif sys.platform == "darwin": ndkbase = "/Applications/Nuke%s/Nuke%s.app" % (nukespec, nukespec) else: ndkbase = "/usr/local/Nuke%s" % nukespec ndkinc = "%s/%s" % (ndkbase, idn) ndklib = "%s/%s" % (ndkbase, ldn) if ldn else ndkbase if ndkinc: env.Append(CPPPATH=[ndkinc]) if ndklib: env.Append(LIBPATH=[ndklib]) if sys.platform == "darwin": #env.Append(CCFLAGS=" -isysroot /Developer/SDKs/MacOSX10.4u.sdk") #env.Append(LINKFLAGS=" -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk") #env.Append(LINKFLAGS=" -framework QuartzCore -framework IOKit -framework CoreFoundation -framework Carbon -framework ApplicationServices -framework OpenGL -framework AGL -framework Quicktime") pass env.Append(DEFINES=["USE_GLEW"]) if sys.platform != "win32": env.Append(CCFLAGS=" -Wno-unused-variable -Wno-unused-parameter") env.Append(LIBS=["DDImage", "GLEW"]) else: env.Append(LIBS=["DDImage", "glew32"])
def Require(min_version=None, require_rtti=False, require_exceptions=False, components=None): cfg = GetLLVMConfig(components) if min_version is not None: rmaj, rmin = None, None if type(min_version) in (str, unicode): try: rmaj, rmin = map(int, min_version.split(".")) except Exception, e: excons.WarnOnce("Invalid version requirement '%s' (%s). Skip version check." % (min_version, e), tool="llvm") elif type(min_version) in (list, tuple): try: rmaj, rmin = int(min_version[0]), int(min_version[1]) except Exception, e: excons.WarnOnce("Invalid version requirement %s (%s). Skip version check." % (min_version, e), tool="llvm")
def Require(env): arnoldinc, arnoldlib = excons.GetDirs( "arnold", libdirname=("bin" if sys.platform != "win32" else "lib")) if arnoldinc: env.Append(CPPPATH=[arnoldinc]) if arnoldlib: env.Append(LIBPATH=[arnoldlib]) aver = Version(asString=False) if aver[0] >= 5: if sys.platform == "win32": if float(excons.mscver) < 14: excons.WarnOnce( "Arnold 5 and above require Visual Studio 2015 or newer (mscver 14.0)" ) if aver[0] >= 6: if sys.platform != "win32": if not excons.GetArgument("use-c++11", 0, int): excons.SetArgument("use-c++11", 1) if not "-std=c++11" in " ".join(env["CXXFLAGS"]): env.Append(CXXFLAGS=" -std=c++11") env.Append(LIBS=["ai"]) excons.AddHelpOptions(arnold=GetOptionsString())
def Version(asString=True, nice=False): mayadir = GetMayaRoot(noWarn=True) if not mayadir: return (None if not asString else "") mayainc = GetMayaInc(mayadir) mayaspec = excons.GetArgument("with-maya") if mayaspec is not None and not os.path.isdir(mayaspec): wantedver = mayaspec else: wantedver = None mtypes = excons.joinpath(mayainc, "maya", "MTypes.h") if os.path.isfile(mtypes): defexp = re.compile(r"^\s*#define\s+MAYA_API_VERSION\s+([0-9]+)") f = open(mtypes, "r") for line in f.readlines(): m = defexp.match(line) if m: year = int(m.group(1)[:4]) sub = int(m.group(1)[4]) if wantedver is not None: usever = "%d%s" % (year, ".5" if sub >= 5 else "") if usever != wantedver: excons.WarnOnce( "Maya headers version (%s) doesn't seem to match requested one (%s).\nMake sure to set or reset devkit path using 'with-mayadevkit=' flag." % (usever, wantedver)) if nice: # Maya 2013 and 2016 have a binary incompatible .5 version if sub >= 5 and year in (2013, 2016): return (year + 0.5 if not asString else "%d.5" % year) else: return (year if not asString else str(year)) else: return (int(m.group(1)) if not asString else m.group(1)) f.close() excons.WarnOnce("Cannot find maya headers (missing with-mayadevkit= ?).") return (None if not asString else "")
def Require(env): excons.AddHelpOptions(maya=GetOptionsString()) mayadir = GetMayaRoot() if not mayadir: return env.Append(CPPPATH=[GetMayaInc(mayadir)]) env.Append(CPPDEFINES=["REQUIRE_IOSTREAM", "_BOOL"]) if sys.platform == "darwin": env.Append(CPPDEFINES=["OSMac_"]) env.Append(CPPFLAGS=" -Wno-unused-private-field") env.Append(LIBPATH=["%s/Maya.app/Contents/MacOS" % mayadir]) mach = "%s/maya/OpenMayaMac.h" % GetMayaInc(mayadir) if os.path.isfile(mach): env.Append(CCFLAGS=" -include \"%s\" -fno-gnu-keywords" % mach) maya_ver = Version(asString=False, nice=True) if maya_ver: # Starting Maya 2017, on osx libc++ is used instead of libstdc++ # Before this version, and unless explicitely overridden by 'use-c++11=' command line flag, use c++0x and libstdc++ if maya_ver < 2017: excons.WarnOnce( "Maya below 2017 requires linking against libstdc++.\nThis can be done using by using the command line flag 'use-stdc++=1'.", tool="maya") # Starting Maya 2018, Maya API is using C++11 standard if maya_ver >= 2018: env.Append(CPPFLAGS=" -std=c++11") else: env.Append(LIBPATH=["%s/lib" % mayadir]) if sys.platform == "win32": env.Append(CPPDEFINES=["NT_PLUGIN"]) else: maya_ver = Version(asString=False, nice=True) # Starting Maya 2018, Maya API is using C++11 standard if maya_ver and maya_ver >= 2018: env.Append(CPPFLAGS=" -std=c++11") env.Append(CPPDEFINES=["LINUX"]) env.Append( CPPFLAGS= " -fno-strict-aliasing -Wno-comment -Wno-sign-compare -funsigned-char -Wno-reorder -fno-gnu-keywords -pthread" ) env.Append(LIBS=[ "OpenMaya", "OpenMayaAnim", "OpenMayaFX", "OpenMayaRender", "OpenMayaUI", "Foundation" ])
def GetMayaRoot(noWarn=False): mayaspec = excons.GetArgument("with-maya") if "MAYA_LOCATION" in os.environ: if not "with-maya" in SCons.Script.ARGUMENTS: # MAYA_LOCATION environment is set and with-maya is either undefined or read from cache excons.PrintOnce("Using MAYA_LOCATION environment.", tool="maya") mayadir = os.environ["MAYA_LOCATION"] return mayadir else: excons.PrintOnce("Ignoring MAYA_LOCATION environment.", tool="maya") if not mayaspec: if not noWarn: #excons.WarnOnce("Please set Maya version or directory using with-maya=", tool="maya") excons.WarnConfig() return None if not os.path.isdir(mayaspec): if not re.match(r"\d+(\.\d+)?", mayaspec): if not noWarn: excons.WarnOnce( "Invalid Maya specification \"%s\": Must be a directory or a version number" % mayaspec, tool="maya") return None ver = mayaspec if sys.platform == "win32": if excons.arch_dir == "x64": mayadir = "C:/Program Files/Autodesk/Maya%s" % ver else: mayadir = "C:/Program Files (x86)/Autodesk/Maya%s" % ver elif sys.platform == "darwin": mayadir = "/Applications/Autodesk/maya%s" % ver else: mayadir = "/usr/autodesk/maya%s" % ver if excons.arch_dir == "x64" and os.path.isdir(mayadir + "-x64"): mayadir += "-x64" else: mayadir = mayaspec.replace("\\", "/") if len(mayadir) > 0 and mayadir[-1] == "/": mayadir = mayadir[:-1] return mayadir
def GenerateFile(outpath, inpath, opts, pattern=None): if pattern is not None: phexp = re.compile(pattern) else: phexp = re.compile(r"@([^@]+)@") with open(outpath, "wb") as outf: with open(inpath, "rb") as inf: for line in inf.readlines(): m = phexp.search(line) while m is not None: for keyi in xrange(len(m.groups())): key = m.group(1 + keyi) if key is None: continue elif not key in opts: excons.WarnOnce( "No value for placeholder '%s' in %s" % (key, inpath)) else: line = line.replace(m.group(0), opts[key]) break m = phexp.search(line) outf.write(line)
def _RealRequire(env): global ThreadSafe_exp, Szlib_exp, Zlib_exp, hdf5_confs hdf5_inc, hdf5_lib = excons.GetDirs("hdf5") if hdf5_inc: env.Append(CPPPATH=[hdf5_inc]) if hdf5_lib: env.Append(LIBPATH=[hdf5_lib]) hdf5_libname = excons.GetArgument("hdf5-libname", None) if not hdf5_libname: hdf5_libsuffix = excons.GetArgument("hdf5-libsuffix", "") hdf5_basename = ("hdf5" if sys.platform != "win32" else "libhdf5") hdf5_libname = hdf5_basename + hdf5_libsuffix hdf5hl_libname = hdf5_basename + "_hl" + hdf5_libsuffix else: hdf5hl_libname = hdf5_libname + "_hl" if hl: env.Append(LIBS=[hdf5hl_libname, hdf5_libname]) else: env.Append(LIBS=[hdf5_libname]) hdf5_static = (excons.GetArgument("hdf5-static", 0, int) != 0) hdf5_threadsafe = False hdf5_szip = False hdf5_zlib = False h5conf = None if hdf5_inc: # Note: On Fedora 14, H5pubconf.h has been renamed to H5pubconf-64.h # -> be slightly more flexible when looking up this file lst = filter(lambda x: os.path.basename(x).startswith("H5pubconf"), glob.glob(hdf5_inc + "/*.h")) if len(lst) > 0: h5conf = lst[0].replace("\\", "/") else: # Look in current include paths for d in env["CPPPATH"]: lst = filter( lambda x: os.path.basename(x).startswith("H5pubconf"), glob.glob(d + "/*.h")) if len(lst) > 0: h5conf = lst[0].replace("\\", "/") break quiet = not verbose if h5conf: if h5conf in hdf5_confs: hdf5_threadsafe = hdf5_confs[h5conf]["threadsafe"] hdf5_zlib = hdf5_confs[h5conf]["zlib"] hdf5_szip = hdf5_confs[h5conf]["szip"] quiet = True else: if verbose: excons.PrintOnce("Reading configuration header '%s'..." % h5conf, tool="hdf5") f = open(h5conf, "r") for l in f.readlines(): l = l.strip() if ThreadSafe_exp.match(l): hdf5_threadsafe = True elif Szip_exp.match(l): hdf5_szip = True elif Zlib_exp.match(l): hdf5_zlib = True hdf5_confs[h5conf] = { "threadsafe": hdf5_threadsafe, "zlib": hdf5_zlib, "szip": hdf5_szip } f.close() if not quiet: if hdf5_threadsafe: excons.PrintOnce("Thread safe", tool="hdf5") if hdf5_zlib: excons.PrintOnce("Using zlib", tool="hdf5") if hdf5_szip: excons.PrintOnce("Using szip", tool="hdf5") else: excons.WarnOnce("Could not find configuration header", tool="hdf5") if hdf5_static: if not quiet: excons.PrintOnce("Static build", tool="hdf5") if hdf5_threadsafe: threads.Require(env) if hdf5_zlib: if excons.GetArgument("zlib-static", None) is None: if not quiet: excons.PrintOnce("Force static zlib", tool="hdf5") excons.SetArgument("zlib-static", 1) zlib.Require(env) if hdf5_szip: szip_static = excons.GetArgument("szip-static", None) if szip_static is None: if not quiet: excons.PrintOnce("Force static szip", tool="hdf5") excons.SetArgument("szip-static", 1) szip.Require(env)
def GenerateFile(outpath, inpath, opts, pattern=None, optgroup=None, converters=None, replacefuncs=None): # Converters must convert opts value to strings # When no defined, str() is used if pattern is not None: if optgroup is None: raise Exception( "Please specify 'optgroup' when using a custom pattern") phexp = re.compile(pattern) qualifiergrp = None else: # @VAR_NAME@ # @VAR_NAME.defined@ # @VAR_NAME.undefined@ # @VAR_NAME.equal(otherval)@ # @VAR_NAME.not_equal(otherval)@ # @VAR_NAME.match(expr)@ # @VAR_NAME.not_match(expr)@ # @VAR_NAME.greater(numeric)@ # @VAR_NAME.greater_or_equal(numeric)@ # @VAR_NAME.lesser(numeric)@ # @VAR_NAME.lesser_or_equal(numeric)@ phexp = re.compile(r"@([^@.]+)(?:\.([^@.]+))?@") qlexp = re.compile( r"defined|undefined|(?:(equal|greater|lesser|greater_or_equal|lesser_or_equal|match|not_equal|not_match)\(([^)]+)\))" ) optgroup = 1 qualifiergrp = 2 if converters is None: converters = {} # value -> string def _convertvalue(v): vt = type(v) if vt in converters: return converters[vt](v) elif not isinstance(v, basestring): return str(v) else: return v with open(outpath, "wb") as outf: with open(inpath, "rb") as inf: for line in inf.readlines(): if replacefuncs is not None: for replacefunc in replacefuncs: line = replacefunc(line, opts) remain = line[:] outline = "" m = phexp.search(remain) while m is not None: outline += remain[:m.start()] matched = m.group() remain = remain[m.end():] key = m.group(optgroup) if not key in opts: val = None else: val = opts[key] if qualifiergrp is not None and m.group(qualifiergrp): qm = qlexp.match(m.group(qualifiergrp)) if qm is None: excons.WarnOnce("Invalid qualifier for '%s': %s" % (key, m.group(qualifiergrp))) else: qualifier = qm.group(0) if qualifier == "defined": val = (val is not None) elif qualifier == "undefined": val = (val is None) else: qualifier = qm.group(1) qval = qm.group(2) if qualifier == "equal": val = (_convertvalue(val) == qval) elif qualifier == "not_equal": val = (_convertvalue(val) != qval) elif qualifier == "greater": val = (float(val) > float(qval)) elif qualifier == "greater_or_equal": val = (float(val) >= float(qval)) elif qualifier == "lesser": val = (float(val) < float(qval)) elif qualifier == "lesser_or_equal": val = (float(val) <= float(qval)) elif qualifier == "match": val = (re.match(qval, val) is not None) elif qualifier == "not_match": val = (re.match(qval, val) is None) else: excons.WarnOnce( "Unexpected qualifier for %s: %s" % (key, qualifier)) val = None if val is None: excons.WarnOnce("No value for placeholder '%s' in %s" % (key, inpath)) else: matched = matched.replace(m.group(0), _convertvalue(val)) outline += matched m = phexp.search(remain) outline += remain outf.write(outline)
def GetConf(env, incdir): h5conf = None cfg = {"threadsafe": False, "zlib": False, "szip": False} quiet = not verbose if incdir: # Note: On Fedora 14, H5pubconf.h has been renamed to H5pubconf-64.h # -> be slightly more flexible when looking up this file lst = filter(lambda x: os.path.basename(x).startswith("H5pubconf"), excons.glob(incdir + "/*.h")) if len(lst) > 0: h5conf = lst[0].replace("\\", "/") else: # Look in current include paths for d in env["CPPPATH"]: lst = filter( lambda x: os.path.basename(x).startswith("H5pubconf"), excons.glob(d + "/*.h")) if len(lst) > 0: h5conf = lst[0].replace("\\", "/") break if h5conf: if h5conf in hdf5_confs: quiet = True cfg = hdf5_confs[h5conf] else: if verbose: excons.PrintOnce("Reading configuration header '%s'..." % h5conf, tool="hdf5") f = open(h5conf, "r") for l in f.readlines(): l = l.strip() if ThreadSafe_exp.match(l): cfg["threadsafe"] = True elif Szip_exp.match(l): cfg["szip"] = True elif Zlib_exp.match(l): cfg["zlib"] = True hdf5_confs[h5conf] = cfg f.close() if not quiet: if cfg["threadsafe"]: excons.PrintOnce("Thread safe", tool="hdf5") if cfg["zlib"]: excons.PrintOnce("Using zlib", tool="hdf5") if cfg["szip"]: excons.PrintOnce("Using szip", tool="hdf5") else: excons.WarnOnce("Could not find configuration header", tool="hdf5") return (False, cfg)
def GetLLVMConfig(components=None): global llvm_cfg if llvm_cfg is None: exesuffix = ("" if sys.platform != "win32" else ".exe") llvm_incdir, llvm_libdir = excons.GetDirs("llvm", silent=False) llvm_config = None if llvm_incdir: path = os.path.dirname(llvm_incdir) + "/bin/llvm-config" + exesuffix if os.path.isfile(path): llvm_config = path if llvm_config is None: if llvm_libdir: path = os.path.dirname(llvm_libdir) + "/bin/llvm-config" + exesuffix if os.path.isfile(path): llvm_config = path if llvm_config is None: for d in os.environ["PATH"].split(os.pathsep): path = d + "/llvm-config" + exesuffix if os.path.isfile(path): llvm_config = path break if llvm_config is None: excons.WarnOnce("Could not find 'llvm-config'", tool="llvm") sys.exit(1) excons.PrintOnce("Use '%s'" % llvm_config, tool="llvm") llvm_cfg = {} procargs = {"shell": True, "stdout": subprocess.PIPE, "stderr": subprocess.STDOUT} if llvm_incdir: llvm_cfg["incdir"] = llvm_incdir if llvm_libdir: llvm_cfg["libdir"] = llvm_libdir cmd = "%s --version" % llvm_config p = subprocess.Popen(cmd, **procargs) out, _ = p.communicate() if p.returncode == 0: llvm_cfg["version_str"] = out.strip() spl = llvm_cfg["version_str"].split(".") llvm_cfg["version_major"] = int(spl[0]) llvm_cfg["version_minor"] = int(spl[1]) else: excons.WarnOnce("'%s' command failed." % cmd, tool="llvm") llvm_cfg["verison_str"] = "" llvm_cfg["verison_major"] = 0 llvm_cfg["verison_minor"] = 0 cmd = "%s --cppflags" % llvm_config p = subprocess.Popen(cmd, **procargs) out, _ = p.communicate() if p.returncode == 0: cppflags = out.strip() llvm_cfg["cppflags"] = " " + " ".join(filter(lambda x: not _IsIncludeFlag(x), _FlagsToList(cppflags))) else: excons.WarnOnce("'%s' command failed." % cmd, tool="llvm") llvm_cfg["cppflags"] = "" cmd = "%s --cxxflags" % llvm_config p = subprocess.Popen(cmd, **procargs) out, _ = p.communicate() if p.returncode == 0: cxxflags = _FlagsToList(out.strip()) if sys.platform != "win32": llvm_cfg["rtti"] = (not "-fno-rtti" in cxxflags) llvm_cfg["exceptions"] = (not "-fno-exceptions" in cxxflags) else: llvm_cfg["rtti"] = (not "/GR-" in cxxflags) llvm_cfg["exceptions"] = (not "/EHs-c-" in cxxflags) else: excons.WarnOnce("'%s' command failed." % cmd, tool="llvm") cmd = "%s --libs" % llvm_config if components: if type(components) in (str, unicode): cmd += " %s" % components elif type(components) in (tuple, list, set): cmd += " %s" % " ".join(components) else: excons.WarnOnce("'components' should either be a string or a list of strings.", tool="llvm") p = subprocess.Popen(cmd, **procargs) out, _ = p.communicate() if p.returncode == 0: libs = [] for l in out.split("\n"): lst = map(_LibName, (_FlagsToList(l) if sys.platform == "win32" else _CleanList(l.split("-l")))) libs.extend(lst) llvm_cfg["libs"] = libs else: excons.WarnOnce("'%s' command failed." % cmd, tool="llvm") llvm_cfg["libs"] = [] cmd = "%s --system-libs" % llvm_config p = subprocess.Popen(cmd, **procargs) out, _ = p.communicate() if p.returncode == 0: libs = [] for l in out.split("\n"): lst = map(_LibName, (_FlagsToList(l) if sys.platform == "win32" else _CleanList(l.split("-l")))) libs.extend(lst) llvm_cfg["syslibs"] = libs else: excons.WarnOnce("'%s' command failed." % cmd, tool="llvm") llvm_cfg["syslibs"] = [] return llvm_cfg
if min_version is not None: rmaj, rmin = None, None if type(min_version) in (str, unicode): try: rmaj, rmin = map(int, min_version.split(".")) except Exception, e: excons.WarnOnce("Invalid version requirement '%s' (%s). Skip version check." % (min_version, e), tool="llvm") elif type(min_version) in (list, tuple): try: rmaj, rmin = int(min_version[0]), int(min_version[1]) except Exception, e: excons.WarnOnce("Invalid version requirement %s (%s). Skip version check." % (min_version, e), tool="llvm") if rmaj is not None and rmin is not None: if cfg["version_major"] != rmaj: excons.WarnOnce("Unsupported LLVM version %d.%d." % (cfg["version_major"], cfg["version_minor"])) sys.exit(1) if cfg["version_minor"] < rmin: excons.WarnOnce("Unsupported LLVM version %d.%d." % (cfg["version_major"], cfg["version_minor"])) sys.exit(1) if require_rtti and not cfg["rtti"]: excons.WarnOnce("Require LLVM with RTTI enabled.", tool="llvm") sys.exit(1) if require_exceptions and not cfg["exceptions"]: excons.WarnOnce("Require LLVM with exceptions enabled.", tool="llvm") sys.exit(1) def _RequireLLVM(env): env.Append(CPPFLAGS=cfg["cppflags"])