From 5876181b6ef753a536ee1fd5e7269c5becc4417e Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Sat, 29 Jun 2024 22:04:17 -0700 Subject: [PATCH] build: raise libtiff min to 4.0 + self-build for libtiff (and libdeflate) (#4296) Signed-off-by: Larry Gritz --- .github/workflows/ci.yml | 1 - INSTALL.md | 2 +- src/cmake/build_TIFF.cmake | 63 ++++++++++++++++++++++++++++++++ src/cmake/build_libdeflate.cmake | 38 +++++++++++++++++++ src/cmake/dependency_utils.cmake | 41 ++++++++++++++++----- src/cmake/externalpackages.cmake | 17 ++++++--- src/tiff.imageio/tiffinput.cpp | 12 +++--- src/tiff.imageio/tiffoutput.cpp | 4 +- 8 files changed, 153 insertions(+), 25 deletions(-) create mode 100644 src/cmake/build_TIFF.cmake create mode 100644 src/cmake/build_libdeflate.cmake diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18fd7487d1..1eee252cf4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -360,7 +360,6 @@ jobs: setenvs: export OpenImageIO_BUILD_LOCAL_DEPS=all LIBJPEGTURBO_VERSION=3.0.1 LIBRAW_VERSION=0.21.2 - OPENCOLORIO_VERSION=v2.3.2 OPENJPEG_VERSION=v2.4.0 PTEX_VERSION=v2.4.2 PUGIXML_VERSION=v1.14 diff --git a/INSTALL.md b/INSTALL.md index dd990924d5..234bd48c6a 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -22,7 +22,7 @@ NEW or CHANGED MINIMUM dependencies since the last major release are **bold**. * **CMake >= 3.15** (tested through 3.29) * **OpenEXR/Imath >= 3.1** (tested through 3.2 and main) - * libTIFF >= 3.9 (recommended: 4.0+; tested through 4.6) + * **libTIFF >= 4.0** (tested through 4.6) * libjpeg >= 8 (tested through jpeg9e), or **libjpeg-turbo >= 2.1** (tested through 3.0) * **[fmtlib](https://github.com/fmtlib/fmt) >= 7.0** (tested through 10.2). diff --git a/src/cmake/build_TIFF.cmake b/src/cmake/build_TIFF.cmake new file mode 100644 index 0000000000..93c3507fa0 --- /dev/null +++ b/src/cmake/build_TIFF.cmake @@ -0,0 +1,63 @@ +# Copyright Contributors to the OpenImageIO project. +# SPDX-License-Identifier: Apache-2.0 +# https://github.com/AcademySoftwareFoundation/OpenImageIO + +###################################################################### +# TIFF by hand! +###################################################################### + +set_cache (TIFF_BUILD_VERSION 4.6.0 "TIFF version for local builds") +set (TIFF_GIT_REPOSITORY "https://gitlab.com/libtiff/libtiff.git") +set (TIFF_GIT_TAG "v${TIFF_BUILD_VERSION}") +set_cache (TIFF_BUILD_SHARED_LIBS ${LOCAL_BUILD_SHARED_LIBS_DEFAULT} + DOC "Should a local TIFF build, if necessary, build shared libraries" ADVANCED) + +# We need libdeflate to build libtiff +checked_find_package (libdeflate REQUIRED + VERSION_MIN 1.18) +alias_library_if_not_exists (Deflate::Deflate libdeflate::libdeflate_static) + +if (TARGET libjpeg-turbo::jpeg) + # We've had some trouble with TIFF finding the JPEG resources it needs to + # build if we're using libjpeg-turbo, TIFF needs an extra nudge. + get_target_property(JPEG_INCLUDE_DIRS JPEG::JPEG INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(JPEG_LIBRARIES JPEG::JPEG INTERFACE_LINK_LIBRARIES) + set (JPEG_FOUND TRUE) + set (MORE_TIFF_CMAKE_ARGS + -D JPEG_INCLUDE_DIR=${JPEG_INCLUDE_DIRS} + -D JPEG_LIBRARY=${JPEG_LIBRARIES} ) +endif () + +build_dependency_with_cmake(TIFF + VERSION ${TIFF_BUILD_VERSION} + GIT_REPOSITORY ${TIFF_GIT_REPOSITORY} + GIT_TAG ${TIFF_GIT_TAG} + CMAKE_ARGS + -D BUILD_SHARED_LIBS=${TIFF_BUILD_SHARED_LIBS} + -D CMAKE_POSITION_INDEPENDENT_CODE=ON + -D CMAKE_INSTALL_LIBDIR=lib + -D tiff-tools=OFF + -D tiff-contrib=OFF + -D tiff-tests=OFF + -D tiff-docs=OFF + -D libdeflate=ON + -D lzma=OFF + -D zstd=OFF + -D jbig=OFF + ${MORE_TIFF_CMAKE_ARGS} + ) + +# Set some things up that we'll need for a subsequent find_package to work + +set (TIFF_ROOT ${TIFF_LOCAL_INSTALL_DIR}) +set (TIFF_DIR ${TIFF_LOCAL_INSTALL_DIR}) + +# Signal to caller that we need to find again at the installed location +# set (TIFF_REFIND TRUE) +find_package (TIFF REQUIRED) + +if (TIFF_BUILD_SHARED_LIBS) + install_local_dependency_libs (TIFF TIFF) +endif () + +unset (MORE_TIFF_CMAKE_ARGS) diff --git a/src/cmake/build_libdeflate.cmake b/src/cmake/build_libdeflate.cmake new file mode 100644 index 0000000000..50543699ce --- /dev/null +++ b/src/cmake/build_libdeflate.cmake @@ -0,0 +1,38 @@ +# Copyright Contributors to the OpenImageIO project. +# SPDX-License-Identifier: Apache-2.0 +# https://github.com/AcademySoftwareFoundation/OpenImageIO + +###################################################################### +# libdeflate by hand! +###################################################################### + +set_cache (libdeflate_BUILD_VERSION 1.20 "libdeflate version for local builds") +set (libdeflate_GIT_REPOSITORY "https://github.com/ebiggers/libdeflate") +set (libdeflate_GIT_TAG "v${libdeflate_BUILD_VERSION}") +set_cache (libdeflate_BUILD_SHARED_LIBS ${LOCAL_BUILD_SHARED_LIBS_DEFAULT} + DOC "Should a local libdeflate build, if necessary, build shared libraries" ADVANCED) + +string (MAKE_C_IDENTIFIER ${libdeflate_BUILD_VERSION} libdeflate_VERSION_IDENT) + +build_dependency_with_cmake(libdeflate + VERSION ${libdeflate_BUILD_VERSION} + GIT_REPOSITORY ${libdeflate_GIT_REPOSITORY} + GIT_TAG ${libdeflate_GIT_TAG} + CMAKE_ARGS + -D BUILD_SHARED_LIBS=${libdeflate_BUILD_SHARED_LIBS} + -D CMAKE_POSITION_INDEPENDENT_CODE=ON + -D CMAKE_INSTALL_LIBDIR=lib + -D LIBDEFLATE_BUILD_GZIP=OFF + ) + +# Set some things up that we'll need for a subsequent find_package to work + +set (libdeflate_ROOT ${libdeflate_LOCAL_INSTALL_DIR}) + +# Signal to caller that we need to find again at the installed location +set (libdeflate_REFIND TRUE) +set (libdeflate_REFIND_ARGS CONFIG) + +if (libdeflate_BUILD_SHARED_LIBS) + install_local_dependency_libs (libdeflate libdeflate) +endif () diff --git a/src/cmake/dependency_utils.cmake b/src/cmake/dependency_utils.cmake index 8426c2cb39..a1470a1c70 100644 --- a/src/cmake/dependency_utils.cmake +++ b/src/cmake/dependency_utils.cmake @@ -24,7 +24,8 @@ include_directories(BEFORE ${${PROJECT_NAME}_LOCAL_DEPS_ROOT}/include) # as the current project. set_cache (${PROJECT_NAME}_DEPENDENCY_BUILD_TYPE ${CMAKE_BUILD_TYPE} "Build type for locally built dependencies") - +set_option (${PROJECT_NAME}_DEPENDENCY_BUILD_VERBOSE + "Make dependency builds extra verbose" OFF) if (MSVC) # I haven't been able to get Windows local dependency builds to work with # static libraries, so default to shared libraries on Windows until we can @@ -516,22 +517,37 @@ macro (build_dependency_with_cmake pkgname) set (${pkgname}_LOCAL_INSTALL_DIR "${${PROJECT_NAME}_LOCAL_DEPS_ROOT}/dist") message (STATUS "Downloading local ${_pkg_GIT_REPOSITORY}") + set (_pkg_quiet OUTPUT_QUIET) + # Clone the repo if we don't already have it find_package (Git REQUIRED) if (NOT IS_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR}) execute_process(COMMAND ${GIT_EXECUTABLE} clone ${_pkg_GIT_REPOSITORY} - -b ${_pkg_GIT_TAG} --depth 1 - ${${pkgname}_LOCAL_SOURCE_DIR}) + -b ${_pkg_GIT_TAG} --depth 1 -q + ${${pkgname}_LOCAL_SOURCE_DIR} + ${_pkg_quiet}) if (NOT IS_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR}) message (FATAL_ERROR "Could not download ${_pkg_GIT_REPOSITORY}") endif () endif () execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${_pkg_GIT_TAG} - WORKING_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR}) - - set (_pkg_quiet OUTPUT_QUIET) + WORKING_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR} + ${_pkg_quiet}) # Configure the package + if (${PROJECT_NAME}_DEPENDENCY_BUILD_VERBOSE) + set (_pkg_cmake_verbose -DCMAKE_VERBOSE_MAKEFILE=ON + -DCMAKE_MESSAGE_LOG_LEVEL=VERBOSE + -DCMAKE_RULE_MESSAGES=ON + ) + else () + set (_pkg_cmake_verbose -DCMAKE_VERBOSE_MAKEFILE=OFF + -DCMAKE_MESSAGE_LOG_LEVEL=ERROR + -DCMAKE_RULE_MESSAGES=OFF + -Wno-dev + ) + endif () + execute_process (COMMAND ${CMAKE_COMMAND} # Put things in our special local build areas @@ -542,10 +558,8 @@ macro (build_dependency_with_cmake pkgname) -DCMAKE_BUILD_TYPE=${${PROJECT_NAME}_DEPENDENCY_BUILD_TYPE} # Shhhh -DCMAKE_MESSAGE_INDENT=" " - -DCMAKE_MESSAGE_LOG_LEVEL=WARNING -DCMAKE_COMPILE_WARNING_AS_ERROR=OFF - -DCMAKE_VERBOSE_MAKEFILE=OFF - -DCMAKE_RULE_MESSAGES=OFF + ${_pkg_cmake_verbose} # Build args passed by caller ${_pkg_CMAKE_ARGS} ${pkg_quiet} @@ -597,3 +611,12 @@ macro (install_local_dependency_libs pkgname libname) endif () unset (_lib_files) endmacro () + + +# If the target `newalias` doesn't yet exist but `realtarget` does, create an +# alias for `newalias` to mean the real target. +macro (alias_library_if_not_exists newalias realtarget) + if (NOT TARGET ${newalias} AND TARGET ${realtarget}) + add_library(${newalias} ALIAS ${realtarget}) + endif () +endmacro () diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index 698fcb1b29..038f31c6ef 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -49,11 +49,6 @@ if (NOT TARGET CMath::CMath) endif () endif () -checked_find_package (TIFF REQUIRED - VERSION_MIN 3.9 - RECOMMEND_MIN 4.0 - RECOMMEND_MIN_REASON "to support >4GB files") - # IlmBase & OpenEXR checked_find_package (Imath REQUIRED VERSION_MIN 3.1 @@ -81,10 +76,20 @@ set (OPENIMAGEIO_CONFIG_DO_NOT_FIND_IMATH OFF CACHE BOOL checked_find_package (libjpeg-turbo VERSION_MIN 2.1 DEFINITIONS USE_JPEG_TURBO=1) -if (NOT TARGET libjpeg-turbo::jpeg) # Try to find the non-turbo version +if (TARGET libjpeg-turbo::jpeg) # Try to find the non-turbo version + # Doctor it so libjpeg-turbo is aliased as JPEG::JPEG + alias_library_if_not_exists (JPEG::JPEG libjpeg-turbo::jpeg) + set (JPEG_FOUND TRUE) +else () + # Try to find the non-turbo version checked_find_package (JPEG REQUIRED) endif () + +checked_find_package (TIFF REQUIRED + VERSION_MIN 4.0) +alias_library_if_not_exists (TIFF::TIFF TIFF::tiff) + # JPEG XL option (USE_JXL "Enable JPEG XL support" ON) checked_find_package (JXL diff --git a/src/tiff.imageio/tiffinput.cpp b/src/tiff.imageio/tiffinput.cpp index a489ad50f0..99e1d44b97 100644 --- a/src/tiff.imageio/tiffinput.cpp +++ b/src/tiff.imageio/tiffinput.cpp @@ -56,10 +56,8 @@ # define OIIO_TIFFLIB_VERSION 40003 #elif TIFFLIB_VERSION >= 20111221 # define OIIO_TIFFLIB_VERSION 40000 -#elif TIFFLIB_VERSION >= 20090820 -# define OIIO_TIFFLIB_VERSION 30900 #else -# error "libtiff 3.9.0 or later is required" +# error "libtiff 4.0.0 or later is required" #endif // clang-format on @@ -1673,7 +1671,9 @@ TIFFInput::read_native_scanline(int subimage, int miplevel, int y, int /*z*/, m_rgbadata.data(), ORIENTATION_TOPLEFT, 0); if (!ok) { - errorfmt("Unknown error trying to read TIFF as RGBA"); + std::string err = oiio_tiff_last_error(); + errorfmt("Unknown error trying to read TIFF as RGBA ({})", + err.size() ? err.c_str() : "unknown error"); return false; } } @@ -2054,7 +2054,9 @@ TIFFInput::read_native_tile(int subimage, int miplevel, int x, int y, int z, m_rgbadata.resize(m_spec.tile_pixels()); bool ok = TIFFReadRGBATile(m_tif, x, y, m_rgbadata.data()); if (!ok) { - errorfmt("Unknown error trying to read TIFF as RGBA"); + std::string err = oiio_tiff_last_error(); + errorfmt("Unknown error trying to read TIFF as RGBA ({})", + err.size() ? err.c_str() : "unknown error"); return false; } // Copy, and use stride magic to reverse top-to-bottom, because diff --git a/src/tiff.imageio/tiffoutput.cpp b/src/tiff.imageio/tiffoutput.cpp index 7bec7eaeec..d7708c9f4f 100644 --- a/src/tiff.imageio/tiffoutput.cpp +++ b/src/tiff.imageio/tiffoutput.cpp @@ -43,10 +43,8 @@ # define OIIO_TIFFLIB_VERSION 40003 #elif TIFFLIB_VERSION >= 20111221 # define OIIO_TIFFLIB_VERSION 40000 -#elif TIFFLIB_VERSION >= 20090820 -# define OIIO_TIFFLIB_VERSION 30900 #else -# error "libtiff 3.9.0 or later is required" +# error "libtiff 4.0.0 or later is required" #endif // clang-format on