From 36beb9bf4e1bfc20fca56c5753825e87759717f2 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Sun, 12 Jul 2026 13:49:44 -0400 Subject: [PATCH 1/9] build(cmake): guard libtiff's missing Deflate target Static libtiff package exports can reference Deflate::Deflate without importing the target. Quietly load libdeflate's config and supply the alias before TIFF discovery when needed. Fixes #4439 Assisted-by: Codex / GPT-5 Signed-off-by: Zach Lewis --- src/cmake/externalpackages.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 107b8ad255..02f215b871 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -90,6 +90,14 @@ endif () checked_find_package (libuhdr VERSION_MIN 1.3) +# Static libtiff configs may reference this target without importing it. +# https://github.com/AcademySoftwareFoundation/OpenImageIO/issues/4439 +if (NOT TARGET Deflate::Deflate) + find_package (libdeflate CONFIG QUIET) + alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_static) + alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_shared) +endif () + checked_find_package (TIFF REQUIRED VERSION_MIN 4.0 RECOMMEND_MIN 4.5 From 9bdcdfeb46ef2a9f515724c7bd52e38799306927 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Sun, 12 Jul 2026 15:41:00 -0400 Subject: [PATCH 2/9] build(cmake): link libtiff workaround upstream Reference the upstream libtiff report from the defensive target guard. Assisted-by: Codex / GPT-5 Signed-off-by: Zach Lewis --- src/cmake/externalpackages.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 02f215b871..46db62798c 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -91,7 +91,7 @@ checked_find_package (libuhdr VERSION_MIN 1.3) # Static libtiff configs may reference this target without importing it. -# https://github.com/AcademySoftwareFoundation/OpenImageIO/issues/4439 +# https://gitlab.com/libtiff/libtiff/-/work_items/871 if (NOT TARGET Deflate::Deflate) find_package (libdeflate CONFIG QUIET) alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_static) From 5b9af7c7de6be1fc49fe46f8365cf71158d7debe Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Sun, 12 Jul 2026 16:29:36 -0400 Subject: [PATCH 3/9] build(cmake): guard static OIIO consumers Define libtiff's missing Deflate target before the installed static OpenImageIO package resolves its TIFF dependency. Assisted-by: Codex / GPT-5 Signed-off-by: Zach Lewis --- src/cmake/Config.cmake.in | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/cmake/Config.cmake.in b/src/cmake/Config.cmake.in index 080a499968..94e1924a6d 100644 --- a/src/cmake/Config.cmake.in +++ b/src/cmake/Config.cmake.in @@ -20,6 +20,16 @@ if (NOT @BUILD_SHARED_LIBS@) # This is required in static library builds, as e.g. PNG::PNG appears among # INTERFACE_LINK_LIBRARIES. If the project does not know about PNG target, it will cause # configuration error about unknown targets being linked in. + # Static libtiff configs may reference this target without importing it. + # https://gitlab.com/libtiff/libtiff/-/work_items/871 + if (NOT TARGET Deflate::Deflate) + find_package (libdeflate CONFIG QUIET) + if (TARGET libdeflate::libdeflate_static) + add_library (Deflate::Deflate ALIAS libdeflate::libdeflate_static) + elseif (TARGET libdeflate::libdeflate_shared) + add_library (Deflate::Deflate ALIAS libdeflate::libdeflate_shared) + endif () + endif () find_dependency(TIFF) find_dependency(OpenColorIO) if (@JPEG_FOUND@) From a5991f47f8a2809dd529b4f7197a17db853d15b6 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Mon, 3 Aug 2026 15:52:42 -0400 Subject: [PATCH 4/9] build(cmake): use checked_find_package for deflate guard Route the pre-TIFF libdeflate guard through checked_find_package so it appears in the dependency report and can use the local auto-builders, rather than a bare find_package. Also document why the guard must precede TIFF discovery: since CMake 3.29, FindTIFF probes the config package first, so a previously auto-built static libtiff rediscovered from the local deps cache is loaded after build_TIFF.cmake (which formerly supplied the Deflate::Deflate alias) has been skipped. Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis --- src/cmake/externalpackages.cmake | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 46db62798c..6fe1a891b1 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -90,10 +90,14 @@ endif () checked_find_package (libuhdr VERSION_MIN 1.3) -# Static libtiff configs may reference this target without importing it. -# https://gitlab.com/libtiff/libtiff/-/work_items/871 +# Static libtiff configs may reference Deflate::Deflate without importing it +# (https://gitlab.com/libtiff/libtiff/-/work_items/871), so libdeflate must be +# located before TIFF discovery. In particular, a previously auto-built static +# TIFF rediscovered from the local deps cache needs this; the libdeflate found +# during build_TIFF.cmake does not carry over to later reconfigures. if (NOT TARGET Deflate::Deflate) - find_package (libdeflate CONFIG QUIET) + checked_find_package (libdeflate + VERSION_MIN 1.18) alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_static) alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_shared) endif () From 374166827cb621983fa46810e8fe33e6e41b03b7 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Mon, 3 Aug 2026 16:58:20 -0400 Subject: [PATCH 5/9] build(deps): support git submodules in local dependency builds Add a GIT_SUBMODULES argument to build_dependency_with_cmake that initializes the named submodule paths (shallow) after the main checkout. The submodule commits are the gitlinks pinned by the verified superproject commit, so they inherit the existing tag/commit supply-chain verification. Needed for dependencies that vendor required libraries as submodules, such as libjxl (brotli, highway, skcms). Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis --- src/cmake/dependency_utils.cmake | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cmake/dependency_utils.cmake b/src/cmake/dependency_utils.cmake index 879580a46b..3543966b6a 100644 --- a/src/cmake/dependency_utils.cmake +++ b/src/cmake/dependency_utils.cmake @@ -615,7 +615,7 @@ macro (build_dependency_with_cmake pkgname) # singleValueKeywords: "GIT_REPOSITORY;GIT_TAG;GIT_COMMIT;VERSION;SOURCE_SUBDIR;QUIET" # multiValueKeywords: - "CMAKE_ARGS" + "CMAKE_ARGS;GIT_SUBMODULES" # argsToParse: ${ARGN}) @@ -701,6 +701,17 @@ macro (build_dependency_with_cmake pkgname) "${pkgname}: Neither GIT_TAG nor GIT_COMMIT was specified.") endif () + # Initialize any requested submodules (paths relative to the package + # source dir). This runs after the checkout above, so the submodule + # commits are the ones pinned by the verified superproject commit and + # inherit its supply-chain guarantee. + if (NOT "${_pkg_GIT_SUBMODULES}" STREQUAL "") + execute_process(COMMAND ${GIT_EXECUTABLE} submodule update + --init --depth 1 -- ${_pkg_GIT_SUBMODULES} + WORKING_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR} + ${_pkg_exec_quiet}) + endif () + # Configure the package if (${PROJECT_NAME}_DEPENDENCY_BUILD_VERBOSE) set (_pkg_cmake_verbose -DCMAKE_VERBOSE_MAKEFILE=ON From b9d393506a5244f1a6742cc89b8c82e62a561cdd Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Mon, 3 Aug 2026 16:58:21 -0400 Subject: [PATCH 6/9] build(deps): add local build recipe for JPEG XL Add build_JXL.cmake so checked_find_package(JXL) can build libjxl locally via OpenImageIO_BUILD_MISSING_DEPS / _BUILD_LOCAL_DEPS, like the other self-buildable dependencies. libjxl is built shared with its vendored brotli/highway/skcms submodules statically folded in, so the installed libraries are self-contained and match what OIIO's FindJXL module links (jxl and jxl_threads). Tools, tests, docs, and optional integrations are disabled; color management uses the bundled skcms. Verified with hidden system packages: fresh configure builds and re-finds JXL 0.12.0; incremental reconfigures rediscover it from the local deps cache without rebuilding. Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis --- src/cmake/build_JXL.cmake | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/cmake/build_JXL.cmake diff --git a/src/cmake/build_JXL.cmake b/src/cmake/build_JXL.cmake new file mode 100644 index 0000000000..cad55650e1 --- /dev/null +++ b/src/cmake/build_JXL.cmake @@ -0,0 +1,62 @@ +# Copyright Contributors to the OpenImageIO project. +# SPDX-License-Identifier: Apache-2.0 +# https://github.com/AcademySoftwareFoundation/OpenImageIO + +###################################################################### +# JPEG XL (libjxl) by hand! +###################################################################### + +set_cache (JXL_BUILD_VERSION 0.12.0 "libjxl version for local builds") +set (JXL_GIT_REPOSITORY "https://github.com/libjxl/libjxl") +set_cache (JXL_GIT_TAG "v${JXL_BUILD_VERSION}" "Git branch or tag") +set_cache (JXL_GIT_COMMIT "a7a9c787341cf703dede03c2009fa460cae5e5df" + "commit hash to verify tag against") + +# Build libjxl shared: its bundled brotli/highway/skcms are built static +# and folded in, so the installed libraries are self-contained and match +# what OIIO's FindJXL module expects to link (jxl + jxl_threads). +set_cache (JXL_BUILD_SHARED_LIBS ON + DOC "Should a local JXL build, if necessary, build shared libraries" ADVANCED) + +build_dependency_with_cmake(JXL + VERSION ${JXL_BUILD_VERSION} + GIT_REPOSITORY ${JXL_GIT_REPOSITORY} + GIT_TAG ${JXL_GIT_TAG} + GIT_COMMIT ${JXL_GIT_COMMIT} + # libjxl vendors its required dependencies as submodules. Only these + # three are needed for the libraries themselves; skcms doubles as the + # color-management backend so no system lcms2 is required. + GIT_SUBMODULES third_party/brotli third_party/highway third_party/skcms + CMAKE_ARGS + -D BUILD_SHARED_LIBS=${JXL_BUILD_SHARED_LIBS} + -D CMAKE_POSITION_INDEPENDENT_CODE=ON + -D CMAKE_INSTALL_LIBDIR=lib + # Libraries only -- no tools, tests, docs, or bindings. + -D BUILD_TESTING=OFF + -D JPEGXL_ENABLE_TOOLS=OFF + -D JPEGXL_ENABLE_EXAMPLES=OFF + -D JPEGXL_ENABLE_BENCHMARK=OFF + -D JPEGXL_ENABLE_MANPAGES=OFF + -D JPEGXL_ENABLE_DOXYGEN=OFF + -D JPEGXL_ENABLE_JNI=OFF + -D JPEGXL_ENABLE_FUZZERS=OFF + # No optional integrations: OIIO's plugin uses the core codestream + # API only. (Transcoding to/from legacy JPEG and the sjpeg/OpenEXR + # helpers are tool/library features OIIO doesn't touch.) + -D JPEGXL_ENABLE_SJPEG=OFF + -D JPEGXL_ENABLE_OPENEXR=OFF + -D JPEGXL_ENABLE_TRANSCODE_JPEG=OFF + # Color management via the bundled skcms submodule. + -D JPEGXL_ENABLE_SKCMS=ON + ) + +# Set some things up that we'll need for a subsequent find_package to work + +set (JXL_ROOT ${JXL_LOCAL_INSTALL_DIR}) + +# Signal to caller that we need to find again at the installed location +set (JXL_REFIND TRUE) + +if (JXL_BUILD_SHARED_LIBS) + install_local_dependency_libs (JXL jxl) +endif () From 13151208a194d59e4acf605731350a837d27ad9e Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Mon, 3 Aug 2026 17:09:41 -0400 Subject: [PATCH 7/9] build(deps): keep Homebrew out of local dependency child builds IGNORE_HOMEBREWED_DEPS pruned prefix paths and set CMAKE_IGNORE_PATH, but CMAKE_IGNORE_PATH does not stop config-package searches, and local dependency child builds could still quietly resolve Homebrew packages we are ignoring. Concretely: with a Homebrew Imath 3.2 installed, the local OpenEXR build resolved Imath_DIR=/opt/homebrew/lib/cmake/Imath while OpenImageIO itself used the locally built Imath 3.1.10, and libOpenImageIO then failed to link with Imath_3_2 vs Imath_3_1 namespace-mangled symbol mismatches. Set CMAKE_IGNORE_PREFIX_PATH for the Homebrew prefixes (honored by config searches) and forward it to dependency child builds alongside CMAKE_IGNORE_PATH. Verified: the OpenEXR child build resolves the local deps Imath and libOpenImageIO links clean. Assisted-by: Claude Code (Fable 5) Signed-off-by: Zach Lewis --- CMakeLists.txt | 6 ++++++ src/cmake/dependency_utils.cmake | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2586106b69..1d7471e87f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -223,6 +223,12 @@ if (IGNORE_HOMEBREWED_DEPS) ) endforeach () + # Also ignore the whole prefixes, which (unlike CMAKE_IGNORE_PATH) is + # honored by config-package searches, and is forwarded to local + # dependency child builds so they can't quietly resolve a Homebrew + # package (e.g. a mismatched Imath) that we ourselves are ignoring. + list (APPEND CMAKE_IGNORE_PREFIX_PATH ${HOMEBREW_PREFIXES}) + message (STATUS "CMAKE_IGNORE_PATH: ${CMAKE_IGNORE_PATH}") endif () diff --git a/src/cmake/dependency_utils.cmake b/src/cmake/dependency_utils.cmake index 3543966b6a..5f0f7f5e29 100644 --- a/src/cmake/dependency_utils.cmake +++ b/src/cmake/dependency_utils.cmake @@ -742,6 +742,10 @@ macro (build_dependency_with_cmake pkgname) string(REPLACE ";" "\\;" CMAKE_IGNORE_PATH_ESCAPED "${CMAKE_IGNORE_PATH}") list(APPEND _pkg_CMAKE_ARGS "-DCMAKE_IGNORE_PATH=${CMAKE_IGNORE_PATH_ESCAPED}") endif() + if (CMAKE_IGNORE_PREFIX_PATH) + string(REPLACE ";" "\\;" CMAKE_IGNORE_PREFIX_PATH_ESCAPED "${CMAKE_IGNORE_PREFIX_PATH}") + list(APPEND _pkg_CMAKE_ARGS "-DCMAKE_IGNORE_PREFIX_PATH=${CMAKE_IGNORE_PREFIX_PATH_ESCAPED}") + endif() # Pass along any CMAKE_MSVC_RUNTIME_LIBRARY if (WIN32 AND CMAKE_MSVC_RUNTIME_LIBRARY) From 338fd7ee0b8c089faac04e444cf2294e107427b5 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Wed, 5 Aug 2026 16:06:10 -0400 Subject: [PATCH 8/9] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Zach Lewis --- src/cmake/dependency_utils.cmake | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cmake/dependency_utils.cmake b/src/cmake/dependency_utils.cmake index 5f0f7f5e29..e95a54cc15 100644 --- a/src/cmake/dependency_utils.cmake +++ b/src/cmake/dependency_utils.cmake @@ -706,10 +706,16 @@ macro (build_dependency_with_cmake pkgname) # commits are the ones pinned by the verified superproject commit and # inherit its supply-chain guarantee. if (NOT "${_pkg_GIT_SUBMODULES}" STREQUAL "") - execute_process(COMMAND ${GIT_EXECUTABLE} submodule update - --init --depth 1 -- ${_pkg_GIT_SUBMODULES} - WORKING_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR} - ${_pkg_exec_quiet}) + execute_process( + COMMAND ${GIT_EXECUTABLE} submodule update --init --depth 1 -- ${_pkg_GIT_SUBMODULES} + WORKING_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR} + RESULT_VARIABLE _pkg_submodule_result + ERROR_VARIABLE _pkg_submodule_errors + ERROR_STRIP_TRAILING_WHITESPACE + ${_pkg_exec_quiet}) + if (NOT _pkg_submodule_result EQUAL 0) + message (FATAL_ERROR "${pkgname}: git submodule update failed: ${_pkg_submodule_errors}") + endif () endif () # Configure the package From 58809766711d07b744d5edc412ed99f65fec0c3a Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Wed, 5 Aug 2026 16:13:07 -0400 Subject: [PATCH 9/9] Fix formatting in build_JXL.cmake comments Signed-off-by: Zach Lewis --- src/cmake/build_JXL.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmake/build_JXL.cmake b/src/cmake/build_JXL.cmake index cad55650e1..ac81406fbf 100644 --- a/src/cmake/build_JXL.cmake +++ b/src/cmake/build_JXL.cmake @@ -16,7 +16,7 @@ set_cache (JXL_GIT_COMMIT "a7a9c787341cf703dede03c2009fa460cae5e5df" # and folded in, so the installed libraries are self-contained and match # what OIIO's FindJXL module expects to link (jxl + jxl_threads). set_cache (JXL_BUILD_SHARED_LIBS ON - DOC "Should a local JXL build, if necessary, build shared libraries" ADVANCED) + "Should a local JXL build, if necessary, build shared libraries" ADVANCED) build_dependency_with_cmake(JXL VERSION ${JXL_BUILD_VERSION}