diff --git a/pyproject.toml b/pyproject.toml index f87303460a..ef82f1fc50 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,6 +76,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/build_ZLIB.cmake b/src/cmake/build_ZLIB.cmake index 6c08e92a33..220e161b12 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} @@ -26,16 +88,49 @@ build_dependency_with_cmake(ZLIB # 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} ) # 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..4de964fb4e 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 @@ -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 6cb6aaf507..bbbd986787 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -37,7 +37,28 @@ 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 +# 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) + # 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 () + 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 () # Help set up this target for libtiff config file when using static libtiff if (NOT TARGET CMath::CMath)