diff --git a/etc/SuperBuild/USD-patch/build_scripts/build_usd.py b/etc/SuperBuild/USD-patch/build_scripts/build_usd.py deleted file mode 100644 index b0d14424..00000000 --- a/etc/SuperBuild/USD-patch/build_scripts/build_usd.py +++ /dev/null @@ -1,2531 +0,0 @@ -# -# Copyright 2017 Pixar -# -# Licensed under the Apache License, Version 2.0 (the "Apache License") -# with the following modification; you may not use this file except in -# compliance with the Apache License and the following modification to it: -# Section 6. Trademarks. is deleted and replaced with: -# -# 6. Trademarks. This License does not grant permission to use the trade -# names, trademarks, service marks, or product names of the Licensor -# and its affiliates, except as required to comply with Section 4(c) of -# the License and to reproduce the content of the NOTICE file. -# -# You may obtain a copy of the Apache License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the Apache License with the above modification is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the Apache License for the specific -# language governing permissions and limitations under the Apache License. -# -# Check whether this script is being run under Python 2 first. Otherwise, -# any Python 3-only code below will cause the script to fail with an -# unhelpful error message. -import sys -if sys.version_info.major == 2: - sys.exit("ERROR: USD does not support Python 2. Use a supported version " - "of Python 3 instead.") - -import argparse -import codecs -import contextlib -import ctypes -import datetime -import distutils -import fnmatch -import glob -import locale -import multiprocessing -import os -import platform -import re -import shlex -import shutil -import subprocess -import sys -import sysconfig -import zipfile - -from urllib.request import urlopen -from shutil import which - -# Helpers for printing output -verbosity = 1 - -def Print(msg): - if verbosity > 0: - print(msg) - -def PrintWarning(warning): - if verbosity > 0: - print("WARNING:", warning) - -def PrintStatus(status): - if verbosity >= 1: - print("STATUS:", status) - -def PrintInfo(info): - if verbosity >= 2: - print("INFO:", info) - -def PrintCommandOutput(output): - if verbosity >= 3: - sys.stdout.write(output) - -def PrintError(error): - if verbosity >= 3 and sys.exc_info()[1] is not None: - import traceback - traceback.print_exc() - print ("ERROR:", error) - -# Helpers for determining platform -def Windows(): - return platform.system() == "Windows" -def Linux(): - return platform.system() == "Linux" -def MacOS(): - return platform.system() == "Darwin" - -if MacOS(): - import apple_utils - -def GetLocale(): - if Windows(): - # Windows handles encoding a little differently then Linux / Mac - # For interactive streams (isatty() == True) it will use the - # console codepage, otherwise it will return an ANSI codepage. - # To keep things consistent we'll force UTF-8 for non-interactive - # streams (which is recommended by Microsoft). See: - # https://docs.python.org/3.6/library/sys.html#sys.stdout - # https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers - if sys.stdout.isatty(): - return sys.stdout.encoding - else: - return "UTF-8" - - return sys.stdout.encoding or locale.getdefaultlocale()[1] or "UTF-8" - -def GetCommandOutput(command): - """Executes the specified command and returns output or None.""" - try: - return subprocess.check_output( - shlex.split(command), - stderr=subprocess.STDOUT).decode(GetLocale(), 'replace').strip() - except subprocess.CalledProcessError: - pass - return None - -def GetXcodeDeveloperDirectory(): - """Returns the active developer directory as reported by 'xcode-select -p'. - Returns None if none is set.""" - if not MacOS(): - return None - - return GetCommandOutput("xcode-select -p") - -def GetVisualStudioCompilerAndVersion(): - """Returns a tuple containing the path to the Visual Studio compiler - and a tuple for its version, e.g. (14, 0). If the compiler is not found - or version number cannot be determined, returns None.""" - if not Windows(): - return None - - msvcCompiler = which('cl') - if msvcCompiler: - # VisualStudioVersion environment variable should be set by the - # Visual Studio Command Prompt. - match = re.search( - r"(\d+)\.(\d+)", - os.environ.get("VisualStudioVersion", "")) - if match: - return (msvcCompiler, tuple(int(v) for v in match.groups())) - return None - -def IsVisualStudioVersionOrGreater(desiredVersion): - if not Windows(): - return False - - msvcCompilerAndVersion = GetVisualStudioCompilerAndVersion() - if msvcCompilerAndVersion: - _, version = msvcCompilerAndVersion - return version >= desiredVersion - return False - -def IsVisualStudio2022OrGreater(): - VISUAL_STUDIO_2022_VERSION = (17, 0) - return IsVisualStudioVersionOrGreater(VISUAL_STUDIO_2022_VERSION) - -def IsVisualStudio2019OrGreater(): - VISUAL_STUDIO_2019_VERSION = (16, 0) - return IsVisualStudioVersionOrGreater(VISUAL_STUDIO_2019_VERSION) - -def IsVisualStudio2017OrGreater(): - VISUAL_STUDIO_2017_VERSION = (15, 0) - return IsVisualStudioVersionOrGreater(VISUAL_STUDIO_2017_VERSION) - -def GetPythonInfo(context): - """Returns a tuple containing the path to the Python executable, shared - library, and include directory corresponding to the version of Python - currently running. Returns None if any path could not be determined. - - This function is used to extract build information from the Python - interpreter used to launch this script. This information is used - in the Boost and USD builds. By taking this approach we can support - having USD builds for different Python versions built on the same - machine. This is very useful, especially when developers have multiple - versions installed on their machine. - """ - - # If we were given build python info then just use it. - if context.build_python_info: - return (context.build_python_info['PYTHON_EXECUTABLE'], - context.build_python_info['PYTHON_LIBRARY'], - context.build_python_info['PYTHON_INCLUDE_DIR'], - context.build_python_info['PYTHON_VERSION']) - - # First we extract the information that can be uniformly dealt with across - # the platforms: - pythonExecPath = sys.executable - pythonVersion = sysconfig.get_config_var("py_version_short") # "3.7" - - # Lib path is unfortunately special for each platform and there is no - # config_var for it. But we can deduce it for each platform, and this - # logic works for any Python version. - def _GetPythonLibraryFilename(context): - if Windows(): - return "python{version}{suffix}.lib".format( - version=sysconfig.get_config_var("py_version_nodot"), - suffix=('_d' if context.buildDebug and context.debugPython - else '')) - elif Linux(): - return sysconfig.get_config_var("LDLIBRARY") - elif MacOS(): - return "libpython{version}.dylib".format( - version=(sysconfig.get_config_var('LDVERSION') or - sysconfig.get_config_var('VERSION') or - pythonVersion)) - else: - raise RuntimeError("Platform not supported") - - pythonIncludeDir = sysconfig.get_path("include") - if not pythonIncludeDir or not os.path.isdir(pythonIncludeDir): - # as a backup, and for legacy reasons - not preferred because - # it may be baked at build time - pythonIncludeDir = sysconfig.get_config_var("INCLUDEPY") - - # if in a venv, installed_base will be the "original" python, - # which is where the libs are ("base" will be the venv dir) - pythonBaseDir = sysconfig.get_config_var("installed_base") - if Windows(): - pythonLibPath = os.path.join(pythonBaseDir, "libs", - _GetPythonLibraryFilename(context)) - elif Linux(): - pythonMultiarchSubdir = sysconfig.get_config_var("multiarchsubdir") - # Try multiple ways to get the python lib dir - for pythonLibDir in (sysconfig.get_config_var("LIBDIR"), - os.path.join(pythonBaseDir, "lib")): - if pythonMultiarchSubdir: - pythonLibPath = \ - os.path.join(pythonLibDir + pythonMultiarchSubdir, - _GetPythonLibraryFilename(context)) - if os.path.isfile(pythonLibPath): - break - pythonLibPath = os.path.join(pythonLibDir, - _GetPythonLibraryFilename(context)) - if os.path.isfile(pythonLibPath): - break - elif MacOS(): - pythonLibPath = os.path.join(pythonBaseDir, "lib", - _GetPythonLibraryFilename(context)) - else: - raise RuntimeError("Platform not supported") - - return (pythonExecPath, pythonLibPath, pythonIncludeDir, pythonVersion) - -def GetCPUCount(): - try: - return multiprocessing.cpu_count() - except NotImplementedError: - return 1 - -def Run(cmd, logCommandOutput = True): - """Run the specified command in a subprocess.""" - PrintInfo('Running "{cmd}"'.format(cmd=cmd)) - - with codecs.open("log.txt", "a", "utf-8") as logfile: - logfile.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M")) - logfile.write("\n") - logfile.write(cmd) - logfile.write("\n") - - # Let exceptions escape from subprocess calls -- higher level - # code will handle them. - if logCommandOutput: - p = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) - while True: - l = p.stdout.readline().decode(GetLocale(), 'replace') - if l: - logfile.write(l) - PrintCommandOutput(l) - elif p.poll() is not None: - break - else: - p = subprocess.Popen(shlex.split(cmd)) - p.wait() - - if p.returncode != 0: - # If verbosity >= 3, we'll have already been printing out command output - # so no reason to print the log file again. - if verbosity < 3: - with open("log.txt", "r") as logfile: - Print(logfile.read()) - raise RuntimeError("Failed to run '{cmd}'\nSee {log} for more details." - .format(cmd=cmd, log=os.path.abspath("log.txt"))) - -@contextlib.contextmanager -def CurrentWorkingDirectory(dir): - """Context manager that sets the current working directory to the given - directory and resets it to the original directory when closed.""" - curdir = os.getcwd() - os.chdir(dir) - try: yield - finally: os.chdir(curdir) - -def CopyFiles(context, src, dest): - """Copy files like shutil.copy, but src may be a glob pattern.""" - filesToCopy = glob.glob(src) - if not filesToCopy: - raise RuntimeError("File(s) to copy {src} not found".format(src=src)) - - instDestDir = os.path.join(context.instDir, dest) - for f in filesToCopy: - PrintCommandOutput("Copying {file} to {destDir}\n" - .format(file=f, destDir=instDestDir)) - shutil.copy(f, instDestDir) - -def CopyDirectory(context, srcDir, destDir): - """Copy directory like shutil.copytree.""" - instDestDir = os.path.join(context.instDir, destDir) - if os.path.isdir(instDestDir): - shutil.rmtree(instDestDir) - - PrintCommandOutput("Copying {srcDir} to {destDir}\n" - .format(srcDir=srcDir, destDir=instDestDir)) - shutil.copytree(srcDir, instDestDir) - -def AppendCXX11ABIArg(buildFlag, context, buildArgs): - """Append a build argument that defines _GLIBCXX_USE_CXX11_ABI - based on the settings in the context. This may either do nothing - or append an entry to buildArgs like: - - ="-D_GLIBCXX_USE_CXX11_ABI={0, 1}" - - If buildArgs contains settings for buildFlag, those settings will - be merged with the above define.""" - if context.useCXX11ABI is None: - return - - cxxFlags = ["-D_GLIBCXX_USE_CXX11_ABI={}".format(context.useCXX11ABI)] - - # buildArgs might look like: - # ["-DFOO=1", "-DBAR=2", ...] or ["-DFOO=1 -DBAR=2 ...", ...] - # - # See if any of the arguments in buildArgs start with the given - # buildFlag. If so, we want to take whatever that buildFlag has - # been set to and merge it in with the cxxFlags above. - # - # For example, if buildArgs = ['-DCMAKE_CXX_FLAGS="-w"', ...] - # we want to add "-w" to cxxFlags. - splitArgs = [shlex.split(a) for a in buildArgs] - for p in [item for arg in splitArgs for item in arg]: - if p.startswith(buildFlag): - (_, _, flags) = p.partition("=") - cxxFlags.append(flags) - - buildArgs.append('{flag}="{flags}"'.format( - flag=buildFlag, flags=" ".join(cxxFlags))) - -def FormatMultiProcs(numJobs, generator): - tag = "-j" - if generator: - if "Visual Studio" in generator: - tag = "/M:" # This will build multiple projects at once. - elif "Xcode" in generator: - tag = "-j " - - return "{tag}{procs}".format(tag=tag, procs=numJobs) - -def RunCMake(context, force, extraArgs = None): - """Invoke CMake to configure, build, and install a library whose - source code is located in the current working directory.""" - # Create a directory for out-of-source builds in the build directory - # using the name of the current working directory. - if extraArgs is None: - extraArgs = [] - else: - # ensure we can freely modify our extraArgs without affecting caller - extraArgs = list(extraArgs) - - if context.cmakeBuildArgs: - extraArgs.insert(0, context.cmakeBuildArgs) - srcDir = os.getcwd() - instDir = (context.usdInstDir if srcDir == context.usdSrcDir - else context.instDir) - buildDir = os.path.join(context.buildDir, os.path.split(srcDir)[1]) - if force and os.path.isdir(buildDir): - shutil.rmtree(buildDir) - - if not os.path.isdir(buildDir): - os.makedirs(buildDir) - - generator = context.cmakeGenerator - - # On Windows, we need to explicitly specify the generator to ensure we're - # building a 64-bit project. (Surely there is a better way to do this?) - # TODO: figure out exactly what "vcvarsall.bat x64" sets to force x64 - if generator is None and Windows(): - if IsVisualStudio2022OrGreater(): - generator = "Visual Studio 17 2022" - elif IsVisualStudio2019OrGreater(): - generator = "Visual Studio 16 2019" - elif IsVisualStudio2017OrGreater(): - generator = "Visual Studio 15 2017 Win64" - - if generator is not None: - generator = '-G "{gen}"'.format(gen=generator) - - # Note - don't want to add -A (architecture flag) if generator is, ie, Ninja - if IsVisualStudio2019OrGreater() and "Visual Studio" in generator: - generator = generator + " -A x64" - - toolset = context.cmakeToolset - if toolset is not None: - toolset = '-T "{toolset}"'.format(toolset=toolset) - - # On MacOS, enable the use of @rpath for relocatable builds. - osx_rpath = None - if MacOS(): - osx_rpath = "-DCMAKE_MACOSX_RPATH=ON" - - # For macOS cross compilation, set the Xcode architecture flags. - targetArch = apple_utils.GetTargetArch(context) - - if context.targetNative or targetArch == apple_utils.GetHostArch(): - extraArgs.append('-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=YES') - else: - extraArgs.append('-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO') - - extraArgs.append('-DCMAKE_OSX_ARCHITECTURES={0}'.format(targetArch)) - - # We use -DCMAKE_BUILD_TYPE for single-configuration generators - # (Ninja, make), and --config for multi-configuration generators - # (Visual Studio); technically we don't need BOTH at the same - # time, but specifying both is simpler than branching - config = "Release" - if context.buildDebug: - config = "Debug" - elif context.buildRelease: - config = "Release" - elif context.buildRelWithDebug: - config = "RelWithDebInfo" - - # Append extra argument controlling libstdc++ ABI if specified. - AppendCXX11ABIArg("-DCMAKE_CXX_FLAGS", context, extraArgs) - - with CurrentWorkingDirectory(buildDir): - Run('cmake ' - '-DCMAKE_INSTALL_PREFIX="{instDir}" ' - '-DCMAKE_PREFIX_PATH="{depsInstDir}" ' - '-DCMAKE_BUILD_TYPE={config} ' - '{osx_rpath} ' - '{generator} ' - '{toolset} ' - '{extraArgs} ' - '"{srcDir}"' - .format(instDir=instDir, - depsInstDir=context.instDir, - config=config, - srcDir=srcDir, - osx_rpath=(osx_rpath or ""), - generator=(generator or ""), - toolset=(toolset or ""), - extraArgs=(" ".join(extraArgs) if extraArgs else ""))) - Run("cmake --build . --config {config} --target install -- {multiproc}" - .format(config=config, - multiproc=FormatMultiProcs(context.numJobs, generator))) - -def GetCMakeVersion(): - """ - Returns the CMake version as tuple of integers (major, minor) or - (major, minor, patch) or None if an error occured while launching cmake and - parsing its output. - """ - - output_string = GetCommandOutput("cmake --version") - if not output_string: - PrintWarning("Could not determine cmake version -- please install it " - "and adjust your PATH") - return None - - # cmake reports, e.g., "... version 3.14.3" - match = re.search(r"version (\d+)\.(\d+)(\.(\d+))?", output_string) - if not match: - PrintWarning("Could not determine cmake version") - return None - - major, minor, patch_group, patch = match.groups() - if patch_group is None: - return (int(major), int(minor)) - else: - return (int(major), int(minor), int(patch)) - -def PatchFile(filename, patches, multiLineMatches=False): - """Applies patches to the specified file. patches is a list of tuples - (old string, new string).""" - if multiLineMatches: - oldLines = [open(filename, 'r').read()] - else: - oldLines = open(filename, 'r').readlines() - newLines = oldLines - for (oldString, newString) in patches: - newLines = [s.replace(oldString, newString) for s in newLines] - if newLines != oldLines: - PrintInfo("Patching file {filename} (original in {oldFilename})..." - .format(filename=filename, oldFilename=filename + ".old")) - shutil.copy(filename, filename + ".old") - open(filename, 'w').writelines(newLines) - -def DownloadFileWithCurl(url, outputFilename): - # Don't log command output so that curl's progress - # meter doesn't get written to the log file. - Run("curl -k {progress} -L -o {filename} {url}".format( - progress="-#" if verbosity >= 2 else "-s", - filename=outputFilename, url=url), - logCommandOutput=False) - -def DownloadFileWithPowershell(url, outputFilename): - # It's important that we specify to use TLS v1.2 at least or some - # of the downloads will fail. - cmd = "powershell [Net.ServicePointManager]::SecurityProtocol = \ - [Net.SecurityProtocolType]::Tls12; \"(new-object \ - System.Net.WebClient).DownloadFile('{url}', '{filename}')\""\ - .format(filename=outputFilename, url=url) - - Run(cmd,logCommandOutput=False) - -def DownloadFileWithUrllib(url, outputFilename): - r = urlopen(url) - with open(outputFilename, "wb") as outfile: - outfile.write(r.read()) - -def DownloadURL(url, context, force, extractDir = None, - dontExtract = None): - """Download and extract the archive file at given URL to the - source directory specified in the context. - - dontExtract may be a sequence of path prefixes that will - be excluded when extracting the archive. - - Returns the absolute path to the directory where files have - been extracted.""" - with CurrentWorkingDirectory(context.srcDir): - # Extract filename from URL and see if file already exists. - filename = url.split("/")[-1] - if force and os.path.exists(filename): - os.remove(filename) - - if os.path.exists(filename): - PrintInfo("{0} already exists, skipping download" - .format(os.path.abspath(filename))) - else: - PrintInfo("Downloading {0} to {1}" - .format(url, os.path.abspath(filename))) - - # To work around occasional hiccups with downloading from websites - # (SSL validation errors, etc.), retry a few times if we don't - # succeed in downloading the file. - maxRetries = 5 - lastError = None - - # Download to a temporary file and rename it to the expected - # filename when complete. This ensures that incomplete downloads - # will be retried if the script is run again. - tmpFilename = filename + ".tmp" - if os.path.exists(tmpFilename): - os.remove(tmpFilename) - - for i in range(maxRetries): - try: - context.downloader(url, tmpFilename) - break - except Exception as e: - PrintCommandOutput("Retrying download due to error: {err}\n" - .format(err=e)) - lastError = e - else: - errorMsg = str(lastError) - if "SSL: TLSV1_ALERT_PROTOCOL_VERSION" in errorMsg: - errorMsg += ("\n\n" - "Your OS or version of Python may not support " - "TLS v1.2+, which is required for downloading " - "files from certain websites. This support " - "was added in Python 2.7.9." - "\n\n" - "You can use curl to download dependencies " - "by installing it in your PATH and re-running " - "this script.") - raise RuntimeError("Failed to download {url}: {err}" - .format(url=url, err=errorMsg)) - - shutil.move(tmpFilename, filename) - - # Open the archive and retrieve the name of the top-most directory. - # This assumes the archive contains a single directory with all - # of the contents beneath it, unless a specific extractDir is specified, - # which is to be used. - archive = None - rootDir = None - members = None - try: - if zipfile.is_zipfile(filename): - archive = zipfile.ZipFile(filename) - if extractDir: - rootDir = extractDir - else: - rootDir = archive.namelist()[0].split('/')[0] - if dontExtract != None: - members = (m for m in archive.namelist() - if not any((fnmatch.fnmatch(m, p) - for p in dontExtract))) - else: - raise RuntimeError("unrecognized archive file type") - - with archive: - extractedPath = os.path.abspath(rootDir) - if force and os.path.isdir(extractedPath): - shutil.rmtree(extractedPath) - - if os.path.isdir(extractedPath): - PrintInfo("Directory {0} already exists, skipping extract" - .format(extractedPath)) - else: - PrintInfo("Extracting archive to {0}".format(extractedPath)) - - # Extract to a temporary directory then move the contents - # to the expected location when complete. This ensures that - # incomplete extracts will be retried if the script is run - # again. - tmpExtractedPath = os.path.abspath("extract_dir") - if os.path.isdir(tmpExtractedPath): - shutil.rmtree(tmpExtractedPath) - - archive.extractall(tmpExtractedPath, members=members) - - shutil.move(os.path.join(tmpExtractedPath, rootDir), - extractedPath) - shutil.rmtree(tmpExtractedPath) - - return extractedPath - except Exception as e: - # If extraction failed for whatever reason, assume the - # archive file was bad and move it aside so that re-running - # the script will try downloading and extracting again. - shutil.move(filename, filename + ".bad") - raise RuntimeError("Failed to extract archive {filename}: {err}" - .format(filename=filename, err=e)) - -############################################################ -# 3rd-Party Dependencies - -AllDependencies = list() -AllDependenciesByName = dict() - -class Dependency(object): - def __init__(self, name, installer, *files): - self.name = name - self.installer = installer - self.filesToCheck = files - - AllDependencies.append(self) - AllDependenciesByName.setdefault(name.lower(), self) - - def Exists(self, context): - return any([os.path.isfile(os.path.join(context.instDir, f)) - for f in self.filesToCheck]) - -class PythonDependency(object): - def __init__(self, name, getInstructions, moduleNames): - self.name = name - self.getInstructions = getInstructions - self.moduleNames = moduleNames - - def Exists(self, context): - # If one of the modules in our list imports successfully, we are good. - for moduleName in self.moduleNames: - try: - pyModule = __import__(moduleName) - return True - except: - pass - - return False - -def AnyPythonDependencies(deps): - return any([type(d) is PythonDependency for d in deps]) - -############################################################ -# zlib - -ZLIB_URL = "https://github.com/madler/zlib/archive/v1.2.13.zip" - -def InstallZlib(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(ZLIB_URL, context, force)): - RunCMake(context, force, buildArgs) - -ZLIB = Dependency("zlib", InstallZlib, "include/zlib.h") - -############################################################ -# boost - -# The default installation of boost on Windows puts headers in a versioned -# subdirectory, which we have to account for here. Specifying "layout=system" -# would cause the Windows header install to match Linux/MacOS, but the -# "layout=system" flag also changes the naming of the boost dlls in a -# manner that causes problems for dependent libraries that rely on boost's -# trick of automatically linking the boost libraries via pragmas in boost's -# standard include files. Dependencies that use boost's pragma linking -# facility in general don't have enough configuration switches to also coerce -# the naming of the dlls and so it is best to rely on boost's most default -# settings for maximum compatibility. -# -# On behalf of versions of visual studio prior to vs2022, we still support -# boost 1.76. We don't completely know if boost 1.78 is in play on Windows, -# until we have determined whether Python 3 has been selected as a target. -# That isn't known at this point in the script, so we simplify the logic by -# checking for any of the possible boost header locations that are possible -# outcomes from running this script. -BOOST_VERSION_FILES = [ - "include/boost/version.hpp", - "include/boost-1_76/boost/version.hpp", - "include/boost-1_78/boost/version.hpp" -] - -def InstallBoost_Helper(context, force, buildArgs): - # In general we use boost 1.76.0 to adhere to VFX Reference Platform CY2022. - # However, there are some cases where a newer version is required. - # - Building with Python 3.10 requires boost 1.76.0 or newer. - # (https://github.com/boostorg/python/commit/cbd2d9) - # XXX: Due to a typo we've been using 1.78.0 in this case for a while. - # We're leaving it that way to minimize potential disruption. - # - Building with Visual Studio 2022 requires boost 1.78.0 or newer. - # (https://github.com/boostorg/build/issues/735) - # - Building on MacOS requires boost 1.78.0 or newer to resolve Python 3 - # compatibility issues on Big Sur and Monterey. - pyInfo = GetPythonInfo(context) - pyVer = (int(pyInfo[3].split('.')[0]), int(pyInfo[3].split('.')[1])) - if context.buildPython and pyVer >= (3, 10): - BOOST_URL = "https://sourceforge.net/projects/boost/files/boost/1.78.0/boost_1_78_0.zip" - elif IsVisualStudio2022OrGreater(): - BOOST_URL = "https://sourceforge.net/projects/boost/files/boost/1.78.0/boost_1_78_0.zip" - elif MacOS(): - BOOST_URL = "https://sourceforge.net/projects/boost/files/boost/1.78.0/boost_1_78_0.zip" - else: - BOOST_URL = "https://sourceforge.net/projects/boost/files/boost/1.78.0/boost_1_78_0.zip" - - # Documentation files in the boost archive can have exceptionally - # long paths. This can lead to errors when extracting boost on Windows, - # since paths are limited to 260 characters by default on that platform. - # To avoid this, we skip extracting all documentation. - # - # For some examples, see: https://svn.boost.org/trac10/ticket/11677 - dontExtract = [ - "*/doc/*", - "*/libs/*/doc/*", - "*/libs/wave/test/testwave/testfiles/utf8-test-*" - ] - - with CurrentWorkingDirectory(DownloadURL(BOOST_URL, context, force, - dontExtract=dontExtract)): - if Windows(): - bootstrap = "bootstrap.bat" - else: - bootstrap = "./bootstrap.sh" - # zip doesn't preserve file attributes, so force +x manually. - Run('chmod +x ' + bootstrap) - Run('chmod +x ./tools/build/src/engine/build.sh') - - # For cross-compilation on macOS we need to specify the architecture - # for both the bootstrap and the b2 phase of building boost. - bootstrapCmd = '{bootstrap} --prefix="{instDir}"'.format( - bootstrap=bootstrap, instDir=context.instDir) - - macOSArch = "" - - if MacOS(): - if apple_utils.GetTargetArch(context) == \ - apple_utils.TARGET_X86: - macOSArch = "-arch {0}".format(apple_utils.TARGET_X86) - elif apple_utils.GetTargetArch(context) == \ - apple_utils.GetTargetArmArch(): - macOSArch = "-arch {0}".format( - apple_utils.GetTargetArmArch()) - elif context.targetUniversal: - (primaryArch, secondaryArch) = \ - apple_utils.GetTargetArchPair(context) - macOSArch="-arch {0} -arch {1}".format( - primaryArch, secondaryArch) - - if macOSArch: - bootstrapCmd += " cxxflags=\"{0}\" " \ - " cflags=\"{0}\" " \ - " linkflags=\"{0}\"".format(macOSArch) - bootstrapCmd += " --with-toolset=clang" - - Run(bootstrapCmd) - - # b2 supports at most -j64 and will error if given a higher value. - num_procs = min(64, context.numJobs) - - # boost only accepts three variants: debug, release, profile - boostBuildVariant = "profile" - if context.buildDebug: - boostBuildVariant= "debug" - elif context.buildRelease: - boostBuildVariant= "release" - elif context.buildRelWithDebug: - boostBuildVariant= "profile" - - b2_settings = [ - '--prefix="{instDir}"'.format(instDir=context.instDir), - '--build-dir="{buildDir}"'.format(buildDir=context.buildDir), - '-j{procs}'.format(procs=num_procs), - 'address-model=64', - 'link=shared', - 'runtime-link=shared', - 'threading=multi', - 'variant={variant}'.format(variant=boostBuildVariant), - '--with-atomic', - '--with-regex' - ] - - if context.buildPython: - b2_settings.append("--with-python") - pythonInfo = GetPythonInfo(context) - # This is the only platform-independent way to configure these - # settings correctly and robustly for the Boost jam build system. - # There are Python config arguments that can be passed to bootstrap - # but those are not available in boostrap.bat (Windows) so we must - # take the following approach: - projectPath = 'python-config.jam' - with open(projectPath, 'w') as projectFile: - # Note that we must escape any special characters, like - # backslashes for jam, hence the mods below for the path - # arguments. Also, if the path contains spaces jam will not - # handle them well. Surround the path parameters in quotes. - projectFile.write('using python : %s\n' % pythonInfo[3]) - projectFile.write(' : "%s"\n' % pythonInfo[0].replace("\\","/")) - projectFile.write(' : "%s"\n' % pythonInfo[2].replace("\\","/")) - projectFile.write(' : "%s"\n' % os.path.dirname(pythonInfo[1]).replace("\\","/")) - if context.buildDebug and context.debugPython: - projectFile.write(' : on\n') - projectFile.write(' ;\n') - b2_settings.append("--user-config=python-config.jam") - - if context.buildDebug and context.debugPython: - b2_settings.append("python-debugging=on") - - if context.buildOIIO: - b2_settings.append("--with-date_time") - - if context.buildOIIO or context.enableOpenVDB: - b2_settings.append("--with-system") - b2_settings.append("--with-thread") - - if context.enableOpenVDB: - b2_settings.append("--with-iostreams") - - # b2 with -sNO_COMPRESSION=1 fails with the following error message: - # error: at [...]/boost_1_61_0/tools/build/src/kernel/modules.jam:107 - # error: Unable to find file or target named - # error: '/zlib//zlib' - # error: referred to from project at - # error: 'libs/iostreams/build' - # error: could not resolve project reference '/zlib' - - # But to avoid an extra library dependency, we can still explicitly - # exclude the bzip2 compression from boost_iostreams (note that - # OpenVDB uses blosc compression). - b2_settings.append("-sNO_BZIP2=1") - - if context.buildOIIO: - b2_settings.append("--with-filesystem") - - if force: - b2_settings.append("-a") - - if Windows(): - # toolset parameter for Visual Studio documented here: - # https://github.com/boostorg/build/blob/develop/src/tools/msvc.jam - if context.cmakeToolset == "v143": - b2_settings.append("toolset=msvc-14.3") - elif context.cmakeToolset == "v142": - b2_settings.append("toolset=msvc-14.2") - elif context.cmakeToolset == "v141": - b2_settings.append("toolset=msvc-14.1") - elif IsVisualStudio2022OrGreater(): - b2_settings.append("toolset=msvc-14.3") - elif IsVisualStudio2019OrGreater(): - b2_settings.append("toolset=msvc-14.2") - elif IsVisualStudio2017OrGreater(): - b2_settings.append("toolset=msvc-14.1") - - if MacOS(): - # Must specify toolset=clang to ensure install_name for boost - # libraries includes @rpath - b2_settings.append("toolset=clang") - - if macOSArch: - b2_settings.append("cxxflags=\"{0}\"".format(macOSArch)) - b2_settings.append("cflags=\"{0}\"".format(macOSArch)) - b2_settings.append("linkflags=\"{0}\"".format(macOSArch)) - - if context.buildDebug: - b2_settings.append("--debug-configuration") - - # Add on any user-specified extra arguments. - b2_settings += buildArgs - - # Append extra argument controlling libstdc++ ABI if specified. - AppendCXX11ABIArg("cxxflags", context, b2_settings) - - b2 = "b2" if Windows() else "./b2" - Run('{b2} {options} install' - .format(b2=b2, options=" ".join(b2_settings))) - -def InstallBoost(context, force, buildArgs): - # Boost's build system will install the version.hpp header before - # building its libraries. We make sure to remove it in case of - # any failure to ensure that the build script detects boost as a - # dependency to build the next time it's run. - try: - InstallBoost_Helper(context, force, buildArgs) - except: - for versionHeader in [ - os.path.join(context.instDir, f) for f in BOOST_VERSION_FILES - ]: - if os.path.isfile(versionHeader): - try: os.remove(versionHeader) - except: pass - raise - -BOOST = Dependency("boost", InstallBoost, *BOOST_VERSION_FILES) - -############################################################ -# Intel TBB - -if Windows(): - TBB_URL = "https://github.com/oneapi-src/oneTBB/releases/download/v2020.3/tbb-2020.3-win.zip" - TBB_ROOT_DIR_NAME = "tbb" -elif MacOS(): - # On MacOS Intel systems we experience various crashes in tests during - # teardown starting with 2018 Update 2. Until we figure that out, we use - # 2018 Update 1 on this platform. - TBB_URL = "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2020.3.zip" - TBB_INTEL_URL = "https://github.com/oneapi-src/oneTBB/archive/refs/tags/2018_U1.zip" -else: - TBB_URL = "https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2020.3.zip" - -def InstallTBB(context, force, buildArgs): - if Windows(): - InstallTBB_Windows(context, force, buildArgs) - elif MacOS(): - InstallTBB_MacOS(context, force, buildArgs) - else: - InstallTBB_Linux(context, force, buildArgs) - -def InstallTBB_Windows(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(TBB_URL, context, force, - TBB_ROOT_DIR_NAME)): - # On Windows, we simply copy headers and pre-built DLLs to - # the appropriate location. - if buildArgs: - PrintWarning("Ignoring build arguments {}, TBB is " - "not built from source on this platform." - .format(buildArgs)) - - CopyFiles(context, "bin\\intel64\\vc14\\*.*", "bin") - CopyFiles(context, "lib\\intel64\\vc14\\*.*", "lib") - CopyDirectory(context, "include\\serial", "include\\serial") - CopyDirectory(context, "include\\tbb", "include\\tbb") - -def InstallTBB_MacOS(context, force, buildArgs): - tbb_url = TBB_URL if apple_utils.IsTargetArm(context) else TBB_INTEL_URL - with CurrentWorkingDirectory(DownloadURL(tbb_url, context, force)): - # Ensure that the tbb build system picks the proper architecture. - PatchFile("build/macos.clang.inc", - [("-m64", - "-m64 -arch {0}".format(apple_utils.TARGET_X86)), - ("ifeq ($(arch),$(filter $(arch),armv7 armv7s arm64))", - "ifeq ($(arch),$(filter $(arch),armv7 armv7s {0}))" - .format(apple_utils.GetTargetArmArch()))]) - - (primaryArch, secondaryArch) = apple_utils.GetTargetArchPair(context) - - # tbb uses different arch names - if (primaryArch == apple_utils.TARGET_X86): - primaryArch = "intel64" - if (secondaryArch == apple_utils.TARGET_X86): - secondaryArch = "intel64" - - # Install both release and debug builds. - # See comments in InstallTBB_Linux. - def _RunBuild(arch): - if not arch: - return - makeTBBCmd = 'make -j{procs} arch={arch} {buildArgs}'.format( - arch=arch, procs=context.numJobs, - buildArgs=" ".join(buildArgs)) - Run(makeTBBCmd) - - _RunBuild(primaryArch) - _RunBuild(secondaryArch) - - # See comments in InstallTBB_Linux about why we patch the Makefile - # and rerun builds. This is only required for TBB 2020; 2019 and - # earlier build both release and debug, and 2021 has moved to CMake. - if "2020" in tbb_url: - PatchFile("Makefile", [("release", "debug")]) - _RunBuild(primaryArch) - _RunBuild(secondaryArch) - - if context.targetUniversal: - x86Files = glob.glob(os.getcwd() + - "/build/*intel64*_release/libtbb*.*") - armFiles = glob.glob(os.getcwd() + - "/build/*{0}*_release/libtbb*.*".format( - apple_utils.GetTargetArmArch())) - libNames = [os.path.basename(x) for x in x86Files] - x86Dir = os.path.dirname(x86Files[0]) - armDir = os.path.dirname(armFiles[0]) - - apple_utils.CreateUniversalBinaries(context, libNames, x86Dir, armDir) - - x86Files = glob.glob( - os.getcwd() + "/build/*intel64*_debug/libtbb*.*") - armFiles = glob.glob( - os.getcwd() + "/build/*{0}*_debug/libtbb*.*".format( - apple_utils.GetTargetArmArch())) - if x86Files and armFiles: - libNames = [os.path.basename(x) for x in x86Files] - x86Dir = os.path.dirname(x86Files[0]) - armDir = os.path.dirname(armFiles[0]) - - apple_utils.CreateUniversalBinaries(context, libNames, x86Dir, armDir) - else: - CopyFiles(context, "build/*_release/libtbb*.*", "lib") - CopyFiles(context, "build/*_debug/libtbb*.*", "lib") - - CopyDirectory(context, "include/serial", "include/serial") - CopyDirectory(context, "include/tbb", "include/tbb") - -def InstallTBB_Linux(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(TBB_URL, context, force)): - # Append extra argument controlling libstdc++ ABI if specified. - AppendCXX11ABIArg("CXXFLAGS", context, buildArgs) - - # TBB does not support out-of-source builds in a custom location. - makeTBBCmd = 'make -j{procs} {buildArgs}'.format( - procs=context.numJobs, - buildArgs=" ".join(buildArgs)) - Run(makeTBBCmd) - - # Install both release and debug builds. USD requires the debug - # libraries when building in debug mode, and installing both - # makes it easier for users to install dependencies in some - # location that can be shared by both release and debug USD - # builds. - # - # As of TBB 2020 the build no longer produces a debug build along - # with the release build. There is also no way to specify a debug - # build when running make, even though the internals of the build - # still support it. - # - # To workaround this, we patch the Makefile to change "release" to - # "debug" and re-run the build, copying the debug libraries - # afterwards. - # - # See https://github.com/oneapi-src/oneTBB/issues/207/ - PatchFile("Makefile", [("release", "debug")]) - Run(makeTBBCmd) - - CopyFiles(context, "build/*_release/libtbb*.*", "lib") - CopyFiles(context, "build/*_debug/libtbb*.*", "lib") - CopyDirectory(context, "include/serial", "include/serial") - CopyDirectory(context, "include/tbb", "include/tbb") - -TBB = Dependency("TBB", InstallTBB, "include/tbb/tbb.h") - -############################################################ -# JPEG - -JPEG_URL = "https://github.com/libjpeg-turbo/libjpeg-turbo/archive/2.0.1.zip" - -def InstallJPEG(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(JPEG_URL, context, force)): - extraJPEGArgs = buildArgs - if not which("nasm"): - extraJPEGArgs.append("-DWITH_SIMD=FALSE") - - RunCMake(context, force, extraJPEGArgs) - return os.getcwd() - -JPEG = Dependency("JPEG", InstallJPEG, "include/jpeglib.h") - -############################################################ -# TIFF - -TIFF_URL = "https://gitlab.com/libtiff/libtiff/-/archive/v4.0.7/libtiff-v4.0.7.zip" - -def InstallTIFF(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(TIFF_URL, context, force)): - # libTIFF has a build issue on Windows where tools/tiffgt.c - # unconditionally includes unistd.h, which does not exist. - # To avoid this, we patch the CMakeLists.txt to skip building - # the tools entirely. We do this on Linux and MacOS as well - # to avoid requiring some GL and X dependencies. - # - # We also need to skip building tests, since they rely on - # the tools we've just elided. - PatchFile("CMakeLists.txt", - [("add_subdirectory(tools)", "# add_subdirectory(tools)"), - ("add_subdirectory(test)", "# add_subdirectory(test)")]) - - # The libTIFF CMakeScript says the ld-version-script - # functionality is only for compilers using GNU ld on - # ELF systems or systems which provide an emulation; therefore - # skipping it completely on mac and windows. - if MacOS() or Windows(): - extraArgs = ["-Dld-version-script=OFF"] - else: - extraArgs = [] - extraArgs += buildArgs - RunCMake(context, force, extraArgs) - -TIFF = Dependency("TIFF", InstallTIFF, "include/tiff.h") - -############################################################ -# PNG - -PNG_URL = "https://github.com/glennrp/libpng/archive/refs/tags/v1.6.38.zip" - -def InstallPNG(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(PNG_URL, context, force)): - macArgs = [] - if MacOS() and apple_utils.IsTargetArm(context): - # Ensure libpng's build doesn't erroneously activate inappropriate - # Neon extensions - macArgs = ["-DCMAKE_C_FLAGS=\"-DPNG_ARM_NEON_OPT=0\""] - - if context.targetUniversal: - PatchFile("scripts/genout.cmake.in", - [("CMAKE_OSX_ARCHITECTURES", - "CMAKE_OSX_INTERNAL_ARCHITECTURES")]) - - RunCMake(context, force, buildArgs + macArgs) - -PNG = Dependency("PNG", InstallPNG, "include/png.h") - -############################################################ -# IlmBase/OpenEXR - -OPENEXR_URL = "https://github.com/AcademySoftwareFoundation/openexr/archive/refs/tags/v3.1.11.zip" - -def InstallOpenEXR(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(OPENEXR_URL, context, force)): - RunCMake(context, force, - ['-DOPENEXR_INSTALL_TOOLS=OFF', - '-DOPENEXR_INSTALL_EXAMPLES=OFF', - - # Force OpenEXR to build and use a separate Imath library - # instead of looking for one externally. This ensures that - # OpenEXR and other dependencies use the Imath library - # built via this script. - '-DOPENEXR_FORCE_INTERNAL_IMATH=ON', - '-DBUILD_TESTING=OFF'] + buildArgs) - -OPENEXR = Dependency("OpenEXR", InstallOpenEXR, "include/OpenEXR/ImfVersion.h") - -############################################################ -# Ptex - -PTEX_URL = "https://github.com/wdas/ptex/archive/refs/tags/v2.4.2.zip" -PTEX_VERSION = "v2.4.2" - -def InstallPtex(context, force, buildArgs): - cmakeOptions = [ - '-DBUILD_TESTING=OFF', - '-DPTEX_BUILD_STATIC_LIBS=OFF', - # We must tell the Ptex build system what version we're building - # otherwise we get errors when running CMake. - '-DPTEX_VER={v}'.format(v=PTEX_VERSION) - ] - cmakeOptions += buildArgs - - with CurrentWorkingDirectory(DownloadURL(PTEX_URL, context, force)): - RunCMake(context, force, cmakeOptions) - -PTEX = Dependency("Ptex", InstallPtex, "include/PtexVersion.h") - -############################################################ -# BLOSC (Compression used by OpenVDB) - -# Using blosc v1.20.1 to avoid build errors on macOS Catalina (10.15) -# related to implicit declaration of functions in zlib. See: -# https://github.com/Blosc/python-blosc/issues/229 -BLOSC_URL = "https://github.com/Blosc/c-blosc/archive/v1.20.1.zip" - -def InstallBLOSC(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(BLOSC_URL, context, force)): - macArgs = [] - if MacOS() and apple_utils.IsTargetArm(context): - # Need to disable SSE for macOS ARM targets. - macArgs = ["-DDEACTIVATE_SSE2=ON"] - RunCMake(context, force, buildArgs + macArgs) - -BLOSC = Dependency("Blosc", InstallBLOSC, "include/blosc.h") - -############################################################ -# OpenVDB - -OPENVDB_URL = "https://github.com/AcademySoftwareFoundation/openvdb/archive/refs/tags/v9.1.0.zip" - -# OpenVDB v9.1.0 requires TBB 2019.0 or above, but this script installs -# TBB 2018 on macOS Intel systems for reasons documented above. So we -# keep OpenVDB at the version specified for the VFX Reference Platform -# CY2021, which is the last version that supported 2018. -OPENVDB_INTEL_URL = "https://github.com/AcademySoftwareFoundation/openvdb/archive/refs/tags/v8.2.0.zip" - -def InstallOpenVDB(context, force, buildArgs): - openvdb_url = OPENVDB_URL - if MacOS() and not apple_utils.IsTargetArm(context): - openvdb_url = OPENVDB_INTEL_URL - - with CurrentWorkingDirectory(DownloadURL(openvdb_url, context, force)): - extraArgs = [ - '-DOPENVDB_BUILD_PYTHON_MODULE=OFF', - '-DOPENVDB_BUILD_BINARIES=OFF', - '-DOPENVDB_BUILD_UNITTESTS=OFF' - ] - - # Make sure to use boost installed by the build script and not any - # system installed boost - extraArgs.append('-DBoost_NO_BOOST_CMAKE=On') - extraArgs.append('-DBoost_NO_SYSTEM_PATHS=True') - - extraArgs.append('-DBLOSC_ROOT="{instDir}"' - .format(instDir=context.instDir)) - extraArgs.append('-DTBB_ROOT="{instDir}"' - .format(instDir=context.instDir)) - # OpenVDB needs Half type from IlmBase - extraArgs.append('-DILMBASE_ROOT="{instDir}"' - .format(instDir=context.instDir)) - - # Add on any user-specified extra arguments. - extraArgs += buildArgs - - RunCMake(context, force, extraArgs) - -OPENVDB = Dependency("OpenVDB", InstallOpenVDB, "include/openvdb/openvdb.h") - -############################################################ -# OpenImageIO - -OIIO_URL = "https://github.com/OpenImageIO/oiio/archive/refs/tags/v2.3.21.0.zip" - -def InstallOpenImageIO(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(OIIO_URL, context, force)): - # The only time that we want to build tools with OIIO is for testing - # purposes. Libraries such as usdImagingGL might need to use tools like - # idiff to compare the output images from their tests - buildOIIOTools = 'ON' if (context.buildUsdImaging - and context.buildTests) else 'OFF' - extraArgs = ['-DOIIO_BUILD_TOOLS={}'.format(buildOIIOTools), - '-DOIIO_BUILD_TESTS=OFF', - '-DBUILD_DOCS=OFF', - '-DUSE_PYTHON=OFF', - '-DSTOP_ON_WARNING=OFF'] - - # OIIO's FindOpenEXR module circumvents CMake's normal library - # search order, which causes versions of OpenEXR installed in - # /usr/local or other hard-coded locations in the module to - # take precedence over the version we've built, which would - # normally be picked up when we specify CMAKE_PREFIX_PATH. - # This may lead to undefined symbol errors at build or runtime. - # So, we explicitly specify the OpenEXR we want to use here. - extraArgs.append('-DOPENEXR_ROOT="{instDir}"' - .format(instDir=context.instDir)) - - # If Ptex support is disabled in USD, disable support in OpenImageIO - # as well. This ensures OIIO doesn't accidentally pick up a Ptex - # library outside of our build. - if not context.enablePtex: - extraArgs.append('-DUSE_PTEX=OFF') - - # Make sure to use boost installed by the build script and not any - # system installed boost - extraArgs.append('-DBoost_NO_BOOST_CMAKE=On') - extraArgs.append('-DBoost_NO_SYSTEM_PATHS=True') - - # OpenImageIO 2.3.5 changed the default postfix for debug library - # names from "" to "_d". USD's build system currently does not support - # finding the library under this name, so as an interim workaround - # we reset it back to its old value. - extraArgs.append('-DCMAKE_DEBUG_POSTFIX=""') - - # Add on any user-specified extra arguments. - extraArgs += buildArgs - - RunCMake(context, force, extraArgs) - -OPENIMAGEIO = Dependency("OpenImageIO", InstallOpenImageIO, - "include/OpenImageIO/oiioversion.h") - -############################################################ -# OpenColorIO - -OCIO_URL = "https://github.com/AcademySoftwareFoundation/OpenColorIO/archive/refs/tags/v2.1.3.zip" - -def InstallOpenColorIO(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(OCIO_URL, context, force)): - extraArgs = ['-DOCIO_BUILD_APPS=OFF', - '-DOCIO_BUILD_NUKE=OFF', - '-DOCIO_BUILD_DOCS=OFF', - '-DOCIO_BUILD_TESTS=OFF', - '-DOCIO_BUILD_GPU_TESTS=OFF', - '-DOCIO_BUILD_PYTHON=OFF'] - - if MacOS(): - if apple_utils.IsTargetArm(context): - extraArgs.append('-DOCIO_USE_SSE=OFF') - - # Add on any user-specified extra arguments. - extraArgs += buildArgs - - RunCMake(context, force, extraArgs) - -OPENCOLORIO = Dependency("OpenColorIO", InstallOpenColorIO, - "include/OpenColorIO/OpenColorABI.h") - -############################################################ -# OpenSubdiv - -OPENSUBDIV_URL = "https://github.com/PixarAnimationStudios/OpenSubdiv/archive/v3_5_1.zip" - -def InstallOpenSubdiv(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(OPENSUBDIV_URL, context, force)): - extraArgs = [ - '-DNO_EXAMPLES=ON', - '-DNO_TUTORIALS=ON', - '-DNO_REGRESSION=ON', - '-DNO_DOC=ON', - '-DNO_OMP=ON', - '-DNO_CUDA=ON', - '-DNO_OPENCL=ON', - '-DNO_DX=ON', - '-DNO_TESTS=ON', - '-DNO_GLEW=ON', - '-DNO_GLFW=ON', - ] - - # If Ptex support is disabled in USD, disable support in OpenSubdiv - # as well. This ensures OSD doesn't accidentally pick up a Ptex - # library outside of our build. - if not context.enablePtex: - extraArgs.append('-DNO_PTEX=ON') - - # NOTE: For now, we disable TBB in our OpenSubdiv build. - # This avoids an issue where OpenSubdiv will link against - # all TBB libraries it finds, including libtbbmalloc and - # libtbbmalloc_proxy. On Linux and MacOS, this has the - # unwanted effect of replacing the system allocator with - # tbbmalloc. - extraArgs.append('-DNO_TBB=ON') - - # Add on any user-specified extra arguments. - extraArgs += buildArgs - - # OpenSubdiv seems to error when building on windows w/ Ninja... - # ...so just use the default generator (ie, Visual Studio on Windows) - # until someone can sort it out - oldGenerator = context.cmakeGenerator - if oldGenerator == "Ninja" and Windows(): - context.cmakeGenerator = None - - try: - RunCMake(context, force, extraArgs) - finally: - context.cmakeGenerator = oldGenerator - -OPENSUBDIV = Dependency("OpenSubdiv", InstallOpenSubdiv, - "include/opensubdiv/version.h") - -############################################################ -# PyOpenGL - -def GetPyOpenGLInstructions(): - return ('PyOpenGL is not installed. If you have pip ' - 'installed, run "pip install PyOpenGL" to ' - 'install it, then re-run this script.\n' - 'If PyOpenGL is already installed, you may need to ' - 'update your PYTHONPATH to indicate where it is ' - 'located.') - -PYOPENGL = PythonDependency("PyOpenGL", GetPyOpenGLInstructions, - moduleNames=["OpenGL"]) - -############################################################ -# PySide - -def GetPySideInstructions(): - # For licensing reasons, this script cannot install PySide itself. - if MacOS(): - # PySide6 is required for Apple Silicon support, so is the default - # across all macOS hardware platforms. - return ('PySide6 is not installed. If you have pip ' - 'installed, run "pip install PySide6" ' - 'to install it, then re-run this script.\n' - 'If PySide6 is already installed, you may need to ' - 'update your PYTHONPATH to indicate where it is ' - 'located.') - else: - return ('PySide2 or PySide6 are not installed. If you have pip ' - 'installed, run "pip install PySide2" ' - 'to install it, then re-run this script.\n' - 'If PySide2 is already installed, you may need to ' - 'update your PYTHONPATH to indicate where it is ' - 'located.') - -PYSIDE = PythonDependency("PySide", GetPySideInstructions, - moduleNames=["PySide2", "PySide6"]) - -############################################################ -# HDF5 - -HDF5_URL = "https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.10/hdf5-1.10.0-patch1/src/hdf5-1.10.0-patch1.zip" - -def InstallHDF5(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(HDF5_URL, context, force)): - if MacOS(): - PatchFile("config/cmake_ext_mod/ConfigureChecks.cmake", - [("if (ARCH_LENGTH GREATER 1)", "if (FALSE)")]) - if context.targetUniversal: - PatchFile("config/cmake/H5pubconf.h.in", - [(" #define H5_SIZEOF_LONG_LONG 8", - " #define H5_SIZEOF_LONG_LONG 8\n" + - " #define H5_SIZEOF_LONG_DOUBLE 16")]) - RunCMake(context, force, - ['-DBUILD_TESTING=OFF', - '-DHDF5_BUILD_TOOLS=OFF', - '-DHDF5_BUILD_EXAMPLES=OFF'] + buildArgs) - -HDF5 = Dependency("HDF5", InstallHDF5, "include/hdf5.h") - -############################################################ -# Alembic - -ALEMBIC_URL = "https://github.com/alembic/alembic/archive/refs/tags/1.8.5.zip" - -def InstallAlembic(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(ALEMBIC_URL, context, force)): - cmakeOptions = ['-DUSE_BINARIES=OFF', '-DUSE_TESTS=OFF'] - if context.enableHDF5: - # HDF5 requires the H5_BUILT_AS_DYNAMIC_LIB macro be defined if - # it was built with CMake as a dynamic library. - cmakeOptions += [ - '-DUSE_HDF5=ON', - '-DHDF5_ROOT="{instDir}"'.format(instDir=context.instDir), - '-DCMAKE_CXX_FLAGS="-D H5_BUILT_AS_DYNAMIC_LIB"'] - else: - cmakeOptions += ['-DUSE_HDF5=OFF'] - - cmakeOptions += buildArgs - - RunCMake(context, force, cmakeOptions) - -ALEMBIC = Dependency("Alembic", InstallAlembic, "include/Alembic/Abc/Base.h") - -############################################################ -# Draco - -DRACO_URL = "https://github.com/google/draco/archive/refs/tags/1.3.6.zip" - -def InstallDraco(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(DRACO_URL, context, force)): - cmakeOptions = [ - '-DBUILD_USD_PLUGIN=ON', - ] - cmakeOptions += buildArgs - RunCMake(context, force, cmakeOptions) - -DRACO = Dependency("Draco", InstallDraco, "include/draco/compression/decode.h") - -############################################################ -# MaterialX - -MATERIALX_URL = "https://github.com/materialx/MaterialX/archive/v1.38.7.zip" - -def InstallMaterialX(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(MATERIALX_URL, context, force)): - # MaterialX 1.38.7 fails to build on windows using VS2017 because of a - # missing header include, following patch fixes the same. This patch - # should be removed when underlying issue is resolved. - # https://github.com/AcademySoftwareFoundation/MaterialX/issues/1401 - if IsVisualStudio2017OrGreater() and not IsVisualStudio2019OrGreater(): - PatchFile("source\\MaterialXGenMsl\\MslShaderGenerator.cpp", - [("#include ", - "#include \n" + - "#include ")]) - cmakeOptions = ['-DMATERIALX_BUILD_SHARED_LIBS=ON', - '-DMATERIALX_BUILD_TESTS=OFF' - ] - cmakeOptions += buildArgs - RunCMake(context, force, cmakeOptions) - -MATERIALX = Dependency("MaterialX", InstallMaterialX, "include/MaterialXCore/Library.h") - -############################################################ -# Embree -# For MacOS we use version 3.13.3 to include a fix from Intel -# to build on Apple Silicon. -if MacOS(): - EMBREE_URL = "https://github.com/embree/embree/archive/v3.13.3.zip" -else: - EMBREE_URL = "https://github.com/embree/embree/archive/v3.2.2.zip" - -def InstallEmbree(context, force, buildArgs): - with CurrentWorkingDirectory(DownloadURL(EMBREE_URL, context, force)): - extraArgs = [ - '-DTBB_ROOT={instDir}'.format(instDir=context.instDir), - '-DEMBREE_TUTORIALS=OFF', - '-DEMBREE_ISPC_SUPPORT=OFF' - ] - - if MacOS() and context.targetUniversal: - extraArgs += [ - '-DEMBREE_MAX_ISA=NEON', - '-DEMBREE_ISA_NEON=ON'] - - extraArgs += buildArgs - - RunCMake(context, force, extraArgs) - -EMBREE = Dependency("Embree", InstallEmbree, "include/embree3/rtcore.h") - -############################################################ -# USD - -def InstallUSD(context, force, buildArgs): - with CurrentWorkingDirectory(context.usdSrcDir): - extraArgs = [] - - extraArgs.append('-DPXR_PREFER_SAFETY_OVER_SPEED={}' - .format('ON' if context.safetyFirst else 'OFF')) - - if context.buildPython: - extraArgs.append('-DPXR_ENABLE_PYTHON_SUPPORT=ON') - - # Many people on Windows may not have Python libraries with debug - # symbols (denoted by a '_d') installed. This is the common - # case when a user installs Python from the official download - # website. Therefore we can still let people decide to build USD - # with the release version of Python if debugging into Python land - # is not what they want which can be done by setting the debugPython - # argument. - if context.buildDebug and context.debugPython: - extraArgs.append('-DPXR_USE_DEBUG_PYTHON=ON') - else: - extraArgs.append('-DPXR_USE_DEBUG_PYTHON=OFF') - - # CMake has trouble finding the executable, library, and include - # directories when there are multiple versions of Python installed. - # This can lead to crashes due to USD being linked against one - # version of Python but running through some other Python - # interpreter version. This primarily shows up on macOS, as it's - # common to have a Python install that's separate from the one - # included with the system. - # - # To avoid this, we try to determine these paths from Python - # itself rather than rely on CMake's heuristics. - pythonInfo = GetPythonInfo(context) - if pythonInfo: - extraArgs.append('-DPython3_EXECUTABLE="{pyExecPath}"' - .format(pyExecPath=pythonInfo[0])) - extraArgs.append('-DPython3_LIBRARY="{pyLibPath}"' - .format(pyLibPath=pythonInfo[1])) - extraArgs.append('-DPython3_INCLUDE_DIR="{pyIncPath}"' - .format(pyIncPath=pythonInfo[2])) - else: - extraArgs.append('-DPXR_ENABLE_PYTHON_SUPPORT=OFF') - - if context.buildShared: - extraArgs.append('-DBUILD_SHARED_LIBS=ON') - elif context.buildMonolithic: - extraArgs.append('-DPXR_BUILD_MONOLITHIC=ON') - - if context.buildDebug: - extraArgs.append('-DTBB_USE_DEBUG_BUILD=ON') - else: - extraArgs.append('-DTBB_USE_DEBUG_BUILD=OFF') - - if context.buildDocs: - extraArgs.append('-DPXR_BUILD_DOCUMENTATION=ON') - else: - extraArgs.append('-DPXR_BUILD_DOCUMENTATION=OFF') - - if context.buildTests: - extraArgs.append('-DPXR_BUILD_TESTS=ON') - else: - extraArgs.append('-DPXR_BUILD_TESTS=OFF') - - if context.buildExamples: - extraArgs.append('-DPXR_BUILD_EXAMPLES=ON') - else: - extraArgs.append('-DPXR_BUILD_EXAMPLES=OFF') - - if context.buildTutorials: - extraArgs.append('-DPXR_BUILD_TUTORIALS=ON') - else: - extraArgs.append('-DPXR_BUILD_TUTORIALS=OFF') - - if context.buildTools: - extraArgs.append('-DPXR_BUILD_USD_TOOLS=ON') - else: - extraArgs.append('-DPXR_BUILD_USD_TOOLS=OFF') - - if context.buildImaging: - extraArgs.append('-DPXR_BUILD_IMAGING=ON') - if context.enablePtex: - extraArgs.append('-DPXR_ENABLE_PTEX_SUPPORT=ON') - else: - extraArgs.append('-DPXR_ENABLE_PTEX_SUPPORT=OFF') - - if context.enableOpenVDB: - extraArgs.append('-DPXR_ENABLE_OPENVDB_SUPPORT=ON') - else: - extraArgs.append('-DPXR_ENABLE_OPENVDB_SUPPORT=OFF') - - if context.buildEmbree: - extraArgs.append('-DPXR_BUILD_EMBREE_PLUGIN=ON') - else: - extraArgs.append('-DPXR_BUILD_EMBREE_PLUGIN=OFF') - - if context.buildPrman: - if context.prmanLocation: - extraArgs.append('-DRENDERMAN_LOCATION="{location}"' - .format(location=context.prmanLocation)) - extraArgs.append('-DPXR_BUILD_PRMAN_PLUGIN=ON') - else: - extraArgs.append('-DPXR_BUILD_PRMAN_PLUGIN=OFF') - - if context.buildOIIO: - extraArgs.append('-DPXR_BUILD_OPENIMAGEIO_PLUGIN=ON') - else: - extraArgs.append('-DPXR_BUILD_OPENIMAGEIO_PLUGIN=OFF') - - if context.buildOCIO: - extraArgs.append('-DPXR_BUILD_OPENCOLORIO_PLUGIN=ON') - else: - extraArgs.append('-DPXR_BUILD_OPENCOLORIO_PLUGIN=OFF') - - else: - extraArgs.append('-DPXR_BUILD_IMAGING=OFF') - - if context.buildUsdImaging: - extraArgs.append('-DPXR_BUILD_USD_IMAGING=ON') - else: - extraArgs.append('-DPXR_BUILD_USD_IMAGING=OFF') - - if context.buildUsdview: - extraArgs.append('-DPXR_BUILD_USDVIEW=ON') - else: - extraArgs.append('-DPXR_BUILD_USDVIEW=OFF') - - if context.buildAlembic: - extraArgs.append('-DPXR_BUILD_ALEMBIC_PLUGIN=ON') - if context.enableHDF5: - extraArgs.append('-DPXR_ENABLE_HDF5_SUPPORT=ON') - - # CMAKE_PREFIX_PATH isn't sufficient for the FindHDF5 module - # to find the HDF5 we've built, so provide an extra hint. - extraArgs.append('-DHDF5_ROOT="{instDir}"' - .format(instDir=context.instDir)) - else: - extraArgs.append('-DPXR_ENABLE_HDF5_SUPPORT=OFF') - else: - extraArgs.append('-DPXR_BUILD_ALEMBIC_PLUGIN=OFF') - - if context.buildDraco: - extraArgs.append('-DPXR_BUILD_DRACO_PLUGIN=ON') - draco_root = (context.dracoLocation - if context.dracoLocation else context.instDir) - extraArgs.append('-DDRACO_ROOT="{}"'.format(draco_root)) - else: - extraArgs.append('-DPXR_BUILD_DRACO_PLUGIN=OFF') - - if context.buildMaterialX: - extraArgs.append('-DPXR_ENABLE_MATERIALX_SUPPORT=ON') - else: - extraArgs.append('-DPXR_ENABLE_MATERIALX_SUPPORT=OFF') - - if context.buildPythonDocs: - extraArgs.append('-DPXR_BUILD_PYTHON_DOCUMENTATION=ON') - else: - extraArgs.append('-DPXR_BUILD_PYTHON_DOCUMENTATION=OFF') - - if Windows(): - # Increase the precompiled header buffer limit. - extraArgs.append('-DCMAKE_CXX_FLAGS="/Zm150"') - - # Make sure to use boost installed by the build script and not any - # system installed boost - extraArgs.append('-DBoost_NO_BOOST_CMAKE=On') - extraArgs.append('-DBoost_NO_SYSTEM_PATHS=True') - extraArgs += buildArgs - - RunCMake(context, force, extraArgs) - -USD = Dependency("USD", InstallUSD, "include/pxr/pxr.h") - -############################################################ -# Install script - -programDescription = """\ -Installation Script for USD - -Builds and installs USD and 3rd-party dependencies to specified location. - -- Libraries: -The following is a list of libraries that this script will download and build -as needed. These names can be used to identify libraries for various script -options, like --force or --build-args. - -{libraryList} - -- Downloading Libraries: -If curl or powershell (on Windows) are installed and located in PATH, they -will be used to download dependencies. Otherwise, a built-in downloader will -be used. - -- Specifying Custom Build Arguments: -Users may specify custom build arguments for libraries using the --build-args -option. This values for this option must take the form ,