Add separate build step for OpenUSD to third_party_deps.

This will fetch and call the build_usd.py build helper for OpenUSD and build within the MuJoCo _deps folder. Simplifying the build process for MuJoCo with USD. Users can still provide their own USD build, but must now do so via pxr_DIR.

PiperOrigin-RevId: 846735578
Change-Id: I0da7eb2da6465e2d518084340e762bf370adb6d5
This commit is contained in:
Sam Haves
2025-12-19 07:59:17 -08:00
committed by Copybara-Service
parent 76e0a78b32
commit 9e150fe82c
6 changed files with 178 additions and 109 deletions
+18 -20
View File
@@ -54,25 +54,6 @@ if(EMSCRIPTEN)
option(MUJOCO_BUILD_TESTS_WASM "Build tests for WASM bindings" ON)
endif()
# Option to provide a path to an existing USD build directory or to Houdini HFS directory.
set(USD_DIR "" CACHE PATH "Path to an existing USD build directory.")
set(HOUDINI_HFS_DIR "" CACHE PATH "Path to Houdini HFS directory to build USD plugins against.")
if(USD_DIR)
if(EXISTS "${USD_DIR}")
# If the path is provided, set MUJOCO_WITH_USD to ON and add the path to CMAKE_PREFIX_PATH.
set(MUJOCO_WITH_USD ON CACHE BOOL "Build with OpenUSD" FORCE)
list(PREPEND CMAKE_PREFIX_PATH "${USD_DIR}")
message(STATUS "Using custom USD build directory: ${USD_DIR}")
else()
message(WARNING "Invalid path provided for USD_DIR: ${USD_DIR}")
endif()
elseif(HOUDINI_HFS_DIR)
if(EXISTS "${HOUDINI_HFS_DIR}")
set(MUJOCO_WITH_USD ON CACHE BOOL "Build with OpenUSD" FORCE)
message(STATUS "Building Mujoco USD against Houdini HFS: ${HOUDINI_HFS_DIR}")
endif()
endif()
if(APPLE AND (MUJOCO_BUILD_EXAMPLES OR MUJOCO_BUILD_SIMULATE))
enable_language(OBJC)
enable_language(OBJCXX)
@@ -243,7 +224,24 @@ if(MUJOCO_BUILD_EXAMPLES)
endif()
if(MUJOCO_WITH_USD)
target_compile_definitions(mujoco PUBLIC mjUSEUSD)
include(third_party_deps/openusd)
get_filename_component(USD_INSTALL_ROOT "${pxr_DIR}/lib" ABSOLUTE)
install(
DIRECTORY ${USD_INSTALL_ROOT}/
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
if(APPLE)
set_target_properties(mujoco PROPERTIES
BUILD_RPATH "${USD_INSTALL_ROOT}"
INSTALL_RPATH "@loader_path")
elseif(UNIX)
set_target_properties(mujoco PROPERTIES
BUILD_RPATH "${USD_INSTALL_ROOT}"
INSTALL_RPATH "$ORIGIN")
endif()
add_subdirectory(src/experimental/usd)
endif()
+38
View File
@@ -0,0 +1,38 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Find OpenUSD package. The user can either provide pxr_DIR to use their own
# OpenUSD installation or they can build external_dependencies.
#
# We use QUIET here to provide a better error message when pxr is not found.
find_package(pxr
QUIET
HINTS "${CMAKE_BINARY_DIR}/_deps/openusd-build"
)
if(NOT pxr_FOUND)
message(FATAL_ERROR
"-----------------------------------------------------------\n"
"USD Configuration Error:\n${pxr_NOT_FOUND_MESSAGE}\n"
"If you have built USD yourself, provide -Dpxr_DIR=your_pxr_install_dir' \n"
"Otherwise you can build cmake/third_party_deps/openusd:\n"
"cd ~/mujoco\n"
"cmake -Bcmake/third_party_deps/openusd/build cmake/third_party_deps/openusd -DBUILD_USD=True\n"
"cmake --build cmake/third_party_deps/openusd/build\n"
"cmake -Bbuild -S. -DMUJOCO_WITH_USD=True\n"
"cmake --build build\n"
"cmake --install build"
"-----------------------------------------------------------"
)
endif()
@@ -0,0 +1,54 @@
# Copyright 2025 DeepMind Technologies Limited
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION "3.16")
option(BUILD_USD OFF "Build OpenUSD")
project(openusd-dependency)
if (BUILD_USD)
include(ExternalProject)
set(DEPS_DIR ${CMAKE_BINARY_DIR}/../../../../build/_deps)
ExternalProject_Add(openusd
GIT_REPOSITORY https://github.com/PixarAnimationStudios/USD.git
GIT_TAG v25.11
PREFIX openusd
BUILD_IN_SOURCE 0
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
INSTALL_COMMAND ""
SOURCE_DIR ${DEPS_DIR}/openusd-src
BINARY_DIR ${DEPS_DIR}/openusd-build
INSTALL_DIR ${DEPS_DIR}/openusd-build
BUILD_COMMAND python3 ${DEPS_DIR}/openusd-src/build_scripts/build_usd.py
--build-shared
--no-examples
--no-tools
--no-ptex
--no-prman
--no-openimageio
--no-opencolorio
--no-alembic
--no-draco
--no-materialx
--no-tutorials
--no-tests
--no-docs
--no-imaging
--no-python
--no-usdValidation
<INSTALL_DIR>
)
endif()
+12 -4
View File
@@ -185,7 +185,7 @@ if(SIMULATE_BUILD_EXECUTABLE)
target_link_libraries(simulate "-framework CoreVideo")
endif()
if (MUJOCO_WITH_USD)
if (BUILD_WITH_USD)
# pxr/usd/tf/hashset.h might include deprecated headers so disable this check
# when compiling with USD enabled.
target_compile_options(
@@ -265,8 +265,13 @@ if(SIMULATE_BUILD_EXECUTABLE)
MUJOCO_ENABLE_RPATH
)
if (MUJOCO_WITH_USD)
target_compile_definitions(simulate PUBLIC mjUSEUSD)
if (BUILD_WITH_USD)
# pxr/usd/tf/hashset.h might include deprecated headers so disable this check
# when compiling with USD enabled.
target_compile_options(
simulate
PRIVATE -Wno-deprecated
)
# Add support to RPATH for the samples.
target_add_rpath(
@@ -275,10 +280,13 @@ if(SIMULATE_BUILD_EXECUTABLE)
INSTALL_DIRECTORY
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
LIB_DIRS
${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/mujocoUsd ${USD_DIR}/lib
DEPENDS
MUJOCO_ENABLE_RPATH
)
# Do we need this?
#target_link_options(simulate PRIVATE -rpath=${pxr_DIR}/lib)
endif()
if(NOT MUJOCO_SIMULATE_USE_SYSTEM_GLFW)
+55 -82
View File
@@ -18,7 +18,7 @@ set(MJCF_PLUGIN_TARGET_NAME usdMjcf)
set(MJC_PHYSICS_PLUGIN_TARGET_NAME mjcPhysics)
# Installation directory for USD plugins
set(MJ_USD_INSTALL_DIR_LIB ${CMAKE_INSTALL_LIBDIR}/mujocoUsd)
set(MJ_USD_INSTALL_DIR_LIB ${CMAKE_INSTALL_LIBDIR}/mujoco-usd-resources)
# Common OpenUSD libraries
set(OPENUSD_CORE_LIBS
@@ -41,7 +41,7 @@ function(configure_and_install_usd_plugin_info plugin_name source_subpath instal
endif()
set(PLUG_INFO_LIBRARY_PATH "../../${LIB_PREFIX}${plugin_name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/${install_base_dir}/resources/${plugin_name}")
set(OUTPUT_DIR "${CMAKE_BINARY_DIR}/${install_base_dir}/${plugin_name}")
set(OUTPUT_FILE "${OUTPUT_DIR}/plugInfo.json")
# Create the output directory if it doesn't exist
@@ -55,7 +55,7 @@ function(configure_and_install_usd_plugin_info plugin_name source_subpath instal
)
install(FILES "${OUTPUT_FILE}"
DESTINATION "${install_base_dir}/resources/${plugin_name}"
DESTINATION "${install_base_dir}/${plugin_name}"
)
endfunction()
@@ -82,6 +82,7 @@ function(configure_houdini_target target_name link_scope include_scope)
${PXR_LIB_PREFIX}usdShade
${PXR_LIB_PREFIX}usdLux
${PXR_LIB_PREFIX}usdGeom
${PXR_LIB_PREFIX}usdImaging
${PXR_LIB_PREFIX}usdPhysics
tbb
hboost_${USD_MJCF_PYTHON_LIB_NUMBER}
@@ -101,56 +102,9 @@ function(configure_houdini_target target_name link_scope include_scope)
endfunction()
## usdMjcf
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# The list of RPATHs:
# 1. $ORIGIN: For libmjcPhysics.so (since it's in the same install dir)
# 2. Path to OpenUSD libraries: Typically ${USD_DIR}/lib
# 3. Path to MuJoCo library: Assuming it's in ${MUJOCO_INSTALL_DIR}/lib
if(APPLE)
set(RPATH_LIST "@loader_path")
# Add OpenUSD lib to RPATH for macOS
if(DEFINED USD_DIR AND EXISTS "${USD_DIR}/lib")
list(APPEND RPATH_LIST "${USD_DIR}/lib")
endif()
# Add MuJoCo lib to RPATH for macOS
if(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/lib")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/lib")
endif()
string(JOIN ":" CMAKE_INSTALL_RPATH "${RPATH_LIST}") # macOS uses colon for RPATH separator
message(STATUS "Final CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
elseif(UNIX)
# For adjacent libs.
set(RPATH_LIST "\$ORIGIN")
# Add OpenUSD library directory
if(DEFINED USD_DIR AND EXISTS "${USD_DIR}/lib")
list(APPEND RPATH_LIST "${USD_DIR}/lib")
message(STATUS "Adding OpenUSD lib to RPATH: ${USD_DIR}/lib")
else()
message(WARNING "USD_DIR is not defined or ${USD_DIR}/lib does not exist. OpenUSD libraries might not be found via RPATH.")
endif()
# Add MuJoCo library directory
if(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/lib")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/lib")
message(STATUS "Adding MuJoCo lib to RPATH: ${MUJOCO_INSTALL_DIR}/lib")
elseif(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/bin")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/bin")
message(STATUS "Adding MuJoCo bin to RPATH: ${MUJOCO_INSTALL_DIR}/bin")
endif()
# Set the final RPATH for installation
string(JOIN ";" CMAKE_INSTALL_RPATH "${RPATH_LIST}")
message(STATUS "Final CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
endif()
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
add_library(${MJCF_PLUGIN_TARGET_NAME} SHARED)
add_library(mujoco::usd::mjcf ALIAS ${MJCF_PLUGIN_TARGET_NAME})
target_sources(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
plugins/mjcf/mjcf_file_format.cc
plugins/mjcf/mjcf_file_format.h
@@ -167,7 +121,7 @@ target_include_directories(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/plugins"
)
## mjcPhysics
## ----- mjcPhysics -----
add_library(${MJC_PHYSICS_PLUGIN_TARGET_NAME} SHARED)
target_sources(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE
@@ -191,7 +145,7 @@ target_include_directories(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../../../include>
)
## mj_usd
## ----- mujoco USD utils -----
target_sources(mujoco PRIVATE
kinematic_tree.cc
@@ -211,42 +165,61 @@ target_compile_options(
PRIVATE -Wno-deprecated
)
if (USD_DIR)
find_package(pxr REQUIRED)
# Configure RPATH for macOS and UNIX.
if(APPLE)
set(RPATH_LIST "@loader_path")
# Add OpenUSD lib to RPATH for macOS
if(DEFINED pxr_DIR AND EXISTS "${pxr_DIR}/lib")
list(APPEND RPATH_LIST "${pxr_DIR}/lib")
endif()
# Add MuJoCo lib to RPATH for macOS
if(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/lib")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/lib")
endif()
target_link_libraries(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE
${OPENUSD_CORE_LIBS}
)
string(JOIN ":" CMAKE_INSTALL_RPATH "${RPATH_LIST}") # macOS uses colon for RPATH separator
message(STATUS "Final CMAKE_INSTALL_RPATH: ${CMAKE_INSTALL_RPATH}")
elseif(UNIX)
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
${OPENUSD_CORE_LIBS}
mujoco
tinyxml2
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
)
# For adjacent libs.
set(RPATH_LIST "\$ORIGIN")
target_link_libraries(mujoco PUBLIC
${OPENUSD_CORE_LIBS}
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
)
elseif (HOUDINI_HFS_DIR)
message(STATUS "Configuring for Houdini target...")
# Add OpenUSD library directory
if(DEFINED pxr_DIR AND EXISTS "${pxr_DIR}/lib")
list(APPEND RPATH_LIST "${pxr_DIR}/lib")
message(STATUS "Adding OpenUSD lib to RPATH: ${pxr_DIR}/lib")
else()
message(WARNING "pxr_DIR is not defined or ${pxr_DIR}/lib does not exist. OpenUSD libraries might not be found via RPATH.")
endif()
# In Houdini, the Houdini package we would typically use via find_package
# does not have all the USD dependencies that we need (namely UsdPhysics)
# so we need to manually link all the required libraries.
configure_houdini_target(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
configure_houdini_target(${MJCF_PLUGIN_TARGET_NAME} PRIVATE PRIVATE)
# Re-add inter-plugin dependencies after Houdini-specific linking
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE ${MJC_PHYSICS_PLUGIN_TARGET_NAME})
# Add MuJoCo library directory
if(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/lib")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/lib")
elseif(DEFINED MUJOCO_INSTALL_DIR AND EXISTS "${MUJOCO_INSTALL_DIR}/bin")
list(APPEND RPATH_LIST "${MUJOCO_INSTALL_DIR}/bin")
endif()
# Set the final RPATH for installation
string(JOIN ";" CMAKE_INSTALL_RPATH "${RPATH_LIST}")
endif()
## Installation
target_link_libraries(${MJC_PHYSICS_PLUGIN_TARGET_NAME} PRIVATE
${OPENUSD_CORE_LIBS}
)
message(STATUS "Mujoco USD plugins will be installed to: ${CMAKE_INSTALL_PREFIX}/${MJ_USD_INSTALL_DIR_LIB}")
message(STATUS "Make sure PXR_PLUGINPATH_NAME includes: ${CMAKE_INSTALL_PREFIX}/${MJ_USD_INSTALL_DIR_LIB}/*/resources")
target_link_libraries(${MJCF_PLUGIN_TARGET_NAME} PRIVATE
${OPENUSD_CORE_LIBS}
mujoco
tinyxml2
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
)
target_link_libraries(mujoco PUBLIC
${OPENUSD_CORE_LIBS}
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
)
## Installation
# Generate and install plugInfo.json for each plugin
configure_and_install_usd_plugin_info(
@@ -263,7 +236,7 @@ configure_and_install_usd_plugin_info(
# Install specific resources that are not plugInfo.json (like generatedSchema.usda)
install(FILES
mjcPhysics/generatedSchema.usda
DESTINATION ${MJ_USD_INSTALL_DIR_LIB}/resources/mjcPhysics
DESTINATION ${MJ_USD_INSTALL_DIR_LIB}/mjcPhysics
)
# Install shared libraries
@@ -271,5 +244,5 @@ install(TARGETS
${MJCF_PLUGIN_TARGET_NAME}
${MJC_PHYSICS_PLUGIN_TARGET_NAME}
EXPORT ${PROJECT_NAME}
LIBRARY DESTINATION ${MJ_USD_INSTALL_DIR_LIB}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
+1 -3
View File
@@ -13,9 +13,7 @@
# limitations under the License.
# Only support testing when building against a standalone version of USD.
if(MUJOCO_WITH_USD AND USD_DIR)
find_package(pxr REQUIRED)
if(MUJOCO_WITH_USD)
add_library(usd_test_utils STATIC usd/test_utils.h usd/test_utils.cc)
target_include_directories(usd_test_utils PUBLIC ${MUJOCO_TEST_INCLUDE})
target_compile_definitions(usd_test_utils PUBLIC MJSTATIC)