From 6d6949547f636c34b4ca375b73a56afd8c019bdc Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Fri, 3 Jul 2026 15:17:35 -0500 Subject: [PATCH] Fixed build-tree export references for superproject builds. The build-tree DCMTKTargets.cmake is written by export(TARGETS ... NAMESPACE DCMTK::), which prefixes DCMTK:: onto every in-build target referenced by the exported link interfaces, including targets owned by a superproject that vendors DCMTK via add_subdirectory() or FetchContent() (e.g. a codec target supplied through ZLIB_LIBRARIES). The export then records nonexistent targets such as DCMTK::ITK::ITKZLIBModule or DCMTK::super_zlibwrap, and any external consumer of the superproject's build tree that imports DCMTKConfig fails at CMake generate with 'target ... not found'. The install-tree export is written by install(EXPORT) and resolves the same references correctly. All genuine DCMTK:: targets are defined once DCMTKConfig.cmake has included DCMTKTargets.cmake, so strip the mis-applied prefix from any DCMTK::-prefixed link-interface reference that is not an existing target. For the install tree and for standalone builds the loop is a no-op. --- CMake/DCMTKConfig.cmake.in | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/CMake/DCMTKConfig.cmake.in b/CMake/DCMTKConfig.cmake.in index 5a18695ff..625884663 100644 --- a/CMake/DCMTKConfig.cmake.in +++ b/CMake/DCMTKConfig.cmake.in @@ -173,4 +173,46 @@ endif() if(NOT DCMTK_TARGETS_IMPORTED) set(DCMTK_TARGETS_IMPORTED 1) include(${DCMTK_TARGETS}) + # When DCMTK is built inside a superproject (add_subdirectory/FetchContent), + # the build-tree export written by export(TARGETS ... NAMESPACE DCMTK::) + # also prefixes DCMTK:: onto link-interface targets owned by the + # superproject, recording nonexistent targets such as + # DCMTK::ITK::ITKZLIBModule or DCMTK::super_zlibwrap. All genuine DCMTK:: + # targets were just defined by the include() above, so strip the + # mis-applied prefix from any DCMTK::-prefixed reference that is not an + # existing target. The install-tree export is written by install(EXPORT) + # and is unaffected; there this loop is a no-op. + foreach(_dcmtk_lib @DCMTK_LIBRARY_TARGETS@) + if(TARGET DCMTK::${_dcmtk_lib}) + get_target_property(_dcmtk_ll DCMTK::${_dcmtk_lib} INTERFACE_LINK_LIBRARIES) + if(_dcmtk_ll) + set(_dcmtk_ll_new "") + foreach(_dcmtk_entry IN LISTS _dcmtk_ll) + set(_dcmtk_name "${_dcmtk_entry}") + set(_dcmtk_link_only 0) + if(_dcmtk_entry MATCHES "^\\$$") + set(_dcmtk_name "${CMAKE_MATCH_1}") + set(_dcmtk_link_only 1) + endif() + if(_dcmtk_name MATCHES "^DCMTK::(.+)$" AND NOT TARGET "${_dcmtk_name}") + set(_dcmtk_name "${CMAKE_MATCH_1}") + endif() + if(_dcmtk_link_only) + list(APPEND _dcmtk_ll_new "$") + else() + list(APPEND _dcmtk_ll_new "${_dcmtk_name}") + endif() + endforeach() + if(NOT "${_dcmtk_ll_new}" STREQUAL "${_dcmtk_ll}") + set_target_properties(DCMTK::${_dcmtk_lib} PROPERTIES INTERFACE_LINK_LIBRARIES "${_dcmtk_ll_new}") + endif() + unset(_dcmtk_ll_new) + unset(_dcmtk_entry) + unset(_dcmtk_name) + unset(_dcmtk_link_only) + endif() + unset(_dcmtk_ll) + endif() + endforeach() + unset(_dcmtk_lib) endif()