From ed9c983292adaea2af72c4f962fea8cf828ceecd Mon Sep 17 00:00:00 2001 From: Greg Benz Date: Sat, 26 Sep 2026 15:07:20 -0500 Subject: [PATCH 1/2] cmake: fix libheif feature detection with multiple definitions --- CMakeLists.txt | 39 ++++++++++++++ cmake/Findlibheif.cmake | 2 +- tests/cmake/libheif-discovery/CMakeLists.txt | 57 ++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tests/cmake/libheif-discovery/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 16928b74..3fd8c21f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -761,6 +761,45 @@ if(UHDR_BUILD_TESTS) -P "${TESTS_DIR}/windows_unicode_cli_test.cmake" ) endif() + + # The fixture configures with the host compiler; skip target toolchains such as Android. + if(NOT CMAKE_CROSSCOMPILING) + set(_libheif_discovery_cmake_args + -G "${CMAKE_GENERATOR}" + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + ) + if(CMAKE_GENERATOR_PLATFORM) + list(APPEND _libheif_discovery_cmake_args -A "${CMAKE_GENERATOR_PLATFORM}") + endif() + if(CMAKE_GENERATOR_TOOLSET) + list(APPEND _libheif_discovery_cmake_args -T "${CMAKE_GENERATOR_TOOLSET}") + endif() + if(CMAKE_TOOLCHAIN_FILE) + list(APPEND _libheif_discovery_cmake_args "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") + endif() + if(CMAKE_OSX_ARCHITECTURES) + string(REPLACE ";" "\\;" _libheif_discovery_osx_architectures "${CMAKE_OSX_ARCHITECTURES}") + list(APPEND _libheif_discovery_cmake_args + "-DCMAKE_OSX_ARCHITECTURES=${_libheif_discovery_osx_architectures}") + endif() + foreach(_variable IN ITEMS CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT) + if(DEFINED ${_variable} AND NOT "${${_variable}}" STREQUAL "") + list(APPEND _libheif_discovery_cmake_args "-D${_variable}=${${_variable}}") + endif() + endforeach() + + foreach(_case IN ITEMS no-defs empty-defs one-def multiple-defs missing-api) + add_test( + NAME "LibheifDiscovery-${_case}" + COMMAND ${CMAKE_COMMAND} + ${_libheif_discovery_cmake_args} + -S "${TESTS_DIR}/cmake/libheif-discovery" + -B "${CMAKE_CURRENT_BINARY_DIR}/libheif-discovery/${_case}" + "-DLIBHEIF_MODULE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/cmake" + "-DLIBHEIF_TEST_CASE=${_case}" + ) + endforeach() + endif() endif() if(UHDR_BUILD_BENCHMARK) diff --git a/cmake/Findlibheif.cmake b/cmake/Findlibheif.cmake index d4ff65ab..f1245220 100644 --- a/cmake/Findlibheif.cmake +++ b/cmake/Findlibheif.cmake @@ -91,7 +91,7 @@ if(LIBHEIF_TARGET) list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBHEIF_INCLUDE_DIR}) endif() if(LIBHEIF_DEFS) - set(CMAKE_REQUIRED_DEFINITIONS "-D${LIBHEIF_DEFS}") + list(TRANSFORM LIBHEIF_DEFS PREPEND "-D" OUTPUT_VARIABLE CMAKE_REQUIRED_DEFINITIONS) endif() # Perform a compile-only check to avoid linking transitive dependencies diff --git a/tests/cmake/libheif-discovery/CMakeLists.txt b/tests/cmake/libheif-discovery/CMakeLists.txt new file mode 100644 index 00000000..7cc3e515 --- /dev/null +++ b/tests/cmake/libheif-discovery/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.15) +project(libheif_discovery_regression LANGUAGES CXX) + +if(NOT LIBHEIF_MODULE_DIR OR NOT LIBHEIF_TEST_CASE) + message(FATAL_ERROR "LIBHEIF_MODULE_DIR and LIBHEIF_TEST_CASE are required") +endif() + +set(_fixture_root "${CMAKE_CURRENT_BINARY_DIR}/fixture") +set(_package_dir "${_fixture_root}/lib/cmake/libheif") +file(MAKE_DIRECTORY "${_package_dir}") + +set(_include_dir "${_fixture_root}/include/${LIBHEIF_TEST_CASE}/libheif") +file(MAKE_DIRECTORY "${_include_dir}") +if(LIBHEIF_TEST_CASE STREQUAL "one-def") + file(WRITE "${_include_dir}/heif.h" [=[ +#ifdef LIBHEIF_TEST_SINGLE +int heif_image_handle_get_gain_map_image_handle(); +#endif +]=]) +elseif(LIBHEIF_TEST_CASE STREQUAL "multiple-defs") + file(WRITE "${_include_dir}/heif.h" [=[ +#if defined(LIBHEIF_TEST_FIRST) && defined(LIBHEIF_TEST_SECOND) +int heif_image_handle_get_gain_map_image_handle(); +#endif +]=]) +elseif(LIBHEIF_TEST_CASE STREQUAL "missing-api") + file(WRITE "${_include_dir}/heif.h" "/* Gain map API intentionally absent. */\n") +else() + file(WRITE "${_include_dir}/heif.h" "int heif_image_handle_get_gain_map_image_handle();\n") +endif() + +file(WRITE "${_package_dir}/libheifConfig.cmake" [=[ +add_library(libheif::heif INTERFACE IMPORTED) +set_property(TARGET libheif::heif PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${LIBHEIF_TEST_INCLUDE_DIR}") +if(LIBHEIF_TEST_CASE STREQUAL "empty-defs") + set_property(TARGET libheif::heif PROPERTY INTERFACE_COMPILE_DEFINITIONS "") +elseif(LIBHEIF_TEST_CASE STREQUAL "one-def") + set_property(TARGET libheif::heif PROPERTY INTERFACE_COMPILE_DEFINITIONS LIBHEIF_TEST_SINGLE) +elseif(LIBHEIF_TEST_CASE STREQUAL "multiple-defs" OR LIBHEIF_TEST_CASE STREQUAL "missing-api") + set_property(TARGET libheif::heif PROPERTY INTERFACE_COMPILE_DEFINITIONS + LIBHEIF_TEST_FIRST LIBHEIF_TEST_SECOND) +endif() +]=]) + +set(libheif_DIR "${_package_dir}") +set(LIBHEIF_TEST_INCLUDE_DIR "${_fixture_root}/include/${LIBHEIF_TEST_CASE}") +list(APPEND CMAKE_MODULE_PATH "${LIBHEIF_MODULE_DIR}") +unset(LIBHEIF_HAS_GAIN_MAP CACHE) +find_package(libheif REQUIRED MODULE) + +if(LIBHEIF_TEST_CASE STREQUAL "missing-api") + if(LIBHEIF_HAS_GAIN_MAP) + message(FATAL_ERROR "The feature check accepted a missing gain map API") + endif() +elseif(NOT LIBHEIF_HAS_GAIN_MAP) + message(FATAL_ERROR "The feature check rejected the ${LIBHEIF_TEST_CASE} fixture") +endif() From 33d866d93c748d179d74fa454872169a3c5331a4 Mon Sep 17 00:00:00 2001 From: Greg Benz Date: Sat, 26 Sep 2026 15:19:11 -0500 Subject: [PATCH 2/2] test: consolidate libheif fixture configuration forwarding --- CMakeLists.txt | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fd8c21f..c535a3dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -764,27 +764,19 @@ if(UHDR_BUILD_TESTS) # The fixture configures with the host compiler; skip target toolchains such as Android. if(NOT CMAKE_CROSSCOMPILING) - set(_libheif_discovery_cmake_args - -G "${CMAKE_GENERATOR}" - "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" - ) + set(_libheif_discovery_cmake_args -G "${CMAKE_GENERATOR}") if(CMAKE_GENERATOR_PLATFORM) list(APPEND _libheif_discovery_cmake_args -A "${CMAKE_GENERATOR_PLATFORM}") endif() if(CMAKE_GENERATOR_TOOLSET) list(APPEND _libheif_discovery_cmake_args -T "${CMAKE_GENERATOR_TOOLSET}") endif() - if(CMAKE_TOOLCHAIN_FILE) - list(APPEND _libheif_discovery_cmake_args "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") - endif() - if(CMAKE_OSX_ARCHITECTURES) - string(REPLACE ";" "\\;" _libheif_discovery_osx_architectures "${CMAKE_OSX_ARCHITECTURES}") - list(APPEND _libheif_discovery_cmake_args - "-DCMAKE_OSX_ARCHITECTURES=${_libheif_discovery_osx_architectures}") - endif() - foreach(_variable IN ITEMS CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT) + + foreach(_variable IN ITEMS CMAKE_CXX_COMPILER CMAKE_TOOLCHAIN_FILE + CMAKE_OSX_ARCHITECTURES CMAKE_OSX_DEPLOYMENT_TARGET CMAKE_OSX_SYSROOT) if(DEFINED ${_variable} AND NOT "${${_variable}}" STREQUAL "") - list(APPEND _libheif_discovery_cmake_args "-D${_variable}=${${_variable}}") + string(REPLACE ";" "\\;" _value "${${_variable}}") + list(APPEND _libheif_discovery_cmake_args "-D${_variable}=${_value}") endif() endforeach()