Building OpenUSD
Tips for compiling on different architectures, and common pitfalls
Compiling USD is not always necessary, if you can use a prebuilt option I'd recommend it. Historically building USD has been one of the most difficult parts of using it. It's gotten a lot better since the early days. I've occasionally managed to get it working on the first try, but I always assume building for a new platform will take somewhere between a few hours and a full day. Your mileage may vary.
When to Build
The good news is that it's pretty easy to get an already compiled version.
If you can use the USD libraries that come with your tools, that's a great place to find them. Blender, Houdini and Maya all ship with USD libraries now. You can also find pre-compiled binaries like the version NVIDIA provides. These will also usually include usdview
and other tools.
If you only need python support you can use the usd-core
package on PyPI, get it with pip install usd-core
.
This covers a lot of use cases. You might still want to build USD yourself though if, for instance:
- There are no packages available for your platform
- You want access to a specific USD version with specific plugins
- You want to write new plugins for Schemas, Hydra, Asset Resolvers, etc.
- You just want to tinker and have a lot of free time 🤓
Building with build_usd.py
If you've decided to build USD, this is the first thing to try. The script takes parameters with common configuration switches, like enabling python, imaging, alembic support, stuff like that. The build script will figure out what dependencies it needs, download source for them, and build compatible versions of the dependencies. The artifacts from those builds are then vendored into the USD build output, so that it has everything it needs to run.
See the documentation on github for all the details. The most basic usage looks like this, run from the root of the git repository.
python build_scripts/build_usd.py ../my-usd-build
That will generate a USD build that includes python support and usdview. The build output will go into the folder ../my-usd-build
. I placed it in the parent directory so that it is outside the git managed USD source tree.
You can also do a "dry run" build with the -n
flag or --dry_run
. This will compute the dependencies and come up with a build plan, report that plan at the command line, and exit without doing anything.
Before building on my M1 Macbook I created the setup below, but on another platform you'd need to do the equivalent (get a C++ build toolchain, get CMake, install necessary python packages).
- Xcode tools installed
- CMake installed with homebrew
pyside6
,PyOpenGL
andjinja2
installed in a python virtual env
The output of a dryrun looks like this:
❯ python build_scripts/build_usd.py -n ../my-usd-build
Building with settings:
USD source directory /Projects/github/rstelzleni/USD
USD install directory /Projects/github/rstelzleni/my-usd-build
3rd-party source directory /Projects/github/rstelzleni/my-usd-build/src
3rd-party install directory /Projects/github/rstelzleni/my-usd-build
Build directory /Projects/github/rstelzleni/my-usd-build/build
CMake generator Default
CMake toolset Default
Downloader curl
Building Shared libraries
Variant Release
Target native
Imaging On
Ptex support: Off
OpenVDB support: Off
OpenImageIO support: Off
OpenColorIO support: Off
PRMan support: Off
UsdImaging On
usdview: On
Python support On
Python Debug: Off
Python docs: Off
Documentation Off
Tests Off
Mayapy Tests: Off
AnimX Tests: Off
Examples On
Tutorials On
Tools On
Alembic Plugin Off
HDF5 support: Off
Draco Plugin Off
MaterialX Plugin On
Dependencies zlib, boost, TBB, MaterialX, OpenSubdiv
Each item listed in Dependencies
will be downloaded and compiled.
Build Output
After a successful compile all the build output is in the ../my-usd-build
folder. What the build includes will depend on the parameters passed to build_usd.py
.
On success you should get a message like this one
Success! To use USD, please ensure that you have:
The following in your PYTHONPATH environment variable:
/Projects/github/rstelzleni/my-usd-build/lib/python
The following in your PATH environment variable:
/Projects/github/rstelzleni/my-usd-build/bin
Really only the PYTHONPATH
needs to be updated to use USD python modules, or to run usdcat
or usdview
. On Linux and Mac updating PATH
is only necessary to make tools available at the command line, but on Windows it is also necessary to run things.
The build output will contain source code from dependencies, intermediate build files, object files and configuration. This amounts to a lot of extra size. You can separate out the files that need to be in the install from the source and intermediate files using a few command line flags, like so:
python build_scripts/build_usd.py --build=../my-usd-build-2-intermediate --src=../my-usd-build-2-src ../my-usd-build-2
If I build USD v24.05 with these two command lines on my Macbook I get directories with these sizes:
3.7G my-usd-build
835M my-usd-build-2
1.7G my-usd-build-2-intermediate
1.0G my-usd-build-2-src
As you can see, this separates out a full 2.7G of files that are only needed for incremental builds. The files needed to run USD and the related tools are all in my-usd-build-2
, so in theory you could delete everything in the intermediate and src folders once your build was working.
If you need to relocate the install it's best to copy the install directory whole. USD's Plug
library requires configuration files that are located at relative path locations to the shared libraries in USD. By copying everything together you can ensure the relative paths don't break. If my-usd-build
or my-usd-build-2
was moved to a new folder, and the PYTHONPATH
and PATH
was updated to point to that folder, then usdview
and other tools should still work from that new location.
Building with CMake Directly
If build_usd.py
serves your needs that's great! It's a good tool and covers most use cases. If you need to build for an exotic or very specific platform though it might not do the job. In that case you can bypass the python script and build with CMake directly.
I won't go too in depth into this here, if there's demand for it this could be a whole dedicated article. When I need to build with CMake I find it useful to run build_usd.py
anyway, and use it to identify the dependencies, versions and build flags that the python script would have used.
Pitfalls
Here are a few common errors I've encountered when building. If you run into these, I'll at least list the first things I try to get things working.
ERROR: PySide's user interface compiler was not found – please install PySide2 or PySide6 and adjust your PATH. (Note that this program may be named pyside6-uic or pyside2-uic depending on your platform)
- If you're building usdview this is pretty common. One of these uic programs needs to be available in your path, and may not be even if pyside is installed on some platforms. The fix is to locate the
uic
version you have and add it to the path.
- If you're building usdview this is pretty common. One of these uic programs needs to be available in your path, and may not be even if pyside is installed on some platforms. The fix is to locate the
fatal error: patchlevel.h: No such file or directory
- I often see this one in docker containers when trying to build boost, it usually means I forgot to install the
python-dev
package or its equivalent on the platform.
- I often see this one in docker containers when trying to build boost, it usually means I forgot to install the
- Build warnings. There can be many, stemming from boost and other packages. I have not created a comprehensive list to disable them, but it would be an interesting thing to have.