From 096508a022b08eb6a115dda40005ed461a54b084 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Tue, 11 Feb 2025 18:00:00 -0500 Subject: [PATCH 1/5] deps: swap in zlib-ng for zlib with ENABLE_ZLIBNG=1 Stab at building zlib-ng (zlib api compatibility mode) by default. Using `checked_find_package` with ZLIB for any version over 2.0.0 will result in attempting to build, install, and find zlib-ng as zlib. If zlib-ng is installed and found as "zlib" this way, then the CMake variable ZLIB_VERSION overwritten to match the value of ZLIB_VERSION in zlib.h This value will match "${ZLIB_VERSION}.zlib-ng". In a future commit, we should remove the `ZLIB_VERSION` CMake variable munging, and instead check for the value of ZLIB_VERSION when assembling "build:dependencies" compiling the OIIO. Signed-off-by: Zach Lewis --- pyproject.toml | 2 + src/cmake/build_ZLIB.cmake | 121 +++++++++++++++++++++++++++---- src/cmake/build_minizip-ng.cmake | 2 +- src/cmake/externalpackages.cmake | 10 ++- 4 files changed, 120 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 53d27c5912..2b5026caab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,8 @@ LINKSTATIC = "1" # Standardize the install directory for libraries, as expected by # other parts of the wheels build process. CMAKE_INSTALL_LIBDIR = "lib" +#OpenImageIO_BUILD_LOCAL_DEPS = "all" +IGNORE_HOMEBREWED_DEPS = "1" # Dynamically set the package version metadata by pasrsing CMakeLists.txt. [tool.scikit-build.metadata.version] diff --git a/src/cmake/build_ZLIB.cmake b/src/cmake/build_ZLIB.cmake index 980fec8fe5..279afeb8c6 100644 --- a/src/cmake/build_ZLIB.cmake +++ b/src/cmake/build_ZLIB.cmake @@ -3,19 +3,81 @@ # https://github.com/AcademySoftwareFoundation/OpenImageIO ###################################################################### -# ZLIB by hand! +# ZLIB / ZLIB-NG by hand! ###################################################################### -set_cache (ZLIB_BUILD_VERSION 1.3.1 "ZLIB version for local builds") -set (ZLIB_GIT_REPOSITORY "https://github.com/madler/zlib") -set (ZLIB_GIT_TAG "v${ZLIB_BUILD_VERSION}") +# This script builds either zlib or zlib-ng (in compatibility mode) from source. -set_cache (ZLIB_BUILD_SHARED_LIBS ${LOCAL_BUILD_SHARED_LIBS_DEFAULT} - DOC "Should execute a local ZLIB build, if necessary, build shared libraries" ADVANCED) +# Zlib-ng is a fork of zlib that is actively maintained and has some +# performance improvments over the original zlib which pertain to +# PNG and WebP plugin performance (on Windows, in particular). + +# By default, we build zlib-ng in zlib API compatibility mode. This +# allows OIIO and its dependencies to use zlib-ng v2.2.4 as a drop-in +# replacement for zlib v1.3.1. + +# Please note -- this means that `find_package(ZLIB)` will recognize zlib-ng +# as zlib, and set ZLIB_VERSION = "1.3.1" (instead of zlib-ng's version) + + +# There are two ways to build against zlib instead of zlib-ng: + +# 1. At build time, set `ENABLE_ZLIBNG=OFF` to +# to build with the original zlib (defaults to ON). + +# 2. When using the `checked_find_package` macro, require a version +# less than 2.0.0, e.g. `find_package(ZLIB 1.3.1 REQUIRED)`. + + +set (ZLIB_VERSION_LATEST "1.3.1") +set (ZLIBNG_VERSION_LATEST "2.2.4") + +# By default, we build zlib-ng in compatibility mode. +# Set ENABLE_ZLIBNG=OFF to build the original zlib. +check_is_enabled(ZLIBNG ENABLE_ZLIBNG) + + +# Set the version to build; note that 1.x versions will build the original zlib, +# while 2.x or later will build zlib-ng. +if (ENABLE_ZLIBNG) + set_cache (ZLIB_BUILD_VERSION ${ZLIBNG_VERSION_LATEST} "ZLIB or ZLIB-NG version for local builds") +else () + set_cache (ZLIB_BUILD_VERSION ${ZLIB_VERSION_LATEST} "ZLIB or ZLIB-NG version for local builds") +endif () + + +# Choose the git repository, tag format, and extra arguments based on version. +# For now, we're assuming that the original zlib will never reach version 2.0, +# so anything greater than or equal to 2.0 is zlib-ng. +if (ZLIB_BUILD_VERSION VERSION_LESS "2.0.0") + # Original zlib: use the 'v' prefix in the tag. + set (ZLIB_GIT_REPOSITORY "https://github.com/madler/zlib") + set (ZLIB_GIT_TAG "v${ZLIB_BUILD_VERSION}") + set (ZLIB_BUILD_OPTIONS "") + set (ZLIBNG_USED FALSE) + if (ENABLE_ZLIBNG) + message (STATUS "Building zlib version ${ZLIB_BUILD_VERSION}, even though ENABLE_ZLIBNG=${ENABLE_ZLIBNG}") + message (STATUS "If you believe this is a mistake, check usages of `checked_find_package(ZLIB ...)` in the code base.") + message (STATUS "See src/cmake/build_ZLIB.cmake for more details.") + else () + message (STATUS "Building zlib version ${ZLIB_BUILD_VERSION}") + endif () +else () + # zlib-ng: omit the 'v' prefix for the git tag and enable compatibility mode. + set (ZLIB_GIT_REPOSITORY "https://github.com/zlib-ng/zlib-ng") + set (ZLIB_GIT_TAG "${ZLIB_BUILD_VERSION}") + set (ZLIB_BUILD_OPTIONS "-DZLIB_COMPAT=ON;-DWITH_GTEST=OFF;-DWITH_GZFILEOP=OFF;-DZLIBNG_ENABLE_TESTS=OFF;-DZLIB_ENABLE_TESTS=OFF") + set (ZLIBNG_USED TRUE) + message (STATUS "Building zlib-ng version ${ZLIB_BUILD_VERSION}") +endif () + + +set_cache (ZLIB_BUILD_SHARED_LIBS OFF + DOC "Should execute a local ZLIB build, if necessary, build shared libraries" ADVANCED) string (MAKE_C_IDENTIFIER ${ZLIB_BUILD_VERSION} ZLIB_VERSION_IDENT) -build_dependency_with_cmake(ZLIB +build_dependency_with_cmake (ZLIB VERSION ${ZLIB_BUILD_VERSION} GIT_REPOSITORY ${ZLIB_GIT_REPOSITORY} GIT_TAG ${ZLIB_GIT_TAG} @@ -23,16 +85,49 @@ build_dependency_with_cmake(ZLIB -D BUILD_SHARED_LIBS=${ZLIB_BUILD_SHARED_LIBS} -D CMAKE_POSITION_INDEPENDENT_CODE=ON -D CMAKE_INSTALL_LIBDIR=lib + ${ZLIB_BUILD_OPTIONS} ) # Set some things up that we'll need for a subsequent find_package to work set (ZLIB_ROOT ${ZLIB_LOCAL_INSTALL_DIR}) -# Signal to caller that we need to find again at the installed location -set (ZLIB_REFIND TRUE) -set (ZLIB_VERSION ${ZLIB_BUILD_VERSION}) -set (ZLIB_REFIND_VERSION ${ZLIB_BUILD_VERSION}) -if (ZLIB_BUILD_SHARED_LIBS) - install_local_dependency_libs (ZLIB ZLIB) +if (ZLIBNG_USED) + # zlib-ng provides a CMake config file, so we can use find_package directly. + find_package (ZLIB CONFIG REQUIRED HINTS ${ZLIB_LOCAL_INSTALL_DIR} NO_DEFAULT_PATH) + + # First, locate the directory containing zlib.h. + find_path (ZLIB_INCLUDE_DIR + NAMES zlib.h + HINTS ${ZLIB_ROOT}/include + ) + + if (NOT ZLIB_INCLUDE_DIR) + message (FATAL_ERROR "Could not locate zlib-ng include directory.") + endif () + + message (STATUS "Found zlib-ng header directory: ${ZLIB_INCLUDE_DIR}") + + # Read the contents of zlib.h + file (READ "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_HEADER_CONTENT) + + # Use a regular expression to search for the ZLIB_VERSION macro. + # This regex looks for a line like: #define ZLIB_VERSION "1.3.1.zlib-ng" + string (REGEX MATCH "#[ \t]*define[ \t]+ZLIB_VERSION[ \t]+\"([^\"]+)\"" _match "${ZLIB_HEADER_CONTENT}") + + if (_match) + # The first capture group is stored in CMAKE_MATCH_1. + set (ZLIB_VERSION "${CMAKE_MATCH_1}") + endif () + + +else () + # Vanilla ZLIB doesn't ship with a CMake config file, so we'll just "refind" it with the + # usual arguments. + set (ZLIB_REFIND TRUE) + set (ZLIB_REFIND_VERSION ${ZLIB_BUILD_VERSION}) endif () + +if (ZLIB_BUILD_SHARED_LIBS) + install_local_dependency_libs(ZLIB ZLIB) +endif() diff --git a/src/cmake/build_minizip-ng.cmake b/src/cmake/build_minizip-ng.cmake index c09e375fb6..638b174f47 100644 --- a/src/cmake/build_minizip-ng.cmake +++ b/src/cmake/build_minizip-ng.cmake @@ -14,7 +14,7 @@ set (minizip-ng_GIT_TAG "${minizip-ng_BUILD_VERSION}") set_cache (minizip-ng_BUILD_SHARED_LIBS OFF DOC "Should a local minizip-ng build, if necessary, build shared libraries" ADVANCED) -checked_find_package (ZLIB REQUIRED) +find_package (ZLIB REQUIRED) build_dependency_with_cmake(minizip-ng diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index eee6373d84..992e0f1248 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -37,7 +37,15 @@ include (FindThreads) # Dependencies for required formats and features. These are so critical # that we will not complete the build if they are not found. -checked_find_package (ZLIB REQUIRED) # Needed by several packages +check_is_enabled(ZLIBNG ENABLE_ZLIBNG) +if (ENABLE_ZLIBNG) + checked_find_package (ZLIB REQUIRED + VERSION_MIN 2.2.4 # ZLIB-NG + BUILD_LOCAL missing + ) +else () + checked_find_package (ZLIB REQUIRED) # Needed by several packages +endif () # Help set up this target for libtiff config file when using static libtiff if (NOT TARGET CMath::CMath) From f7a52313b96a04b6fd765aba3a5386971f161331 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Fri, 21 Feb 2025 17:45:45 -0500 Subject: [PATCH 2/5] fix: Revert changes to pyproject.toml Signed-off-by: Zach Lewis --- pyproject.toml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2b5026caab..53d27c5912 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,8 +73,6 @@ LINKSTATIC = "1" # Standardize the install directory for libraries, as expected by # other parts of the wheels build process. CMAKE_INSTALL_LIBDIR = "lib" -#OpenImageIO_BUILD_LOCAL_DEPS = "all" -IGNORE_HOMEBREWED_DEPS = "1" # Dynamically set the package version metadata by pasrsing CMakeLists.txt. [tool.scikit-build.metadata.version] From 72e8a29c56c4f1f24a8ec4cee61cd53fee3f8503 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Fri, 21 Feb 2025 20:22:21 -0500 Subject: [PATCH 3/5] build(zlib): ENABLE_ZLIB=1 permits building with zlib instead of zlib-ng DISABLE_ZLIB=1 to only build against zlib-ng. DISABLE_ZLIBNG=1 will attempt to build against zlib instead of zlib-ng; but it will not necessarily _prevent_ building against zlib-ng.... Signed-off-by: Zach Lewis --- pyproject.toml | 2 ++ src/cmake/externalpackages.cmake | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 53d27c5912..de5c106466 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,6 +73,8 @@ LINKSTATIC = "1" # Standardize the install directory for libraries, as expected by # other parts of the wheels build process. CMAKE_INSTALL_LIBDIR = "lib" +# Always build against zlib-ng (instead of regular zlib) +DISABLE_ZLIB = "1" # Dynamically set the package version metadata by pasrsing CMakeLists.txt. [tool.scikit-build.metadata.version] diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 992e0f1248..5a365345fc 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -37,14 +37,20 @@ include (FindThreads) # Dependencies for required formats and features. These are so critical # that we will not complete the build if they are not found. +# ZLIB +# We prefer zlib-ng to regular zlib, but we can use either. + check_is_enabled(ZLIBNG ENABLE_ZLIBNG) +check_is_enabled(ZLIB ALLOW_ZLIB) + if (ENABLE_ZLIBNG) - checked_find_package (ZLIB REQUIRED - VERSION_MIN 2.2.4 # ZLIB-NG - BUILD_LOCAL missing - ) + if (ALLOW_ZLIB) + checked_find_package (ZLIB PREFER_CONFIG REQUIRED) + else () + checked_find_package (ZLIB CONFIG REQUIRED) + endif () else () - checked_find_package (ZLIB REQUIRED) # Needed by several packages + checked_find_package (ZLIB REQUIRED) endif () # Help set up this target for libtiff config file when using static libtiff From 34ed8b0cb096e589934db58c9082ac0bb4f42793 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Fri, 7 Mar 2025 21:50:01 -0500 Subject: [PATCH 4/5] fix(deps): let minizip-ng find locally-built zlibs Signed-off-by: Zach Lewis --- src/cmake/build_minizip-ng.cmake | 2 -- src/cmake/externalpackages.cmake | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cmake/build_minizip-ng.cmake b/src/cmake/build_minizip-ng.cmake index 638b174f47..4de964fb4e 100644 --- a/src/cmake/build_minizip-ng.cmake +++ b/src/cmake/build_minizip-ng.cmake @@ -45,8 +45,6 @@ build_dependency_with_cmake(minizip-ng -D MZ_ICONV=OFF -D MZ_FETCH_LIBS=OFF -D MZ_FORCE_FETCH_LIBS=OFF - -D ZLIB_LIBRARY=${ZLIB_LIBRARIES} - -D ZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIRS} ) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 5a365345fc..2ce18c76dd 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -47,6 +47,7 @@ if (ENABLE_ZLIBNG) if (ALLOW_ZLIB) checked_find_package (ZLIB PREFER_CONFIG REQUIRED) else () + # This assumption will hold until zlib-1.3.2 is released. checked_find_package (ZLIB CONFIG REQUIRED) endif () else () From bd02b23e5997a7e93f8baff6759248e525451498 Mon Sep 17 00:00:00 2001 From: Zach Lewis Date: Wed, 2 Apr 2025 11:01:37 -0400 Subject: [PATCH 5/5] build: More changes to be robust for cmake 4.0 also, improve inline comments Signed-off-by: Zach Lewis --- src/cmake/build_ZLIB.cmake | 3 +++ src/cmake/externalpackages.cmake | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/cmake/build_ZLIB.cmake b/src/cmake/build_ZLIB.cmake index 279afeb8c6..220e161b12 100644 --- a/src/cmake/build_ZLIB.cmake +++ b/src/cmake/build_ZLIB.cmake @@ -85,6 +85,9 @@ build_dependency_with_cmake (ZLIB -D BUILD_SHARED_LIBS=${ZLIB_BUILD_SHARED_LIBS} -D CMAKE_POSITION_INDEPENDENT_CODE=ON -D CMAKE_INSTALL_LIBDIR=lib + # Fix for zlib breaking against cmake 4.0. + # Remove when zlib is fixed to declare its own minimum high enough. + -D CMAKE_POLICY_VERSION_MINIMUM=3.5 ${ZLIB_BUILD_OPTIONS} ) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 2ce18c76dd..b4978dffe6 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -44,13 +44,19 @@ check_is_enabled(ZLIBNG ENABLE_ZLIBNG) check_is_enabled(ZLIB ALLOW_ZLIB) if (ENABLE_ZLIBNG) + # For zlib <= 1.3.1, we can differentiate between whether + # find_package(ZLIB ...) finds zlib-ng or zlib with the CONFIG + # or PREFER_CONFIG options. if (ALLOW_ZLIB) + # Prefer zlib-ng if it's available, but fail over to zlib if it isn't. checked_find_package (ZLIB PREFER_CONFIG REQUIRED) else () - # This assumption will hold until zlib-1.3.2 is released. checked_find_package (ZLIB CONFIG REQUIRED) endif () else () + # Starting v1.3.2, zlib will export CMake configs; so once zlib-1.3.2+ + # starts shipping with distros, we will have to re-evaluate how (and if) + # we support "ignoring" compatibility-mode-zlib-ng in favor of system zlib. checked_find_package (ZLIB REQUIRED) endif ()