Skip to content

COMP: Repair DCMTK build-tree export references for external consumers#6548

Open
hjmjohnson wants to merge 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:fix-dcmtk-buildtree-export-repair
Open

COMP: Repair DCMTK build-tree export references for external consumers#6548
hjmjohnson wants to merge 1 commit into
InsightSoftwareConsortium:mainfrom
hjmjohnson:fix-dcmtk-buildtree-export-repair

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Jul 3, 2026

Copy link
Copy Markdown
Member

Repair DCMTK's build-tree export after find_package(DCMTK) import — strip the DCMTK:: prefix from any link-interface reference that is not an existing target (all genuine DCMTK:: targets exist once DCMTKTargets.cmake is included) — so external consumers of an ITK build tree (e.g. an ANTs SuperBuild) survive CMake generate. Split out of #6543 at @blowekamp's request; the repair loop is line-for-line the fix proposed upstream in DCMTK/dcmtk#150, so it can be deleted verbatim when ITK's DCMTK pin includes that fix.

Merge-ordering note: once #6543's namespaced linking is in, an external build-tree consumer fails at generate without this repair (repro below); on pre-#6543 main the same consumer already fails, but later, at link (bare dcmdata names resolving against the system DCMTK). Install-tree consumers are unaffected either way.

Root cause

DCMTK's build-tree DCMTKTargets.cmake is written by the legacy export(TARGETS ... NAMESPACE DCMTK::), which prefixes DCMTK:: onto ITK's imported codec targets and records the nonexistent DCMTK::ITK::ITKZLIBModule (and TIFF/JPEG/PNG). An external consumer of an ITK build tree that resolves the DCMTK targets (where ITK_BINARY_DIR is unset in the find_package(ITK) scope) fails at generate. The install-tree export, written by install(EXPORT), resolves the same dependencies to their real ITK::* names and is unaffected.

Patching after import (in ITKDCMTK_EXPORT_CODE_BUILD) preserves the DCMTK_DIR seeding and every DCMTKConfig side effect, and corrects the targets regardless of import order. The "normal" fix is proposed upstream as DCMTK/dcmtk#150 (identical repair, shipped in DCMTKConfig.cmake itself); this in-ITK patch is the contained workaround until ITK's DCMTK pin includes it. The existence-checked form (rather than a DCMTK::ITK:: string replace) also covers the second defect shape found while building the upstream minimal repro: ALIAS targets are recorded de-aliased (e.g. DCMTK::super_zlibwrap), with no :: in the stripped name.

Minimal reproduction (verified)
  1. Configure and build ITK at COMP: Link namespaced DCMTK targets in the DCMTK IO modules #6543's head (0a0a06c700a) with the vendored DCMTK:
cmake -S ITK -B ITK-build -G Ninja -DModule_ITKIODCMTK:BOOL=ON -DITK_USE_SYSTEM_DCMTK:BOOL=OFF
ninja -C ITK-build ITKIODCMTK
grep 'DCMTK::ITK::' ITK-build/DCMTKTargets.cmake   # the mis-prefixed entries
  1. Configure a minimal external consumer against the build tree (use the same compiler as the ITK build):
# CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(consumer CXX C)
find_package(ITK REQUIRED COMPONENTS ITKIODCMTK)
include(${ITK_USE_FILE})
add_executable(t main.cxx)
target_link_libraries(t ${ITK_LIBRARIES})
// main.cxx
#include "itkDCMTKImageIO.h"
int main() { auto io = itk::DCMTKImageIO::New(); return io.IsNull() ? 1 : 0; }
cmake -S consumer -B consumer-build -G Ninja -DITK_DIR=$PWD/ITK-build
  1. Without this PR, generate fails:
CMake Error at .../ITK-build/DCMTKTargets.cmake:83 (set_target_properties):
  The link interface of target "DCMTK::dcmdata" contains:

    DCMTK::ITK::ITKZLIBModule

  but the target was not found.
  1. With this PR applied on top of COMP: Link namespaced DCMTK targets in the DCMTK IO modules #6543, the consumer configures, generates, links, and runs (./consumer-build/t; echo $?0).
Testing performed

Composes with #6543 (kept independent: applies and configures standalone on main).

@github-actions github-actions Bot added type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots area:ThirdParty Issues affecting the ThirdParty module labels Jul 3, 2026
@hjmjohnson hjmjohnson requested a review from blowekamp July 3, 2026 19:45
DCMTK's build-tree DCMTKTargets.cmake is written by the legacy
export(TARGETS ... NAMESPACE DCMTK::), which prefixes DCMTK:: onto
ITK's imported codec targets and records the nonexistent
DCMTK::ITK::ITKZLIBModule (and TIFF/JPEG/PNG). An external consumer of
an ITK build tree that resolves the DCMTK targets (e.g. an ANTs
SuperBuild, where ITK_BINARY_DIR is unset in the find_package(ITK)
scope) fails at generate with 'target DCMTK::ITK::ITKZLIBModule not
found'. The install-tree export, written by install(EXPORT), resolves
the same dependencies to their real ITK::* names and is unaffected.

Rewrite the mis-prefixed link-interface entries in place after the
existing find_package(DCMTK) import. Patching after import preserves
the DCMTK_DIR seeding and every DCMTKConfig side effect (DCMTK_FOUND,
DCMTK_INCLUDE_DIRS, ...), and corrects the targets regardless of
whether the consumer imported them before or after find_package(ITK).
@hjmjohnson hjmjohnson force-pushed the fix-dcmtk-buildtree-export-repair branch from 6eab740 to ec1ff34 Compare July 3, 2026 21:11
@hjmjohnson hjmjohnson marked this pull request as ready for review July 4, 2026 14:12
@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR repairs DCMTK build-tree exports for external ITK consumers. The main changes are:

  • Re-imports DCMTK from the ITK build root for build-tree consumers.
  • Rewrites missing DCMTK:: link-interface references after find_package(DCMTK).
  • Leaves install-tree DCMTK lookup unchanged.

Confidence Score: 4/5

Safe after the suffixed-target case is handled.

The change is narrow, but the repair loop skips the actual exported target names when DCMTK_LIBRARY_SUFFIX is set.

Modules/ThirdParty/DCMTK/CMakeLists.txt

T-Rex T-Rex Logs

What T-Rex did

  • The suffixed-target repair scenario was reproduced using a deterministic harness that loads the repository CMakeLists.txt and models the suffixed DCMTK target.
  • The run demonstrated that the build-tree repair loop iterates unsuffixed names, checks DCMTK::dcmdata, skips the repair, and leaves the suffixed target's final INTERFACE_LINK_LIBRARIES containing the ITKZLIBModule entry.
  • Because CMake and Ninja were not available in PATH, the reproduction used a deterministic fallback script rather than a native CMake harness.
  • Environment checks showed cmake, ninja, and pixi were not found while gcc/g++ were available, and the end-to-end runtime path could not be executed, so no runtime finding was reported.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
Modules/ThirdParty/DCMTK/CMakeLists.txt Adds a build-tree DCMTK target link-interface repair loop, but it misses configurations using DCMTK_LIBRARY_SUFFIX.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
  participant Consumer as External build-tree consumer
  participant ITK as ITKConfig / module export code
  participant DCMTK as DCMTKConfig + DCMTKTargets
  Consumer->>ITK: find_package(ITK COMPONENTS ITKIODCMTK)
  ITK->>DCMTK: find_package(DCMTK) with build-tree DCMTK_DIR
  DCMTK-->>ITK: imports DCMTK:: targets
  ITK->>ITK: rewrite missing DCMTK:: link-interface entries
  ITK-->>Consumer: exposes corrected ITKIODCMTK dependencies
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
  participant Consumer as External build-tree consumer
  participant ITK as ITKConfig / module export code
  participant DCMTK as DCMTKConfig + DCMTKTargets
  Consumer->>ITK: find_package(ITK COMPONENTS ITKIODCMTK)
  ITK->>DCMTK: find_package(DCMTK) with build-tree DCMTK_DIR
  DCMTK-->>ITK: imports DCMTK:: targets
  ITK->>ITK: rewrite missing DCMTK:: link-interface entries
  ITK-->>Consumer: exposes corrected ITKIODCMTK dependencies
Loading

Reviews (1): Last reviewed commit: "COMP: Repair DCMTK build-tree export ref..." | Re-trigger Greptile

Comment on lines +172 to +179
list(JOIN _ITKDCMTK_LIB_NAMES " " _itkdcmtk_lib_names_spaced)
set(
ITKDCMTK_EXPORT_CODE_BUILD
"
if(NOT ITK_BINARY_DIR)
set(DCMTK_DIR \"${CMAKE_BINARY_DIR}\")
find_package(DCMTK REQUIRED NO_MODULE)
foreach(_itkdcmtk_lib ${_itkdcmtk_lib_names_spaced})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Include suffixed targets
The repair loop uses the unsuffixed _ITKDCMTK_LIB_NAMES, but this file creates and links DCMTK::${_dcmtk_lib}${DCMTK_LIBRARY_SUFFIX} targets at lines 151-161. When DCMTK_LIBRARY_SUFFIX is non-empty, no DCMTK::dcmdata target exists, so the loop skips every exported DCMTK target and leaves the broken DCMTK::ITK::* references in the build-tree export.

Artifacts

Repro: deterministic suffixed DCMTK repair harness

  • Contains supporting evidence from the run (text/x-python; charset=utf-8).

Repro: harness execution log showing skipped repair and remaining broken entry

  • Keeps the command output available without making the summary code-heavy.

Repro: command-v output showing CMake and Ninja unavailable

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

@blowekamp

Copy link
Copy Markdown
Member

This solution does not seem quite right to me.

If DCMTK saw ITK's provided libraries as "imported" targets it would not alter the namespace. I tries one way to modify the ITK's third party libraries to be imported target to DCMTK but it did not work. I may look into modifying how DCMTK does the exports.

I have not found this type of issue in searches. I may create a minimal reproducible example and seek some advice on it.

@hjmjohnson

hjmjohnson commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

I may create a minimal reproducible example and seek some advice on it.

@blowekamp See DCMTK/dcmtk#150 for a minimal reproducible example. I am trying to build a forest of tools (ANTs, BRAINSTools, Slicer, SlicerExtensions, ITK-SNAP, .... and may others, and keep running into DCMTK build failures downstream.

@blowekamp

Copy link
Copy Markdown
Member

I may create a minimal reproducible example and seek some advice on it.

@blowekamp See DCMTK/dcmtk#150 for a minimal reproducible example. I am trying to build a forest of tools (ANTs, BRAINSTools, Slicer, SlicerExtensions, ITK-SNAP, .... and may others, and keep running into DCMTK build failures downstream.

That is a good start to the MRE I was thinking. But I was going also going to create a minimal sub-project to replace DCMTK's library and export.

On thing that is atypical in ITK is that the export name space is set as a property:

set_target_properties(
${_name}
PROPERTIES
EXPORT_NAME
${_export_namespace}${_name}
)

I am currently looking at example cmake code which export multiple namespace to see how things can be done.

@hjmjohnson

Copy link
Copy Markdown
Member Author

@blowekamp Thank you for looking into this. If you find a workable solution, please just push over top of this PR, or close this and open a new PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:ThirdParty Issues affecting the ThirdParty module type:Compiler Compiler support or related warnings type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants