CMake: add hdCycles Hydra delegate build and deployment
- Build Cycles from third_party/cycles via ExternalProject (WITH_CYCLES=ON) - Deploy hdCycles.dll + plugin metadata to usd/ alongside hdEmbree/hdArnold - Copy Cycles runtime deps (embree4, openvdb, OIDN, sycl, imath, etc.) via a cmake -P script that globs at build time, excluding CRT DLLs to avoid MSVCP140 version conflicts - Deploy tbb12.dll explicitly from the precompiled lib tree (required by openvdb/embree4 but absent from the install output) - Bake all renderer paths into CMakePresets.json default preset (WITH_CYCLES, HDARNOLD_ROOT -> E:/library/hdArnold, ARNOLD_LOCATION, HDEMBREE_USD_ROOT) so a fresh configure needs no manual -D flags Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+168
-6
@@ -60,14 +60,96 @@ if(HDARNOLD_ROOT AND EXISTS "${HDARNOLD_ROOT}/plugin/hdArnold.dll")
|
||||
set(NDRARNOLD_PLUGIN_DIR "${HDARNOLD_ROOT}/plugin/ndrArnold")
|
||||
if(ARNOLD_LOCATION AND EXISTS "${ARNOLD_LOCATION}/bin/ai.dll")
|
||||
set(ARNOLD_AI_DLL "${ARNOLD_LOCATION}/bin/ai.dll")
|
||||
# ai.dll also requires companion runtime DLLs (OIDN denoiser, Adsk licensing, cer)
|
||||
file(GLOB ARNOLD_RUNTIME_DLLS
|
||||
"${ARNOLD_LOCATION}/bin/ai*.dll"
|
||||
"${ARNOLD_LOCATION}/bin/AdClm*.dll"
|
||||
"${ARNOLD_LOCATION}/bin/AdskLicensing*.dll"
|
||||
"${ARNOLD_LOCATION}/bin/cer.dll"
|
||||
)
|
||||
else()
|
||||
set(ARNOLD_AI_DLL "")
|
||||
set(ARNOLD_RUNTIME_DLLS "")
|
||||
endif()
|
||||
else()
|
||||
set(OPENUSD_HAS_ARNOLD FALSE)
|
||||
message(STATUS "hdArnold: NOT found — set HDARNOLD_ROOT to the arnold-usd install dir and ARNOLD_LOCATION to the MtoA root")
|
||||
endif()
|
||||
|
||||
# ── Cycles hdCycles Hydra render delegate ────────────────────────────────────
|
||||
# Build Blender Cycles from third_party/cycles using ExternalProject.
|
||||
# Set WITH_CYCLES=ON to enable; requires MSVC, and uses the precompiled libs
|
||||
# bundled in third_party/cycles/lib/windows_x64/.
|
||||
# hdCycles.dll is deployed to usd/ alongside hdEmbree and hdArnold.
|
||||
option(WITH_CYCLES "Build Cycles Hydra render delegate from third_party/cycles" OFF)
|
||||
|
||||
set(CYCLES_BINARY_DIR "${CMAKE_BINARY_DIR}/cycles_build")
|
||||
set(CYCLES_INSTALL_DIR "${CMAKE_BINARY_DIR}/cycles_install")
|
||||
set(HDCYCLES_DLL "${CYCLES_INSTALL_DIR}/hydra/hdCycles.dll")
|
||||
set(HDCYCLES_PLUGIN_DIR "${CYCLES_INSTALL_DIR}/hydra/hdCycles")
|
||||
# tbb12.dll is required by openvdb/embree4 but lives in the precompiled lib tree,
|
||||
# not in the install output — deploy it explicitly.
|
||||
set(CYCLES_TBB12_DLL "${CMAKE_SOURCE_DIR}/third_party/cycles/lib/windows_x64/tbb/bin/tbb12.dll")
|
||||
|
||||
if(WITH_CYCLES)
|
||||
include(ExternalProject)
|
||||
|
||||
# Resolve absolute USD root so we can forward it to the sub-build.
|
||||
# FindOpenUSD.cmake stores the path in OpenUSD_ROOT_DIR.
|
||||
if(NOT OpenUSD_ROOT_DIR)
|
||||
message(FATAL_ERROR "WITH_CYCLES requires OpenUSD_ROOT_DIR to be set (run find_package(OpenUSD) first).")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(CyclesBuild
|
||||
SOURCE_DIR "${CMAKE_SOURCE_DIR}/third_party/cycles"
|
||||
BINARY_DIR "${CYCLES_BINARY_DIR}"
|
||||
INSTALL_DIR "${CYCLES_INSTALL_DIR}"
|
||||
CMAKE_ARGS
|
||||
# Always Release — Cycles' Debug build is slow and rarely needed here.
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
|
||||
# Point Cycles at our app's USD so hdCycles is ABI-compatible.
|
||||
-DPXR_ROOT=${OpenUSD_ROOT_DIR}
|
||||
# Hydra delegate is the only deliverable we need.
|
||||
-DWITH_CYCLES_HYDRA_RENDER_DELEGATE=ON
|
||||
-DWITH_CYCLES_USD=ON
|
||||
# Use bundled precompiled libs from lib/windows_x64/.
|
||||
-DWITH_LIBS_PRECOMPILED=ON
|
||||
# Turn off heavy optional features that aren't needed for the delegate.
|
||||
-DWITH_CYCLES_STANDALONE_GUI=OFF
|
||||
-DWITH_CYCLES_DEVICE_CUDA=OFF
|
||||
-DWITH_CYCLES_DEVICE_OPTIX=OFF
|
||||
-DWITH_CYCLES_DEVICE_HIP=OFF
|
||||
-DWITH_CYCLES_DEVICE_ONEAPI=OFF
|
||||
-DWITH_CYCLES_LOGGING=OFF
|
||||
# ---- pxrConfig.cmake dependency overrides ----
|
||||
# pxrConfig.cmake runs find_dependency() for these before Cycles'
|
||||
# precompiled lib paths are on CMAKE_PREFIX_PATH, so we must supply
|
||||
# them explicitly. The Python3 vars also override the hardcoded
|
||||
# CI build-machine path embedded in pxrConfig.cmake.
|
||||
-DPython3_EXECUTABLE=$ENV{LOCALAPPDATA}/Programs/Python/Python312/python.exe
|
||||
-DPython3_LIBRARY=$ENV{LOCALAPPDATA}/Programs/Python/Python312/libs/python312.lib
|
||||
-DPython3_INCLUDE_DIR=$ENV{LOCALAPPDATA}/Programs/Python/Python312/include
|
||||
-DTBB_DIR=${OpenUSD_ROOT_DIR}/lib/cmake/TBB
|
||||
-DMaterialX_DIR=${OpenUSD_ROOT_DIR}/lib/cmake/MaterialX
|
||||
# Our USD install has no standalone OpenSubdiv/Imath cmake packages
|
||||
# (they're linked into the USD DLLs); skip those find_dependency calls.
|
||||
-DPXR_FIND_OPENSUBDIV_IN_CONFIG=OFF
|
||||
-DPXR_FIND_IMATH_IN_CONFIG=OFF
|
||||
BUILD_COMMAND
|
||||
${CMAKE_COMMAND} --build <BINARY_DIR> --config Release
|
||||
INSTALL_COMMAND
|
||||
${CMAKE_COMMAND} --install <BINARY_DIR> --config Release
|
||||
BUILD_BYPRODUCTS
|
||||
"${HDCYCLES_DLL}"
|
||||
)
|
||||
|
||||
set(OPENUSD_HAS_CYCLES TRUE)
|
||||
else()
|
||||
set(OPENUSD_HAS_CYCLES FALSE)
|
||||
message(STATUS "hdCycles: disabled — set WITH_CYCLES=ON to build from third_party/cycles")
|
||||
endif()
|
||||
|
||||
# Collect source files
|
||||
file(GLOB_RECURSE CORE_SOURCES "src/core/*.cpp")
|
||||
file(GLOB_RECURSE UI_SOURCES "src/ui/*.cpp")
|
||||
@@ -97,6 +179,12 @@ target_link_libraries(UsdLayerManager PRIVATE
|
||||
Glad::Glad
|
||||
)
|
||||
|
||||
# Cycles is an ExternalProject; UsdLayerManager must wait for it to finish
|
||||
# before POST_BUILD copies hdCycles.dll to the output directory.
|
||||
if(WITH_CYCLES)
|
||||
add_dependencies(UsdLayerManager CyclesBuild)
|
||||
endif()
|
||||
|
||||
# Platform-specific settings
|
||||
if(WIN32)
|
||||
# Windows-specific settings
|
||||
@@ -171,15 +259,61 @@ if(WIN32)
|
||||
"$<TARGET_FILE_DIR:UsdLayerManager>/usd/ndrArnold"
|
||||
COMMENT "Copying hdArnold plugin..."
|
||||
)
|
||||
if(ARNOLD_AI_DLL)
|
||||
if(ARNOLD_RUNTIME_DLLS)
|
||||
add_custom_command(TARGET UsdLayerManager POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${ARNOLD_AI_DLL}"
|
||||
${ARNOLD_RUNTIME_DLLS}
|
||||
"$<TARGET_FILE_DIR:UsdLayerManager>"
|
||||
COMMENT "Copying Arnold runtime ai.dll..."
|
||||
COMMENT "Copying Arnold runtime DLLs (ai, OIDN, licensing)..."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENUSD_HAS_CYCLES)
|
||||
# hdCycles uses the same usd/ layout as hdEmbree:
|
||||
# usd/hdCycles.dll + usd/hdCycles/resources/plugInfo.json
|
||||
# The bundled plugInfo.json has Root=".." and LibraryPath="../hdCycles.dll"
|
||||
# which resolves correctly once the plugin dir lives in usd/.
|
||||
#
|
||||
# Runtime deps (embree4, epoxy, imath, openvdb, OIDN, sycl, vulkan, etc.)
|
||||
# live in CYCLES_INSTALL_DIR root and must be next to the exe. We can't
|
||||
# file(GLOB) them at configure time (ExternalProject hasn't run yet), so we
|
||||
# write a small cmake -P script that globs them at build time instead.
|
||||
# The script runs at build time (after ExternalProject finishes) so it can glob
|
||||
# the actual install output. CRT/Windows DLLs are excluded — they must come
|
||||
# from the system or the main exe's toolchain, not from Cycles' bundled copy.
|
||||
file(WRITE "${CMAKE_BINARY_DIR}/copy_cycles_runtime_dlls.cmake"
|
||||
"file(GLOB _all_dlls \"${CYCLES_INSTALL_DIR}/*.dll\")\n"
|
||||
"set(_dlls)\n"
|
||||
"foreach(_dll \${_all_dlls})\n"
|
||||
" get_filename_component(_name \"\${_dll}\" NAME)\n"
|
||||
" string(TOLOWER \"\${_name}\" _lname)\n"
|
||||
" if(_lname MATCHES \"^(msvcp|vcruntime|ucrtbase|concrt|api-ms-win-)\")\n"
|
||||
" continue()\n"
|
||||
" endif()\n"
|
||||
" list(APPEND _dlls \"\${_dll}\")\n"
|
||||
"endforeach()\n"
|
||||
"if(_dlls)\n"
|
||||
" file(COPY \${_dlls} DESTINATION \"\${DEST_DIR}\")\n"
|
||||
"endif()\n"
|
||||
)
|
||||
add_custom_command(TARGET UsdLayerManager POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${HDCYCLES_DLL}"
|
||||
"$<TARGET_FILE_DIR:UsdLayerManager>/usd/hdCycles.dll"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
"${HDCYCLES_PLUGIN_DIR}"
|
||||
"$<TARGET_FILE_DIR:UsdLayerManager>/usd/hdCycles"
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DDEST_DIR=$<TARGET_FILE_DIR:UsdLayerManager>"
|
||||
-P "${CMAKE_BINARY_DIR}/copy_cycles_runtime_dlls.cmake"
|
||||
# tbb12.dll is required by openvdb/embree4 but is not in the install output
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"${CYCLES_TBB12_DLL}"
|
||||
"$<TARGET_FILE_DIR:UsdLayerManager>/tbb12.dll"
|
||||
COMMENT "Copying hdCycles plugin and runtime DLLs..."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compiler warnings
|
||||
@@ -251,14 +385,36 @@ if(OPENUSD_HAS_ARNOLD)
|
||||
DESTINATION bin/usd
|
||||
OPTIONAL
|
||||
)
|
||||
if(ARNOLD_AI_DLL)
|
||||
install(FILES "${ARNOLD_AI_DLL}"
|
||||
if(ARNOLD_RUNTIME_DLLS)
|
||||
install(FILES ${ARNOLD_RUNTIME_DLLS}
|
||||
DESTINATION bin
|
||||
OPTIONAL
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENUSD_HAS_CYCLES)
|
||||
install(FILES "${HDCYCLES_DLL}"
|
||||
DESTINATION bin/usd
|
||||
OPTIONAL
|
||||
)
|
||||
install(DIRECTORY "${HDCYCLES_PLUGIN_DIR}"
|
||||
DESTINATION bin/usd
|
||||
OPTIONAL
|
||||
)
|
||||
# Cycles runtime deps (embree4, epoxy, imath, openvdb, OIDN, sycl, etc.)
|
||||
install(DIRECTORY "${CYCLES_INSTALL_DIR}/"
|
||||
DESTINATION bin
|
||||
FILES_MATCHING PATTERN "*.dll"
|
||||
OPTIONAL
|
||||
)
|
||||
# tbb12.dll (used by openvdb/embree4) lives in the precompiled lib tree, not install output
|
||||
install(FILES "${CYCLES_TBB12_DLL}"
|
||||
DESTINATION bin
|
||||
OPTIONAL
|
||||
)
|
||||
endif()
|
||||
|
||||
# Install Python runtime DLLs required by OpenUSD.
|
||||
install(FILES
|
||||
"$ENV{LOCALAPPDATA}/Programs/Python/Python312/python312.dll"
|
||||
@@ -318,11 +474,17 @@ endif()
|
||||
message(STATUS "hdArnold support: ${OPENUSD_HAS_ARNOLD}")
|
||||
if(OPENUSD_HAS_ARNOLD)
|
||||
message(STATUS "hdArnold DLL: ${HDARNOLD_DLL}")
|
||||
message(STATUS "Arnold ai.dll: ${ARNOLD_AI_DLL}")
|
||||
message(STATUS "Arnold runtime DLLs: ${ARNOLD_RUNTIME_DLLS}")
|
||||
if(NOT ARNOLD_AI_DLL)
|
||||
message(WARNING "hdArnold found but ai.dll not located — set ARNOLD_LOCATION to the MtoA root (e.g. C:/Autodesk/mtoa/5.5.0/2026)")
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "hdCycles support: ${OPENUSD_HAS_CYCLES}")
|
||||
if(OPENUSD_HAS_CYCLES)
|
||||
message(STATUS "Cycles source: ${CMAKE_SOURCE_DIR}/third_party/cycles")
|
||||
message(STATUS "Cycles build: ${CYCLES_BINARY_DIR}")
|
||||
message(STATUS "Cycles install: ${CYCLES_INSTALL_DIR}")
|
||||
endif()
|
||||
message(STATUS "=======================================")
|
||||
message(STATUS "")
|
||||
|
||||
|
||||
+5
-1
@@ -13,7 +13,11 @@
|
||||
"IMGUI_DIR": "${sourceDir}/third_party/imgui-1.92.7",
|
||||
"CMAKE_CXX_STANDARD": "17",
|
||||
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
|
||||
"BUILD_TESTS": "ON"
|
||||
"BUILD_TESTS": "ON",
|
||||
"WITH_CYCLES": "ON",
|
||||
"HDARNOLD_ROOT": "E:/library/hdArnold",
|
||||
"ARNOLD_LOCATION": "C:/Autodesk/mtoa/5.5.0/2026",
|
||||
"HDEMBREE_USD_ROOT": "E:/USD_v25.05_embree"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user