From 7718de4f2950a9c6a142e2602aebe7bb0722bca7 Mon Sep 17 00:00:00 2001 From: "Shelton, Nick (NBCUniversal)" Date: Fri, 31 Jul 2026 15:52:18 -0700 Subject: [PATCH 1/4] Merge pull request #232 from dwanim/nshelton/support-cmake4-clang21 MOONRAY-6112 Support MacOS Tahoe 26.5 build - update cmake modules submodule - use CommandlineTools instead of XCode python, so we can build without XCode. Signed-off-by: Nick Shelton --- CMakeDWAPresets.json | 7 +- CMakeMacOSPresets.json | 6 +- building/.DS_Store | Bin 0 -> 6148 bytes building/macOS/Boost.patch | 25 +++--- building/macOS/CMakeLists.txt | 143 ++++++++++++++++++--------------- building/macOS/macOS_build.md | 11 ++- building/macOS/user-config.jam | 6 +- cmake_modules | 2 +- 8 files changed, 115 insertions(+), 85 deletions(-) create mode 100644 building/.DS_Store diff --git a/CMakeDWAPresets.json b/CMakeDWAPresets.json index ee23dee1..ba8f7277 100644 --- a/CMakeDWAPresets.json +++ b/CMakeDWAPresets.json @@ -24,7 +24,12 @@ "OIIO_PYTHON" : "$env{DEPS_ROOT}/lib/python3.9/site-packages" }, "cacheVariables": { - "CMAKE_PREFIX_PATH": "$env{DEPS_ROOT}" + "CMAKE_PREFIX_PATH": "$env{DEPS_ROOT}", + "BUILD_MATERIALX_SHADERS": "ON", + "CMAKE_IGNORE_PATH": "/opt/homebrew", + "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew", + "CMAKE_POLICY_VERSION_MINIMUM": "3.5", + "Python_EXECUTABLE": "/usr/bin/python3" } }, { diff --git a/CMakeMacOSPresets.json b/CMakeMacOSPresets.json index f13d05ef..3d5d6e71 100644 --- a/CMakeMacOSPresets.json +++ b/CMakeMacOSPresets.json @@ -25,7 +25,11 @@ "OIIO_PYTHON" : "$env{DEPS_ROOT}/lib/python3.9/site-packages" }, "cacheVariables": { - "CMAKE_PREFIX_PATH": "$env{DEPS_ROOT}" + "CMAKE_PREFIX_PATH": "$env{DEPS_ROOT}", + "CMAKE_IGNORE_PATH": "/opt/homebrew", + "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew", + "CMAKE_POLICY_VERSION_MINIMUM": "3.5", + "Python_EXECUTABLE": "/usr/bin/python3" } }, { diff --git a/building/.DS_Store b/building/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..969df20583e8f333b026d6247313ea443cd487bb GIT binary patch literal 6148 zcmeH~J&pn~427S8m5^vCDbwr$xIu)5nt}@~3nhqRwSA7h&yE`gYBX9sOU{d(cz(WO zG6rC~-^&(Q16a~s@#(|JjPVCj9nDcwEnAi3o^*2#A0P zh`@vh#39b}e>I_J(xZrg2uy>3e;*3nwWhYN@#)|YEdX`FbQtH+OHhj^s5P~9Wrk+i zJy@1nv>~34a%#zaHMMo^<*;l%EbnaI#n7ym!wLhM)esFLAOa%-^B%AL{NK}G_5Y(1 zg(4sV|BQewhU2i~OXb=6^m?BE%B;^Dof_LYJp2SO@S}J`5950A3ALuSuFTN%BM=xg Jh`?J3`~g7x6D$A# literal 0 HcmV?d00001 diff --git a/building/macOS/Boost.patch b/building/macOS/Boost.patch index e406f5f4..4eade256 100644 --- a/building/macOS/Boost.patch +++ b/building/macOS/Boost.patch @@ -1,8 +1,6 @@ -Only in Boost-prefix-mod/src/Boost: b2 -Only in Boost-prefix-mod/src/Boost: bin.v2 diff -ru Boost-prefix/src/Boost/boost/mpl/aux_/integral_wrapper.hpp Boost-prefix-mod/src/Boost/boost/mpl/aux_/integral_wrapper.hpp ---- Boost-prefix/src/Boost/boost/mpl/aux_/integral_wrapper.hpp 2025-10-19 16:45:55 -+++ Boost-prefix-mod/src/Boost/boost/mpl/aux_/integral_wrapper.hpp 2025-10-19 16:37:32 +--- Boost-prefix/src/Boost/boost/mpl/aux_/integral_wrapper.hpp 2026-07-16 20:54:37 ++++ Boost-prefix-mod/src/Boost/boost/mpl/aux_/integral_wrapper.hpp 2026-07-16 20:54:03 @@ -13,6 +13,11 @@ // NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION! @@ -15,8 +13,17 @@ diff -ru Boost-prefix/src/Boost/boost/mpl/aux_/integral_wrapper.hpp Boost-prefix #include #include #include -Only in Boost-prefix-mod/src/Boost: project-config.jam -Only in Boost-prefix-mod/src/Boost/tools/build/src/engine: b2 -Only in Boost-prefix-mod/src/Boost/tools/build/src/engine: bjam -Only in Boost-prefix-mod/src/Boost-stamp: Boost-configure -Only in Boost-prefix-mod/src/Boost-stamp: Boost-patch +@@ -68,6 +73,13 @@ + || (BOOST_WORKAROUND(__HP_aCC, <= 53800) && (BOOST_WORKAROUND(__hpxstd98, != 1))) + typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)) ) next; + typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)) ) prior; ++#elif defined(__clang__) ++ // clang rejects out-of-range enum conversions in constant expressions ++ // (a hard error since clang 20 that pragmas cannot suppress), so keep ++ // enum-typed wrappers at their current value: next/prior arithmetic is ++ // only meaningful for integral value types. ++ typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (__is_enum(AUX_WRAPPER_VALUE_TYPE) ? value : value + 1)) ) next; ++ typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (__is_enum(AUX_WRAPPER_VALUE_TYPE) ? value : value - 1)) ) prior; + #else + typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next; + typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior; diff --git a/building/macOS/CMakeLists.txt b/building/macOS/CMakeLists.txt index 12ef7ce3..00085e2f 100644 --- a/building/macOS/CMakeLists.txt +++ b/building/macOS/CMakeLists.txt @@ -12,6 +12,20 @@ project(openmoonray_third_party) include(ExternalProject) cmake_policy(SET CMP0135 NEW) +# Allow the pinned (older) dependencies to configure under CMake 4.x, which +# rejects cmake_minimum_required < 3.5 and hides legacy find modules +# (FindBoost, FindPythonInterp/Libs) behind policies. Passed to every +# CMake-based ExternalProject below; empty (no-op) under CMake 3.x. +# Note: a set(ENV{...}) here would NOT work — ExternalProject configure steps +# run at build time in separate processes. +if(CMAKE_VERSION VERSION_GREATER_EQUAL 4.0) + set(POLICY_MIN -DCMAKE_POLICY_VERSION_MINIMUM=3.5) + # For deps that run NESTED ExternalProjects at build time (OpenColorIO + # builds its own yaml-cpp/pystring), the cache arg above cannot reach the + # inner configure; CMake >= 4 also honors this as an environment variable. + set(POLICY_MIN_ENV CMAKE_POLICY_VERSION_MINIMUM=3.5) +endif() + include(ProcessorCount) ProcessorCount(N) if(NOT N EQUAL 0) @@ -26,24 +40,34 @@ set(InstallRoot ${rootSrcDir}/../../../../installs CACHE FILEPATH "Install root set(PythonVer 3.9.6 CACHE STRING "Python version (n.m), e.g. 3.6") set(PythonRoot /usr CACHE FILEPATH "Location of Python install") +# Arguments shared by every CMake-based dependency: policy floor for CMake 4, +# find dependencies only in ${InstallRoot}, never in homebrew, and install +# into ${InstallRoot}. +set(COMMON_CMAKE_ARGS + ${POLICY_MIN} + -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} + -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew + -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} +) + ExternalProject_Add(Blosc GIT_REPOSITORY https://github.com/Blosc/c-blosc GIT_TAG 616f4b7 # 1.21.6 # macOS 26 Tahoe BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} + ${COMMON_CMAKE_ARGS} ) set(CHAIN Blosc) ExternalProject_Add(Boost - URL https://sourceforge.net/projects/boost/files/boost/1.78.0/boost_1_78_0.tar.gz - UPDATE_COMMAND ./bootstrap.sh --prefix=${InstallRoot} --with-toolset=clang linkflags="-arch ${BOOST_ARCH}" + URL https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.gz + https://downloads.sourceforge.net/project/boost/boost/1.78.0/boost_1_78_0.tar.gz + URL_HASH SHA256=94ced8b72956591c4775ae2207a9763d3600b30d9d7446562c552f0a14a63be7 + UPDATE_COMMAND ./bootstrap.sh --prefix=${InstallRoot} --with-libraries=python,filesystem,system,thread,regex,date_time,chrono,program_options,iostreams --with-toolset=clang linkflags="-arch ${BOOST_ARCH}" CONFIGURE_COMMAND "" - PATCH_COMMAND patch -p3 -N < ${THIS_DIR}/Boost.patch - BUILD_COMMAND ./b2 install ${JOBS_ARG} --user-config=${THIS_DIR}/user-config.jam --with_python variant=release link=shared threading=multi define=BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT=0 + PATCH_COMMAND patch -p3 -N < ${THIS_DIR}/Boost.patch || true + BUILD_COMMAND ./b2 install ${JOBS_ARG} --user-config=${THIS_DIR}/user-config.jam variant=release link=shared threading=multi define=BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT=0 BUILD_IN_SOURCE 1 INSTALL_COMMAND "" DEPENDS ${CHAIN} @@ -53,12 +77,8 @@ set(CHAIN Boost) ExternalProject_Add(JsonCpp GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp.git GIT_TAG 5defb4ed1a4293b8e2bf641e16b156fb9de498cc # 1.9.5 - INSTALL_DIR ${InstallRoot} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH= + ${COMMON_CMAKE_ARGS} -DJSONCPP_LIB_BUILD_SHARED:BOOL=ON DEPENDS ${CHAIN} ) @@ -66,6 +86,7 @@ set(CHAIN JsonCpp) ExternalProject_Add(Lua URL https://www.lua.org/ftp/lua-5.4.4.tar.gz + URL_HASH SHA256=164c7849653b80ae67bec4b7473b884bf5cc8d2dca05653475ec2ed27b9ebf61 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" BUILD_COMMAND make ${JOBS_ARG} generic MYCFLAGS=-fPIC MYLIBS=-ldl @@ -78,7 +99,11 @@ set(CHAIN Lua) ExternalProject_Add(MicroHttpd URL https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.72.tar.gz + https://mirrors.kernel.org/gnu/libmicrohttpd/libmicrohttpd-0.9.72.tar.gz + URL_HASH SHA256=0ae825f8e0d7f41201fd44a0df1cf454c1cb0bc50fe9d59c26552260264c2ff8 BUILD_IN_SOURCE 1 + # prevent make from regenerating autotools files (requires automake), as for CppUnit below + PATCH_COMMAND bash -c "touch aclocal.m4 && find . -name '*.in' -exec touch {} + && touch configure" CONFIGURE_COMMAND ./configure --prefix ${InstallRoot} BUILD_COMMAND make ${JOBS_ARG} DEPENDS ${CHAIN} @@ -90,10 +115,7 @@ ExternalProject_Add(OpenSubdiv GIT_TAG 8ffa2b6566be10209529d7a0d1db02a0796b160c # v3_5_0 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} + ${COMMON_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=Release -DNO_PTEX=1 -DNO_OMP=1 -DNO_TBB=1 -DNO_CUDA=1 -DNO_GLFW_X11=1 -DNO_OPENCL=1 -DNO_CLEW=1 -DNO_REGRESSION=1 -DNO_EXAMPLES=1 -DNO_TUTORIALS=1 @@ -107,11 +129,8 @@ ExternalProject_Add(OpenEXR PATCH_COMMAND patch IlmBase/Half/CMakeLists.txt ${THIS_DIR}/../Imath_include_paths.patch BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -DBoost_ROOT=${InstallRoot} - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} -DBUILD_SHARED_LIBS=OFF DEPENDS ${CHAIN} ) @@ -119,6 +138,7 @@ set(CHAIN OpenEXR) ExternalProject_Add(TBB URL https://github.com/oneapi-src/oneTBB/archive/2020_U3.tar.gz + URL_HASH SHA256=2103cc6238c935664f87680618f6684d57501d4a2fa8ea8f6c97ad6ff7dc722a BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" BUILD_COMMAND make ${JOBS_ARG} arch=arm64 @@ -134,13 +154,10 @@ ExternalProject_Add(OpenVDB PATCH_COMMAND patch -p1 -N < ${THIS_DIR}/OpenVDB.patch || true BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -DBlosc_ROOT=${InstallRoot} -DBoost_ROOT=${InstallRoot} -DTBB_ROOT=${InstallRoot} - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} DEPENDS ${CHAIN} ) set(CHAIN OpenVDB) @@ -149,6 +166,8 @@ ExternalProject_Add(Log4CPlus GIT_REPOSITORY https://github.com/log4cplus/log4cplus GIT_TAG REL_2_0_5 PATCH_COMMAND patch -p1 -N < ${THIS_DIR}/log4plus-limit-threads.patch || true + # prevent make from regenerating autotools files (requires automake), as for CppUnit below + COMMAND bash -c "touch aclocal.m4 && find . -name '*.in' -exec touch {} + && touch configure tests/testsuite" BUILD_IN_SOURCE 1 CONFIGURE_COMMAND ./configure --prefix ${InstallRoot} BUILD_COMMAND make @@ -158,7 +177,8 @@ ExternalProject_Add(Log4CPlus set(CHAIN Log4CPlus) ExternalProject_Add(CppUnit - URL http://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz + URL https://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz + URL_HASH SHA256=89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7 BUILD_IN_SOURCE 1 PATCH_COMMAND find . -name "Makefile.in" -exec touch {} + # prevent make from thinking these files are stale CONFIGURE_COMMAND ./configure --prefix ${InstallRoot} @@ -181,6 +201,7 @@ set(CHAIN Random123) ExternalProject_Add(ISPC URL https://github.com/ispc/ispc/releases/download/v1.20.0/ispc-v1.20.0-macOS.arm64.tar.gz + URL_HASH SHA256=c423a5a88d7a9a6ed667e41d025801c123fa0c5fd384d4ea138fa1fcf2bc24c9 BUILD_IN_SOURCE 1 CONFIGURE_COMMAND "" BUILD_COMMAND "" @@ -196,10 +217,7 @@ ExternalProject_Add(embree BUILD_IN_SOURCE 1 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} + ${COMMON_CMAKE_ARGS} -DEMBREE_ISPC_EXECUTABLE=${InstallRoot}/bin/ispc -DEMBREE_ISPC_SUPPORT=ON -DEMBREE_TBB_ROOT=${InstallRoot} @@ -216,18 +234,15 @@ set(CHAIN embree) ExternalProject_Add(OpenColorIO GIT_REPOSITORY https://github.com/AcademySoftwareFoundation/OpenColorIO GIT_TAG 056b7b0cb0d087961e9dba75104820e44faf52a1 # v2.0.2 - BUILD_COMMAND make ${JOBS_ARG} + BUILD_COMMAND ${CMAKE_COMMAND} -E env ${POLICY_MIN_ENV} make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -Dyaml-cpp_ROOT=${InstallRoot} -DOCIO_BUILD_APPS=OFF -DOCIO_BUILD_TESTS=OFF -DOCIO_BUILD_GPU_TESTS=OFF -DOCIO_USE_SSE=OFF -DOCIO_BUILD_PYTHON=OFF - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} -DBUILD_SHARED_LIBS=ON -DOCIO_BUILD_STATIC=OFF -DCMAKE_CXX_STANDARD=17 @@ -237,13 +252,11 @@ set(CHAIN OpenColorIO) ExternalProject_Add(TIFF URL https://gitlab.com/libtiff/libtiff/-/archive/v4.0.7/libtiff-v4.0.7.tar.gz + URL_HASH SHA256=67c79057aa42ed8f48ae42dd1db60d56773d45cd7c8ec4c30857031adcd9ed2c BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -Dld-version-script=OFF - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} DEPENDS ${CHAIN} ) set(CHAIN TIFF) @@ -253,11 +266,8 @@ ExternalProject_Add(JPEGTurbo GIT_TAG bb3d325624526c91646bb9af9578d7198c082d51 # 2.0.1 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -DWITH_SIMD=FALSE - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} DEPENDS ${CHAIN} ) set(CHAIN JPEGTurbo) @@ -267,6 +277,7 @@ ExternalProject_Add(pybind11 GIT_TAG a2e59f0e7065404b44dfe92a28aca47ba1378dc4 # v2.13.6 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS + ${POLICY_MIN} -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} -DPYBIND11_TEST=NO DEPENDS ${CHAIN} @@ -278,23 +289,22 @@ ExternalProject_Add(OpenImageIO GIT_TAG 331a323468928c8017ad048b26d47c4e57a724a7 # 2.3.20.0 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew + ${COMMON_CMAKE_ARGS} -DBoost_ROOT=${InstallRoot} -DIMath_ROOT=${InstallRoot} -DDISABLE_CMAKE_SEARCH_PATHS=TRUE -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=TRUE -DOpenEXR_ROOT=${InstallRoot} - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} -DUSE_QT=0 -DUSE_PYTHON=1 + -DPython_EXECUTABLE=/usr/bin/python3 DEPENDS ${CHAIN} ) set(CHAIN OpenImageIO) ExternalProject_Add(OpenImageDenoise URL https://github.com/OpenImageDenoise/oidn/releases/download/v2.2.0/oidn-2.2.0.arm64.macos.tar.gz + URL_HASH SHA256=16cdaddabeb0f2af22fc8e466317c1a14a54b6ec03db2ac343e17fad40c70f3f BUILD_COMMAND "" CONFIGURE_COMMAND "" INSTALL_COMMAND bash -c "rm -f ../OpenImageDenoise/lib/libtbb.dylib" @@ -325,16 +335,13 @@ if(NOT NO_USD) PATCH_COMMAND pwd && patch -Ni ${THIS_DIR}/USD.patch || true BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} + ${COMMON_CMAKE_ARGS} -DPXR_ENABLE_PYTHON_SUPPORT=ON -DPXR_USE_PYTHON_3=ON -DPXR_USE_DEBUG_PYTHON=OFF - -DPYTHON_EXECUTABLE=/usr/bin/python3 - -DPYTHON_LIBRARY=/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/libpython3.9.dylib - -DPYTHON_INCLUDE_DIR=/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/Headers + -DPYTHON_EXECUTABLE=/Library/Developer/CommandLineTools/usr/bin/python3 + -DPYTHON_LIBRARY=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib/libpython3.9.dylib + -DPYTHON_INCLUDE_DIR=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Headers -DPYTHON_VERSION_MAJOR=3 -DPYTHON_VERSION_MINOR=9 -DTBB_USE_DEBUG_BUILD=OFF @@ -354,7 +361,11 @@ if(NOT NO_USD) endif() ExternalProject_Add(libuuid - URL https://sourceforge.net/projects/libuuid/files/libuuid-1.0.3.tar.gz/download + URL https://downloads.sourceforge.net/project/libuuid/libuuid-1.0.3.tar.gz + https://sourceforge.net/projects/libuuid/files/libuuid-1.0.3.tar.gz/download + URL_HASH SHA256=46af3275291091009ad7f1b899de3d0cea0252737550e7919d17237997db5644 + # prevent make from regenerating autotools files (requires automake), as for CppUnit above + PATCH_COMMAND bash -c "touch aclocal.m4 && find . -name '*.in' -exec touch {} + && touch configure" CONFIGURE_COMMAND ./configure --prefix=${InstallRoot} BUILD_COMMAND make ${JOBS_ARG} BUILD_IN_SOURCE 1 @@ -380,6 +391,10 @@ set(CHAIN OpenSSL) ExternalProject_Add(libcurl URL https://curl.se/download/curl-7.88.1.tar.gz + https://github.com/curl/curl/releases/download/curl-7_88_1/curl-7.88.1.tar.gz + URL_HASH SHA256=cdb38b72e36bc5d33d5b8810f8018ece1baa29a8f215b4495e495ded82bbf3c7 + # prevent make from regenerating autotools files (requires automake), as for CppUnit above + PATCH_COMMAND bash -c "touch aclocal.m4 && find . -name '*.in' -exec touch {} + && touch configure" CONFIGURE_COMMAND ./configure --prefix=${InstallRoot} --with-secure-transport BUILD_COMMAND make ${JOBS_ARG} BUILD_IN_SOURCE 1 @@ -391,15 +406,14 @@ set(CHAIN libcurl) ExternalProject_Add(FreeType URL https://download.savannah.gnu.org/releases/freetype/freetype-2.13.2.tar.gz + https://downloads.sourceforge.net/project/freetype/freetype2/2.13.2/freetype-2.13.2.tar.gz + URL_HASH SHA256=1ac27e16c134a7f2ccea177faba19801131116fd682efc1f5737037c5db224b5 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} - -D FT_REQUIRE_ZLIB=FALSE - -D FT_REQUIRE_BZIP2=FALSE - -D BUILD_SHARED_LIBS=true + ${COMMON_CMAKE_ARGS} + -DFT_REQUIRE_ZLIB=FALSE + -DFT_REQUIRE_BZIP2=FALSE + -DBUILD_SHARED_LIBS=true DEPENDS ${CHAIN} ) set(CHAIN FreeType) @@ -409,10 +423,7 @@ ExternalProject_Add(GLFW GIT_TAG 3.4 BUILD_COMMAND make ${JOBS_ARG} CMAKE_ARGS - -DCMAKE_PREFIX_PATH:PATH=${InstallRoot} - -DCMAKE_IGNORE_PATH:PATH=/opt/homebrew - -DCMAKE_IGNORE_PREFIX_PATH:PATH=/opt/homebrew - -DCMAKE_INSTALL_PREFIX:PATH=${InstallRoot} + ${COMMON_CMAKE_ARGS} -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF diff --git a/building/macOS/macOS_build.md b/building/macOS/macOS_build.md index 605a8eb0..e1d0147b 100644 --- a/building/macOS/macOS_build.md +++ b/building/macOS/macOS_build.md @@ -5,11 +5,14 @@ Start with reading the [general build instructions](../general_build). --- ## Base Requirements - Apple M-series hardware -- macOS 14.6 Sonoma / Xcode 15.4 -- macOS 15.6 Sequoia / Xcode 16.4 -- macOS 26.0.Tahoe / Xcode 26.0 + - macOS 14.6 Sonoma / Xcode 15.4 + - macOS 15.6 Sequoia / Xcode 16.4 + - macOS 26.0.Tahoe / Xcode 26.0 + - macOS 26.5 Tahoe / Xcode 26.6 +- 17+ GB Disk Space - Install Xcode -- Tahoe requires an additional component: xcodebuild -downloadComponent MetalToolchain +- Tahoe requires an additional component: `xcodebuild -downloadComponent MetalToolchain` +- `/usr/bin/python3` must be the internal macOS Python 3.9 shim (this is default with an Xcode install) - Git and [Git LFS](https://git-lfs.com/) - Download and install CMake 3.26.5 (or greater): https://github.com/Kitware/CMake/releases/download/v3.26.5/cmake-3.26.5-macos-universal.dmg diff --git a/building/macOS/user-config.jam b/building/macOS/user-config.jam index f163655e..dd729f78 100644 --- a/building/macOS/user-config.jam +++ b/building/macOS/user-config.jam @@ -1,6 +1,6 @@ using python : 3.9 - : "/usr/bin/python3" - : "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/Headers" - : "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib" + : "/Library/Developer/CommandLineTools/usr/bin/python3" + : "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/Headers" + : "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.9/lib" ; using clang : : : -"arch arm64" "-arch arm64" ; diff --git a/cmake_modules b/cmake_modules index 6e4c94b4..1b1b7af8 160000 --- a/cmake_modules +++ b/cmake_modules @@ -1 +1 @@ -Subproject commit 6e4c94b4d1376962f631284378ea859e66199e1b +Subproject commit 1b1b7af8111b0a8ceaff45f3c47a778b0ca07ec4 From bc1d489654e82fadb0c1420fd2a259dfd3f9dbb7 Mon Sep 17 00:00:00 2001 From: Nick Shelton Date: Fri, 14 Aug 2026 17:21:12 -0700 Subject: [PATCH 2/4] houdini 20 houdini-usd fix Signed-off-by: Nick Shelton --- CMakeMacOSPresets.json | 1 + .../pxr/usd/sdf/childrenProxy.h | 475 ++++++++++++++++++ 2 files changed, 476 insertions(+) create mode 100644 building/macOS/houdini-usd-fixes/pxr/usd/sdf/childrenProxy.h diff --git a/CMakeMacOSPresets.json b/CMakeMacOSPresets.json index 3d5d6e71..0524fa1f 100644 --- a/CMakeMacOSPresets.json +++ b/CMakeMacOSPresets.json @@ -26,6 +26,7 @@ }, "cacheVariables": { "CMAKE_PREFIX_PATH": "$env{DEPS_ROOT}", + "CMAKE_CXX_FLAGS": "-D_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION -I${sourceParentDir}/building/macOS/houdini-usd-fixes", "CMAKE_IGNORE_PATH": "/opt/homebrew", "CMAKE_IGNORE_PREFIX_PATH": "/opt/homebrew", "CMAKE_POLICY_VERSION_MINIMUM": "3.5", diff --git a/building/macOS/houdini-usd-fixes/pxr/usd/sdf/childrenProxy.h b/building/macOS/houdini-usd-fixes/pxr/usd/sdf/childrenProxy.h new file mode 100644 index 00000000..1d3ef5f5 --- /dev/null +++ b/building/macOS/houdini-usd-fixes/pxr/usd/sdf/childrenProxy.h @@ -0,0 +1,475 @@ +// +// Copyright 2016 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. +// +#ifndef PXR_USD_SDF_CHILDREN_PROXY_H +#define PXR_USD_SDF_CHILDREN_PROXY_H + +/// \file sdf/childrenProxy.h + +#include "pxr/pxr.h" +#include "pxr/usd/sdf/api.h" +#include "pxr/usd/sdf/changeBlock.h" +#include "pxr/base/vt/value.h" +#include "pxr/base/tf/diagnostic.h" +#include "pxr/base/tf/iterator.h" + +#include +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +template +class SdfChildrenProxy { +public: + typedef _View View; + typedef typename View::Adapter Adapter; + typedef typename View::ChildPolicy ChildPolicy; + typedef typename View::key_type key_type; + typedef typename View::value_type mapped_type; + typedef std::vector mapped_vector_type; + typedef std::pair value_type; + typedef std::map map_type; + typedef typename View::size_type size_type; + typedef SdfChildrenProxy This; + +private: + typedef typename View::const_iterator _inner_iterator; + + class _ValueProxy { + public: + _ValueProxy() : _owner(NULL) { } + _ValueProxy(This* owner, _inner_iterator i) : _owner(owner), _pos(i) + { + // Do nothing + } + + operator mapped_type() const + { + return *_pos; + } + + bool operator==(const mapped_type& other) const + { + return *_pos == other; + } + + private: + This* _owner; + _inner_iterator _pos; + }; + + class _PairProxy { + public: + explicit _PairProxy(This* owner, _inner_iterator i) : + first(owner->_view.key(i)), second(owner, i) { } + + const key_type first; + _ValueProxy second; + + operator value_type() const + { + return value_type(first, second); + } + }; + friend class _PairProxy; + + class _Traits { + public: + static value_type Dereference(const This* owner, _inner_iterator i) + { + return value_type(owner->_view.key(i), *i); + } + + static _PairProxy Dereference(This* owner, _inner_iterator i) + { + return _PairProxy(owner, i); + } + }; + + template + class _Iterator : + public hboost::iterator_facade< + _Iterator<_Owner, _Iter, _Value>, + _Value, + std::bidirectional_iterator_tag, + _Value> { + public: + _Iterator() { } + _Iterator(_Owner owner, _inner_iterator i) : _owner(owner), _pos(i) { } + template + _Iterator(const _Iterator& other) : + _owner(other._owner), _pos(other._pos) { } + + private: + friend class hboost::iterator_core_access; + + _Value dereference() const + { + return _Traits::Dereference(_owner, _pos); + } + + template + bool equal(const _Iterator& other) const + { + return _pos == other._pos; + } + + void increment() { + ++_pos; + } + + void decrement() { + --_pos; + } + + private: + _Owner _owner; + _inner_iterator _pos; + + template + friend class _Iterator; + }; + +public: + typedef _ValueProxy reference; + typedef _Iterator iterator; + typedef hboost::reverse_iterator reverse_iterator; + typedef _Iterator const_iterator; + typedef hboost::reverse_iterator const_reverse_iterator; + + static const int CanSet = 1; + static const int CanInsert = 2; + static const int CanErase = 4; + + SdfChildrenProxy(const View& view, const std::string& type, + int permission = CanSet | CanInsert | CanErase) : + _view(view), _type(type), _permission(permission) + { + // Do nothing + } + + template + SdfChildrenProxy(const SdfChildrenProxy& other) : + _view(other._view), _type(other._type), _permission(other._permission) + { + // Do nothing + } + + This& operator=(const This& other) + { + if (other._Validate()) { + _Copy(other._view.values()); + } + return *this; + } + + template + This& operator=(const SdfChildrenProxy& other) + { + if (other._Validate()) { + _Copy(other._view.values()); + } + return *this; + } + + This& operator=(const mapped_vector_type& values) + { + _Copy(values); + return *this; + } + + operator mapped_vector_type() const + { + return _Validate() ? _view.values() : mapped_vector_type(); + } + + map_type items() const + { + return _Validate() ? _view.template items_as() :map_type(); + } + + iterator begin() + { + return iterator(_GetThis(), _view.begin()); + } + iterator end() + { + return iterator(_GetThis(), _view.end()); + } + const_iterator begin() const + { + return const_iterator(_GetThis(), _view.begin()); + } + const_iterator end() const + { + return const_iterator(_GetThis(), _view.end()); + } + + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + const_reverse_iterator rbegin() const + { + return reverse_iterator(end()); + } + const_reverse_iterator rend() const + { + return reverse_iterator(begin()); + } + + size_type size() const + { + return _Validate() ? _view.size() : 0; + } + + size_type max_size() const + { + return _view.max_size(); + } + + bool empty() const + { + return _Validate() ? _view.empty() : true; + } + + std::pair insert(const mapped_type& value) + { + if (_Validate(CanInsert)) { + iterator i = find(_view.key(value)); + if (i == end()) { + if (_PrimInsert(value, size())) { + return std::make_pair(find(_view.key(value)), true); + } + else { + return std::make_pair(end(), false); + } + } + else { + return std::make_pair(i, false); + } + } + else { + return std::make_pair(iterator(), false); + } + } + + iterator insert(iterator pos, const mapped_type& value) + { + return insert(value).first; + } + + template + void insert(InputIterator first, InputIterator last) + { + if (_Validate(CanInsert)) { + SdfChangeBlock block; + for (; first != last; ++first) { + _PrimInsert(*first, size()); + } + } + } + + void erase(iterator pos) + { + _Erase(pos->first); + } + + size_type erase(const key_type& key) + { + return _Erase(key) ? 1 : 0; + } + + void erase(iterator first, iterator last) + { + if (_Validate(CanErase)) { + SdfChangeBlock block; + while (first != last) { + const key_type& key = first->first; + ++first; + _PrimErase(key); + } + } + } + + void clear() + { + _Copy(mapped_vector_type()); + } + + iterator find(const key_type& key) + { + return _Validate() ? iterator(this, _view.find(key)) : iterator(); + } + + const_iterator find(const key_type& key) const + { + return _Validate() ? const_iterator(this, _view.find(key)) : + const_iterator(); + } + + size_type count(const key_type& key) const + { + return _Validate() ? _view.count(key) : 0; + } + + bool operator==(const This& other) const + { + return _view == other._view; + } + + bool operator!=(const This& other) const + { + return !(*this == other); + } + + /// Explicit bool conversion operator. The proxy object converts to + /// \c true if it is valid, \c false otherwise. + explicit operator bool() const + { + return _view.IsValid(); + } + +private: + const std::string& _GetType() const + { + return _type; + } + + int _GetPermission() const + { + return _permission; + } + + This* _GetThis() + { + return _Validate() ? this : NULL; + } + + const This* _GetThis() const + { + return _Validate() ? this : NULL; + } + + bool _Validate() const + { + if (_view.IsValid()) { + return true; + } + else { + TF_CODING_ERROR("Accessing expired %s", _type.c_str()); + return false; + } + } + + bool _Validate(int permission) + { + if (!_Validate()) { + return false; + } + if ((_permission & permission) == permission) { + return true; + } + const char* op = "edit"; + if (~_permission & permission & CanSet) { + op = "replace"; + } + else if (~_permission & permission & CanInsert) { + op = "insert"; + } + else if (~_permission & permission & CanErase) { + op = "remove"; + } + TF_CODING_ERROR("Cannot %s %s", op, _type.c_str()); + return false; + } + + bool _Copy(const mapped_vector_type& values) + { + return _Validate(CanSet) ? _PrimCopy(values) : false; + } + + bool _Insert(const mapped_type& value, size_t index) + { + return _Validate(CanInsert) ? _PrimInsert(value, index) : false; + } + + bool _Erase(const key_type& key) + { + return _Validate(CanErase) ? _PrimErase(key) : false; + } + + bool _PrimCopy(const mapped_vector_type& values) + { + typedef std::vector + ChildrenValueVector; + + ChildrenValueVector v; + for (size_t i = 0; i < values.size(); ++i) + v.push_back(Adapter::Convert(values[i])); + + return _view.GetChildren().Copy(v, _type); + } + + bool _PrimInsert(const mapped_type& value, size_t index) + { + return _view.GetChildren().Insert( + Adapter::Convert(value), index, _type); + } + + bool _PrimErase(const key_type& key) + { + return _view.GetChildren().Erase(key, _type); + } + +private: + View _view; + std::string _type; + int _permission; + + template friend class SdfChildrenProxy; + template friend class SdfPyChildrenProxy; +}; + +// Allow TfIteration over children proxies. +template +struct Tf_ShouldIterateOverCopy > : std::true_type +{ +}; + +// Cannot get from a VtValue except as the correct type. +template +struct Vt_DefaultValueFactory > { + static Vt_DefaultValueHolder Invoke() = delete; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif // PXR_USD_SDF_CHILDREN_PROXY_H From 0f74cc1ef750be93790c86e9efc86b3300cad7cc Mon Sep 17 00:00:00 2001 From: Nick Shelton Date: Mon, 17 Aug 2026 16:05:46 -0700 Subject: [PATCH 3/4] improve setup scripts Signed-off-by: Nick Shelton --- building/macOS/macOS_build.md | 4 +++- scripts/macOS/setupHoudini.sh | 12 +++++++++--- scripts/setup.sh | 6 ++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/building/macOS/macOS_build.md b/building/macOS/macOS_build.md index e1d0147b..dc1c92c5 100644 --- a/building/macOS/macOS_build.md +++ b/building/macOS/macOS_build.md @@ -48,6 +48,8 @@ Note: If building for Houdini, you'll potentially need to make the following cha * Edit source/openmoonray/scripts/macOS/setupHoudini.sh to update HOUDINI_PATH * Edit source/openmoonray/building/macOS/pxr-houdini/pxrTargets.cmake to update HPYTHONLIB and HPYTHONINC if needed +Houdini 20 is officially supported. + --- ### Step 4. Build the dependencies Note: If building for Houdini you'll need to build moonray against Houdini's USD libraries. @@ -82,7 +84,7 @@ moonray_gui -exec_mode xpu -info -in curves.rdla HOUDINI: Open "Houdini Terminal" in Applications and run: ```bash -source /Applications/MoonRay/openmoonray/scripts/macOS/setupHoudini.sh +source /Applications/MoonRay/installs/openmoonray/scripts/macOS/setupHoudini.sh houdini ``` diff --git a/scripts/macOS/setupHoudini.sh b/scripts/macOS/setupHoudini.sh index 68ac25fb..6bfc563d 100644 --- a/scripts/macOS/setupHoudini.sh +++ b/scripts/macOS/setupHoudini.sh @@ -9,6 +9,12 @@ export REL=${omr_install_dir} export RDL2_DSO_PATH=${omr_install_dir}/rdl2dso.proxy:${omr_install_dir}/rdl2dso export MOONRAY_CLASS_PATH=${omr_install_dir}/shader_json export ARRAS_SESSION_PATH=${omr_install_dir}/sessions -PXR_PLUGINPATH_NAME=${omr_install_dir}/plugin/pxr -#export HOUDINI_DSO_ERROR=5 -export HOUDINI_PATH=/Applications/Houdini/Houdini20.0.751/Frameworks/Houdini.framework/Versions/Current/Resources/houdini:${omr_install_dir}/houdini/:${omr_install_dir}/plugin/houdini +export PXR_PLUGINPATH_NAME=${omr_install_dir}/plugin/pxr + +# debugging options for Houdini if you are having trouble loading the Moonray plugin +# export HOUDINI_DSO_ERROR=4 +# export HOUDINI_OTL_DEBUG=1 +# export HOUDINI_PACKAGE_VERBOSE=1 + +export HOUDINI_OTLSCAN_PATH="${omr_install_dir}/plugin/houdini/otls:&" +export HOUDINI_PATH="${omr_install_dir}/houdini/:${omr_install_dir}/plugin/houdini:&" \ No newline at end of file diff --git a/scripts/setup.sh b/scripts/setup.sh index 999594db..ced7d68c 100644 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -11,6 +11,12 @@ install_root=${omr_root} while [ "$(basename ${install_root})" != "installs" ] do install_root=$(dirname ${install_root}) + + if [ "${install_root}" == "/" ] + then + echo "Could not find install root. Be sure you are running this script from the installed location." + exit 1 + fi done echo "Found install root at ${install_root}" From b6a19944805796f7f3b0582906f699b6fb159a88 Mon Sep 17 00:00:00 2001 From: Nick Shelton Date: Mon, 17 Aug 2026 17:29:16 -0700 Subject: [PATCH 4/4] update submodule Signed-off-by: Nick Shelton --- moonray/scene_rdl2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/moonray/scene_rdl2 b/moonray/scene_rdl2 index d3da0349..1229d3ea 160000 --- a/moonray/scene_rdl2 +++ b/moonray/scene_rdl2 @@ -1 +1 @@ -Subproject commit d3da03498c261993b50dc2a084f5931b7bfc17dd +Subproject commit 1229d3eaa1ee41dc1ddefbe781c623edceafbac8