Advanced Build Configuration ============================ ## Table of Contents - [Building With Build Script](#building-with-build-script) - [Building With CMake](#building-with-cmake) - [Optional Components](#optional-components) - [Imaging Plugins](#imaging-plugins) - [Third Party Plugins](#third-party-plugins) - [Tests](#tests) - [Other Build Options](#other-build-options) - [USD Developer Options](#usd-developer-options) - [Optimization Options](#optimization-options) - [Linker Options](#linker-options) - [Build Issues FAQ](#build-issues-faq) ## Building With Build Script The simplest way to build USD is to run the supplied `build_usd.py` script. This script will download required dependencies and build and install them along with USD in a given directory. See instructions and examples in [README.md](README.md#getting-and-building-the-code). ## Building With CMake Users may specify libraries to build USD against and other build options by passing arguments when running cmake. Documentation for these arguments are below. Some examples: #### On Linux ```bash cmake \ -DTBB_ROOT_DIR=/path/to/tbb \ -DOPENSUBDIV_ROOT_DIR=/path/to/opensubdiv \ /path/to/USD/source cmake --build . --target install -- -j ``` #### On macOS The following will generate an Xcode project that can be used to build USD. ```bash cmake \ -G "Xcode" \ -DTBB_ROOT_DIR=/path/to/tbb \ -DOPENSUBDIV_ROOT_DIR=/path/to/opensubdiv \ /path/to/USD/source cmake --build . --target install -- -j ``` #### On Windows The following will generate a Visual Studio 2017 solution that can be used to build USD. ```cmd.exe "C:\Program Files\CMake\bin\cmake.exe" ^ -G "Visual Studio 15 2017 Win64" ^ -DTBB_ROOT_DIR=C:\path\to\tbb ^ -DOPENSUBDIV_ROOT_DIR=C:\path\to\opensubdiv ^ \path\to\USD\source cmake --build . --target install -- /m:%NUMBER_OF_PROCESSORS% ``` For other versions of Visual Studio, use the following cmake arguments: - For VS2019: `-G "Visual Studio 16 2019" -A x64` - For VS2022: `-G "Visual Studio 17 2022" -A x64` For more information on Visual Studio generators for cmake, see [Visual Studio Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators). #### WebAssembly To produce a Wasm build, you will first need to [download and install the Emscripten Compiler Toolchain](https://emscripten.org/docs/getting_started/downloads.html). USD requires oneTBB, which can be built for 32 and 64 bit wasm out of the box. Begin by [Downloading](https://github.com/oneapi-src/oneTBB/archive/refs/tags/v2021.12.0.zip), building for Wasm, and installing the library. Next build USD: ```bash emcmake cmake \ -DCMAKE_INSTALL_PREFIX="/path/to/build/openusd_wasm" \ -DCMAKE_PREFIX_PATH="/path/to/build/openusd_wasm" \ -DPXR_BUILD_TESTS=ON \ -DPXR_BUILD_EXAMPLES=OFF \ -DPXR_BUILD_IMAGING=OFF \ -DCMAKE_FIND_ROOT_PATH="/path/to/build/tbb_wasm" \ -DBUILD_SHARED_LIBS=OFF \ -DCMAKE_CXX_FLAGS="-pthread --use-port=zlib" \ -DCMAKE_C_FLAGS="-pthread --use-port=zlib" \ -DCMAKE_EXE_LINKER_FLAGS="-pthread" \ "/path/to/src/OpenUSD" emmake cmake --build . --config Release --target install -j 8 ``` By default, 32 bit Wasm is built. To produce 64 bit output, ensure that `-sMEMORY64=1` is appended to `CMAKE_C_FLAGS` above. Additionally, ensure that you have built a Wasm64 version of oneTBB as well. When performing a Wasm build, resource files will be embedded in the resulting binary as part of the linking process. These files, which consist of the `plugInfo.json` files required for the usd library to correctly load types and schemas are placed under `/usd` in the virtual file system. ## Optional Components USD contains several optional components that are enabled by default but may be disabled when invoking cmake. Disabling these components removes the need for their dependencies when building USD. ##### Python Some optional USD components use Python: - [The USD Toolset](https://graphics.pixar.com/usd/docs/USD-Toolset.html) - [Third Party Plugins](https://graphics.pixar.com/usd/docs/USD-3rd-Party-Plugins.html) - Python language bindings for the USD C++ API - Unit tests using Python Please refer to [VERSIONS.md](VERSIONS.md) for supported Python versions. Support for Python can optionally be disabled by specifying the cmake flag `PXR_ENABLE_PYTHON_SUPPORT=FALSE`. By default, Python bindings are installed into the standard Python site-packages directory under `CMAKE_INSTALL_PREFIX`. This directory varies depending on the platform and version of Python used to build USD: - Linux / macOS: - `/lib/pythonX.Y/site-packages` - Windows: - `/Lib/site-packages` To install into a custom directory instead, set `PXR_PYTHON_INSTALL_DIR` to a path relative to `CMAKE_INSTALL_PREFIX` or to an absolute path. For example, to restore the layout used by older USD releases: ``` -DPXR_PYTHON_INSTALL_DIR=lib/python ``` Python must be set up to discover the bindings in order to use them and the components that depend on them. This is typically done by adding the install directory to the `PYTHONPATH` environment variable. Note that with the default settings, no additional configuration is required if USD is built into a virtualenv (i.e., `CMAKE_INSTALL_PREFIX` is set to the virtual environment's root directory). ##### OpenGL Support for OpenGL can optionally be disabled by specifying the cmake flag `PXR_ENABLE_GL_SUPPORT=FALSE`. This will skip components and libraries that depend on GL, including: - usdview - Hydra GL imaging ##### Metal Building USD with Metal enabled requires macOS Mojave (10.14) or newer. Support for Metal can optionally be disabled by specifying the cmake flag `PXR_ENABLE_METAL_SUPPORT=FALSE`. This will skip components and libraries that depend on Metal, including: - Hydra imaging ##### Vulkan Vulkan support for USD is currently experimental and disabled by default. Building USD with Vulkan enabled requires the Vulkan SDK and glslang to be installed. If you wish to build a debug build on Windows, please make sure you have the optional component "Shader Toolchain Debug Symbols" installed as part of the Vulkan SDK. The VULKAN_SDK environment variable must point to the location of the SDK. The glslang compiler headers must be locatable during the build process. Support for Vulkan can optionally be enabled by specifying the cmake flag `PXR_ENABLE_VULKAN_SUPPORT=TRUE`. ##### MaterialX Enable [MaterialX](https://github.com/materialx/materialx) support in the build by specifying the cmake flag `PXR_ENABLE_MATERIALX_SUPPORT=TRUE` when invoking cmake. Note that MaterialX with shared library support is required. When building via build_usd.py, MaterialX support is enabled by default. The default can be overriden using the --materialx and --no-materialx flags. The additional dependencies that must be supplied when invoking cmake are: | Dependency Name | Description | | ------------------ |----------------------------------------------------------- | | MaterialX_DIR | Path to the CMake package config of a MaterialX SDK install.| See [3rd Party Library and Application Versions](VERSIONS.md) for version information. ##### OSL (OpenShadingLanguage) Support for OSL is disabled by default, and can optionally be enabled by specifying the cmake flag `PXR_ENABLE_OSL_SUPPORT=TRUE`. This will enable components and libraries that depend on OSL. Enabling OSL suport allows the Shader Definition Registry (sdr) to parse metadata from OSL shaders. ##### Documentation Doxygen documentation can optionally be generated by specifying the cmake flag `PXR_BUILD_DOCUMENTATION=TRUE`. There are two documentation sub-components, controlled by setting `PXR_BUILD_HTML_DOCUMENTATION` and `PXR_BUILD_PYTHON_DOCUMENTATION`. See the sections below for descriptions of precisely what they control. Neither sub- component will have any effect if `PXR_BUILD_DOCUMENTATION` is not `TRUE`. The additional dependencies that must be supplied for enabling documentation generation are: | Dependency Name | Description | | ------------------ |--------------------------------------- | | DOXYGEN_EXECUTABLE | The location of Doxygen | See [3rd Party Library and Application Versions](VERSIONS.md) for version information, including supported Doxygen versions. ##### HTML Documentation If `PXR_BUILD_HTML_DOCUMENTATION` evaluates `TRUE` then building of the HTML documentation is enabled. This includes USD overview and general concepts, and the C++ API documentation. It defaults to `TRUE`, and so is built by default when `PXR_BUILD_DOCUMENTATION` is also enabled (but has no effect if `PXR_BUILD_DOCUMENTATION` is not set.) The additional dependencies that must be supplied for enabling HTML documentation generation are: | Dependency Name | Description | | ------------------ |--------------------------------------- | | DOT_EXECUTABLE | The location of Dot(from GraphViz). | See [3rd Party Library and Application Versions](VERSIONS.md) for version information, including supported GraphViz versions. ##### Python Documentation Python docstrings for Python entities can be generated by specifying the cmake flag `PXR_BUILD_PYTHON_DOCUMENTATION`. This process requires that Python support (`PXR_ENABLE_PYTHON_SUPPORT`) and documentation (`PXR_BUILD_DOCUMENTATION`) are enabled. It defaults to `FALSE`. This process uses the scripts in the docs/python subdirectory. Relevant documentation from generated doxygen XML data is extracted and matched with associated Python classes, functions, and properties in the built Python modules. A `__DOC.py` file is generated and installed in each of the directories of the installed Python modules. The `__DOC.py` file adds the docstrings to the Python entities when the module is loaded. ##### Imaging This component contains Hydra, a high-performance graphics rendering engine. Disable this component by specifying the cmake flag `PXR_BUILD_IMAGING=FALSE` when invoking cmake. Disabling this component will also disable the [USD Imaging](#usd-imaging) component and any [Imaging Plugins](#imaging-plugins). ##### USD Imaging This component provides the USD imaging delegates for Hydra, as well as usdview, a standalone native viewer for USD files. Disable this component by specifying the cmake flag `PXR_BUILD_USD_IMAGING=FALSE` when invoking cmake. usdview may also be disabled independently by specifying the cmake flag `PXR_BUILD_USDVIEW=FALSE`. ##### Command-line Tools USD by default builds several helpful command-line tools for validating and manipulating USD files. For more information on the tools, see [USD Toolset](https://graphics.pixar.com/usd/release/toolset.html). Disable building the command-line tools by specifying the cmake flag `PXR_BUILD_USD_TOOLS=FALSE` when invoking cmake. ##### Examples USD by default builds several example projects that demonstrate how to develop various extensions and plugins. Disable building the examples by specifying the cmake flag `PXR_BUILD_EXAMPLES=FALSE` when invoking cmake. ##### Tutorials USD by default builds USD and Python files used for the [USD Tutorials](https://graphics.pixar.com/usd/release/tut_usd_tutorials.html). Disable building the tutorial support files by specifying the cmake flag `PXR_BUILD_TUTORIALS=FALSE` when invoking cmake. ## Imaging Plugins Hydra's rendering functionality can be extended with these optional plugins. ##### Ptex Support for Ptex is disabled by default and can be enabled by specifying the cmake flag `PXR_ENABLE_PTEX_SUPPORT=TRUE`. ##### OpenImageIO This plugin can optionally be enabled by specifying the cmake flag `PXR_BUILD_OPENIMAGEIO_PLUGIN=TRUE`. When enabled, OpenImageIO provides broader support for reading and writing different image formats as textures. If OpenImageIO is disabled, imaging by default supports the image formats bmp, jpg, png, tga, and hdr. With OpenImageIO enabled, support extends to exr, tif, zfile, and tx file formats, which allows for the use of more advanced features like subimages and mipmaps. ##### OpenColorIO This plugin can optionally be enabled by specifying the cmake flag `PXR_BUILD_OPENCOLORIO_PLUGIN=TRUE`. When enabled, OpenColorIO provides color management for Hydra viewports. ##### Embree Rendering This component contains an example rendering backend for Hydra and usdview, based on the embree raycasting library. Enable the plugin in the build by specifying the cmake flag `PXR_BUILD_EMBREE_PLUGIN=TRUE` when invoking cmake. The additional dependencies that must be supplied when invoking cmake are: | Dependency Name | Description | | -------------- | ----------------------------------- | | EMBREE_LOCATION | The root path to an embree library install. | See [3rd Party Library and Application Versions](VERSIONS.md) for version information. ##### RenderMan Rendering This plugin uses Pixar's RenderMan as a rendering backend for Hydra and usdview. Enable the plugin in the build by specifying the cmake flag `PXR_BUILD_PRMAN_PLUGIN=TRUE` when invoking cmake. The additional dependencies that must be supplied when invoking cmake are: | Dependency Name | Description | | -------------- | ----------------------------------- | | RENDERMAN_LOCATION | The root path to an RenderMan install. | See [3rd Party Library and Application Versions](VERSIONS.md) for version information. More documentation is available [here](http://openusd.org/docs/RenderMan-USD-Imaging-Plugin.html). ## Third Party Plugins USD provides several plugins for integration with third-party software packages. There is additional documentation on each plugin [here](http://openusd.org/docs/USD-3rd-Party-Plugins.html). These plugins are not built by default and must be enabled via the instructions below. The USD Maya plugins can be found in the Autodesk-supported repo available [here](https://github.com/Autodesk/maya-usd). The USD Katana plugins can be found in the Foundry-supported repo available [here](https://github.com/TheFoundryVisionmongers/KatanaUsdPlugins). ##### Alembic Plugin Enable the [Alembic](https://github.com/alembic/alembic) plugin in the build by specifying the cmake flag `PXR_BUILD_ALEMBIC_PLUGIN=TRUE` when invoking cmake. The additional dependencies that must be supplied when invoking cmake are: | Dependency Name | Description | | ----------------------------------|-------------------------------------------------- | | ALEMBIC_DIR | The location of [Alembic](https://https://github.com/alembic/alembic) | | OPENEXR_LOCATION | The location of [OpenEXR](http://www.openexr.com) | | Imath_DIR (If not using OpenEXR) | Path to the CMake package config of a Imath SDK install. (With OpenEXR 3+, Imath can be used explicitly instead of OpenEXR.)| Either OpenEXR or Imath is required depending on which library is used by the Alembic library specified in ALEMBIC_DIR. See [3rd Party Library and Application Versions](VERSIONS.md) for version information. Support for Alembic files using the HDF5 backend can be enabled by specifying the cmake flag `PXR_ENABLE_HDF5_SUPPORT=TRUE`. HDF5 support requires the following dependencies: | Dependency Name | Description | | ------------------ |---------------- | | HDF5_LOCATION | The location of [HDF5](https://www.hdfgroup.org/HDF5/) | For further information see the documentation on the Alembic plugin [here](http://openusd.org/docs/Alembic-USD-Plugin.html). ##### Draco Plugin Enable the [Draco](https://github.com/google/draco) plugin in the build by specifying the cmake flag `PXR_BUILD_DRACO_PLUGIN=TRUE` when invoking cmake. This plugin is compatible with Draco 1.3.4. The additional dependencies that must be supplied when invoking cmake are: | Dependency Name | Description | Version | | ------------------ |---------------------------------------- | ------- | | DRACO_ROOT | The root path to a Draco SDK install. | 1.3.4 | ## Tests Tests are built by default but can be disabled by specifying the cmake flag `PXR_BUILD_TESTS=FALSE` when invoking cmake. ##### Running Tests Run tests by invoking ctest from the build directory, which is typically the directory in which cmake was originally invoked. For example, to run all tests in a release build with verbose output: ```bash ctest -C Release -V ``` The "-R" argument may be used to specify a regular expression matching the names of tests to be run. For example, to run all tests in a release build matching "testUsdShade" with verbose output: ```bash ctest -C Release -R testUsdShade -V ``` See the [ctest documentation](https://cmake.org/cmake/help/latest/manual/ctest.1.html) for more options. ##### Test Run Directories Each test is run out of an automatically-created temporary directory containing any additional files required by the test. Set the cmake option `PXR_TEST_RUN_TEMP_DIR_PREFIX` to prepend a prefix string to the name of these directories. For example, setting this option to "foo-" will create test run directories named "foo-" ##### Diagnosing Failed Tests In order to aid with diagnosing of failing tests, test generated files for failing test are explicitly put in the following directories, where (formatted as "%Y-%m-%dT%H.%M.%S") represents the timestamp when ctest was run for the failing test. ``` ${CMAKE_BINARY_DIR}/Testing/Failed-Diffs//${TEST_NAME}/${filename}.result.${ext} ${CMAKE_BINARY_DIR}/Testing/Failed-Diffs//${TEST_NAME}/${filename}.baseline.${ext} ``` ## Other Build Options ##### Custom Task Management System USD uses task-based parallelism to improve scalability and performance. This foundation for this is located in the "work" library in pxr/base/work. By default, this library is implemented using the Intel TBB or oneAPI oneTBB library. Users may substitute their own task management system by providing a custom implementation for the work library. To do so, set the cmake variable `PXR_WORK_IMPL` to the name of the CMake package providing the custom implementation. USD must be able to locate a package with that name via a call to `find_package(${PXR_WORK_IMPL}` CONFIG)`, which may require specifying additional CMake variables. The package must provide a library target named `${PXR_WORK_IMPL}::${PXR_WORK_IMPL}` that specifies interface definitions (include directories, shared libraries, etc.) needed to use that library. The library must implement the required functions and classes and have a header named `impl.h` that supplies their declarations (either directly or in header files included in `impl.h`). This header must be able to be included via `#include <${PXR_WORK_IMPL}/impl.h>`. For example, a custom work implementation named `workExample` must provide a `workExampleConfig.cmake` file specifying a library target named `workExample::workExample`. This library must at minimum provide an `impl.h` header with the required implementations and set up interface include directories so that the header can be located via an include statement like `#include `. ##### Plugin Metadata Location Each library in the USD core generally has an associated file named 'plugInfo.json' that contains metadata about that library, such as the schema types provided by that library. These files are consumed by USD's internal plugin system to lazily load libraries when needed. The plugin system requires knowledge of where these metadata files are located. The cmake build will ensure this is set up properly based on the install location of the build. However, if you plan to relocate these files to a new location after the build, you must inform the build by setting the cmake variable `PXR_INSTALL_LOCATION` to the intended final directory where these files will be located. This variable may be a ':'-delimited list of paths. Another way USD is locating plugins is the `PXR_PLUGINPATH_NAME` environment variable. This variable may be a list of paths. If you do not want your USD build to use this default variable name, you can override the name of the environment variable using the following CMake option: ``` -DPXR_OVERRIDE_PLUGINPATH_NAME=CUSTOM_USD_PLUGINPATHS ``` By doing this, USD will check the `CUSTOM_USD_PLUGINPATHS` environment variable for paths, instead of the default `PXR_PLUGINPATH_NAME` one. The values specified in `PXR_PLUGINPATH_NAME` or `PXR_INSTALL_LOCATION` have the following characteristics: - Values may contain any number of paths. - Paths ending with slash ('/') have 'plugInfo.json' appended automatically. - '*' may be used anywhere to match any character except slash. - '**' may be used anywhere to match any character including slash. - Paths follow Unix '$PATH'-like conventions; when duplicate definitions exist in the path, the first one found is used. ##### Shared library prefix By default shared libraries will have the prefix 'lib'. This means, for a given component such as [usdGeom](pxr/usd/lib/usdGeom), the build will generate a corresponding libusdGeom object (libusdGeom.so on Linux, libusdGeom.dll on Windows and libusdGeom.dylib on Mac). You can change the prefix (or remove it) through `PXR_LIB_PREFIX`. For example, ``` -DPXR_LIB_PREFIX=pxr ``` Will generate pxrusdGeom.so on Linux, pxrusdGeom.dll on Windows and pxrusdGeom.dylib on Mac for the usdGeom component. > Note: This prefix does not apply to shared objects used for Python bindings. ##### Address Sanitizer Address Sanitizer's memory leak detection will trigger many assertions that are more the responsibility of Leak Sanitizer than Address Sanitizer. To get an address sanitized build of OpenUSD without leak detection, build with the flag `-fsanitize=address` and set the following option: ```bash export ASAN_OPTIONS=detect_leaks=0 ``` This can also be defaulted within code by defining the following function (see [ASAN runtime flags](https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags)) ```cpp const char *__asan_default_options() { return "detect_leaks=0"; } ``` ## USD Developer Options ##### C++ Namespace Configuration USD comes with options to enable and customize C++ namespaces via the following flags: | Option Name | Description | Default | | ------------------------------ |-----------------------------------------| ------- | | PXR_SET_EXTERNAL_NAMESPACE | The outer namespace identifier | `pxr` | | PXR_SET_INTERNAL_NAMESPACE | The internal namespace identifier | `pxrInternal_v_x_y` (for version x.y.z) | | PXR_ENABLE_NAMESPACES | Enable namespaces | `ON` | When enabled, there are a set of macros provided in a generated header, pxr/pxr.h, which facilitates using namespaces: | Macro Name | Description | | ------------------------------ |-----------------------------------------| | PXR_NAMESPACE_OPEN_SCOPE | Opens the namespace scope. | | PXR_NAMESPACE_CLOSE_SCOPE | Closes the namespace. | | PXR_NS | Explicit qualification on items, e.g. `PXR_NS::TfToken foo = ...`| | PXR_NAMESPACE_USING_DIRECTIVE | Enacts a using-directive, e.g. `using namespace PXR_NS;` | ##### USD Schema Generation USD generates some code through a process called [schema generation]. This process requires the following python modules be installed and available on the syspath. You can learn more about Schemas and why you might want to generate them [here](http://openusd.org//docs/Generating-New-Schema-Classes.html). | Python Module Name | Description | | ------------------------------------------ |------------------------------- | | [Jinja2](http://jinja.pocoo.org/docs/dev/) | Jinja is the core code generator of usdGenSchema | | [Argparse](https://docs.python.org/3/library/argparse.html) | Argparse is used for basic command line arguments | See [3rd Party Library and Application Versions](VERSIONS.md) for version information. ## Optimization Options There are certain optimizations that can be enabled in the build. ##### Malloc Library We've found that USD performs best with allocators such as [Jemalloc](https://github.com/jemalloc/jemalloc). In support of this, you can specify your own allocator through `PXR_MALLOC_LIBRARY`. This variable should be set to a path to a shared object for the allocator. For example, ```bash -DPXR_MALLOC_LIBRARY:path=/usr/local/lib/libjemalloc.so ``` If none are specified, the default allocator will be used. More information on getting the most out of USD can be found [Getting the Best Performance with USD](http://openusd.org/docs/Maximizing-USD-Performance.html). ## Linker Options There are four ways to link USD controlled by the following options: | Option Name | Default | Description | | ---------------------- | --------- | ----------------------------------------- | | BUILD_SHARED_LIBS | `ON` | Build shared or static libraries | | PXR_BUILD_MONOLITHIC | `OFF` | Build single or several libraries | | PXR_MONOLITHIC_IMPORT | | CMake file defining usd_m import library | ##### Shared Libraries The default creates several shared libraries. This option allows loading just the libraries necessary for a given task. | Option Name | Value | | ---------------------- | --------- | | BUILD_SHARED_LIBS | `ON` | | PXR_BUILD_MONOLITHIC | `OFF` | | PXR_MONOLITHIC_IMPORT | | ```bash cmake -DBUILD_SHARED_LIBS=ON ... ``` ##### Static Libraries This mode builds several static libraries. This option allows embedding just the libraries necessary for a given task. However, it does not allow USD plugins or Python modules since that would necessarily cause multiple symbol definitions; for any given symbol we'd have an instance in the main application and another in each plugin/module. | Option Name | Value | | ---------------------- | --------- | | BUILD_SHARED_LIBS | `OFF` | | PXR_BUILD_MONOLITHIC | `OFF` | | PXR_MONOLITHIC_IMPORT | | ```bash cmake -DBUILD_SHARED_LIBS=OFF ... ``` ##### Internal Monolithic Library This mode builds the core libraries (i.e. everything under `pxr/`) into a single library, `usd_m`. The monolithic library will be static or shared based on the value of `BUILD_SHARED_LIBS`. It builds plugins outside of `pxr/` and Python modules as usual except they link against 'usd_m' instead of the individual libraries of the default mode. Plugins inside of `pxr/` are compiled into 'usd_m'. plugInfo.json files under `pxr/` refer to 'usd_m'. This mode is useful to reduce the number of installed files and simplify linking against USD. | Option Name | Value | | ---------------------- | ---------- | | BUILD_SHARED_LIBS | `ON` / `OFF` | | PXR_BUILD_MONOLITHIC | `ON` | | PXR_MONOLITHIC_IMPORT | | ```bash # Configuring to build a monolithic shared USD library cmake -DPXR_BUILD_MONOLITHIC=ON -DBUILD_SHARED_LIBS=ON ... # Configuring to build a monolithic static USD library cmake -DPXR_BUILD_MONOLITHIC=ON -DBUILD_SHARED_LIBS=OFF ... ``` > [!NOTE] > For historical consistency, the output filename of the USD shared monolithic > library is `usd_ms` while the static monolithic library is named `usd_m`. In > both cases the CMake target is `usd_m`. > [!WARNING] > Due to the need to link to the static monolithic library with the > `WHOLE_ARCHIVE` option (see [Linking Whole Archives](#linking-whole-archives)), > consumers should be aware that resulting executables and shared libraries will > be quite large as they are effectively bringing in every object file from USD. ##### External Monolithic Library This mode is similar to the [Internal Monolithic Library](#internal-monolithic-library) except the client has control of building the monolithic shared library. This mode is useful to embed USD into another shared library. The build steps are significantly more complicated and are described below. | Option Name | Value | | ---------------------- | ---------- | | BUILD_SHARED_LIBS | _Don't care_ | | PXR_BUILD_MONOLITHIC | `ON` | | PXR_MONOLITHIC_IMPORT | _Path-to-import-file_ | To build in this mode: 1. Choose a path where the import file will be. You'll be creating a cmake file with `add_library(usd_m SHARED IMPORTED)` and one or more `set_property` calls. The file doesn't need to exist. If it does exist it should be empty or valid cmake code. 1. Configure the build in the usual way but with `PXR_BUILD_MONOLITHIC=ON` and `PXR_MONOLITHIC_IMPORT` set to the path in step 1. 1. Build the usual way except the target is `monolithic`. 1. Create your shared library. If using cmake you can include the file `pxr/usd-targets-` under the USD binary (build) directory, where `` is the configuration you built in step 3. Then you can link your library against 'usd_m'. However, this isn't as simple as `target_link_libraries(mylib PUBLIC usd_m)` because you must get **everything** from 'usd_m'. See [Linking Whole Archives](#linking-whole-archives) for more details. 1. Edit the import file to describe your library. Your cmake build may be able to generate the file directly via `export()`. The USD build will include this file and having done so must be able to link against your library by adding 'usd_m' as a target link library. The file should look something like this: ```cmake add_library(usd_m SHARED IMPORTED) set_property(TARGET usd_m PROPERTY IMPORTED_LOCATION ...) # The following is necessary on Windows. #set_property(TARGET usd_m PROPERTY IMPORTED_IMPLIB ...) set_property(TARGET usd_m PROPERTY INTERFACE_COMPILE_DEFINITIONS ...) set_property(TARGET usd_m PROPERTY INTERFACE_INCLUDE_DIRECTORIES ...) set_property(TARGET usd_m PROPERTY INTERFACE_LINK_LIBRARIES ...) ``` 1. Complete the USD build by building the usual way, either with the default target or the 'install' target. Two notes: 1. Your library does **not** need to be named usd_m. That's simply the name given to it by the import file. The IMPORTED_LOCATION has the real name and path to your library. 1. USD currently only supports installations where your library is in the same directory the USD library/libraries would have been relative to the other installed USD files. Specifically, the location of your library will be used to find plugInfo.json files using the relative paths `../share/usd/plugins` and `../plugin/usd`. ###### Linking Whole Archives Normally when linking against a static library the linker will only pull in object files that provide a needed symbol. USD has many files that have static global objects with constructors with side effects. If nothing uses any visible symbol from those object files then a normal link would not include them. The side effects will not occur and USD will not work. To include everything you need to tell the linker to include the whole archive. The exact link flags to achieve this are platform-dependent but CMake 3.24 and above support the following platform-agnostic generator expression: ```cmake target_link_libraries(mylib "$") ``` ###### Avoiding linking statically to Python The default build with python support will link to the python static lib for your interpreter. This is to support running python code from C++. If that is not desirable, python static linking can be disabled using the flag ``` -DPXR_PY_UNDEFINED_DYNAMIC_LOOKUP=ON ``` The primary motivating case for this is generating wheel packages for PyPI, but the parameter was made more generic in case it has other uses in the future. It is useful when we want to take advantage of python's approach to ABI compatibility. Note that this flag has no effect on Windows, see [here for more info](https://docs.python.org/3/extending/windows.html) ## Spline Options Splines (keyframe animation) are implemented by the library `pxr/base/ts`. #### Default Anti-Regression Authoring Mode A `Ts` spline provides a function from time to attribute value. Bezier math permits long tangents to create shapes that go backwards in time, resulting in non-functions. This is typically prevented at authoring time, and there are several strategies available. See [pxr/base/ts/doxygen/regression.md](./pxr/base/ts/doxygen/regression.md) for details of the different choices. The hard-coded default is `TsAntiRegressionKeepRatio`. To set a different default: * With `build_usd.py`: `--build-args USD,"-DPXR_TS_DEFAULT_ANTI_REGRESSION_AUTHORING_MODE=TsAntiRegression..."` * With cmake: `-DPXR_TS_DEFAULT_ANTI_REGRESSION_AUTHORING_MODE=TsAntiRegression...` Client code can also override the default as needed. ## Build Issues FAQ 1. Windows and Python 3.8+ (non-Anaconda) Python 3.8 and later on Windows will no longer search PATH for DLL dependencies. Instead, clients can call `os.add_dll_directory(p)` to set paths to search. By default on that platform USD will iterate over PATH and add all paths using `os.add_dll_directory()` when importing Python modules. Users may override this by setting the environment variable `PXR_USD_WINDOWS_DLL_PATH` to a PATH-like string. If this is set, USD will use these paths instead. Note that the above does not apply to Anaconda python 3.8+ interpreters, as they are modified to behave like pre-3.8 python interpreters, and so continue to use the PATH for DLL dependencies. When running under Anaconda users should configure their system the same way they did for pre-python 3.8.