COMP: Build DCMTK with FetchContent instead of ExternalProject#6397
COMP: Build DCMTK with FetchContent instead of ExternalProject#6397hjmjohnson wants to merge 5 commits into
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
|
The first Windows CI run surfaced a real bug in the in-scope conversion that my local target-by-target builds had missed (I was building
Fixed in Verified locally: |
|
Good diagnosis and clean fix. A few observations on The fix is correct.
The comment block at ~line 190 documents this reasoning well, which is good since "why not EXCLUDE_FROM_ALL" will come up in review. One thing to double-check with the CI run: Minor — ICU path is now inconsistent: The |
Root cause of the Windows CI failure — a fundamental blocker for the in-scope approachI chased the "3699 tests Not Run" down to its actual cause, and it is not about tests or WhyDCMTK and ITK's MINC both probe the C library with identical cache-variable names:
With Why this is the cruxThis is precisely what the ExternalProject design prevents: DCMTK is configured in a separate CMake process, so its hundreds of A fix would mean save/restoring all RecommendationThis confirms the in-scope/FetchContent direction is not viable for DCMTK without process isolation, which is the very thing ExternalProject already provides. I'd suggest keeping this PR as a documented exploration and landing the surgical ExternalProject fix in #6393 instead. Happy to pursue mitigation if the team wants to, but it would be a substantial and brittle undertaking. |
|
Using fetch content over external project remove the need to export DCMTK targets with ITK specific code. And similarly describe ITK target to DCMTK with variables. This is extra code burdens ITK developers. Can we determine what are the potential conflicted CMake Cache variables between ITK and DCMTK. Perhaps by examining a cache of ITK (without DCMTK) and one of a standalone DCMTK? Then we might need to modify a DCMTK or some other ITK subproject to address the conflict. For the HAVE_MKSTEMP above, perhaps MINC could be modified to use the MINC prefix for more of there CMake variables. |
bc50dc5 to
e7fb08c
Compare
|
@blowekamp Took your suggestion — enumerated the ITK↔DCMTK cache-variable collisions and fixed them in-tree ( Collision analysis (your "diff the caches" approach)Rather than two separate caches, I diffed MINC's generated
Fix
ValidationLocal (Linux, in-scope DCMTK + MINC, internal everything):
The actual Windows |
bf19e38 to
f08a836
Compare
|
Reworked the MINC fix ( Confirmed root cause
Fix
Inert on non-MSVC (Linux/macOS config.h unchanged); Windows CI is the first executor of the MSVC path. |
Replace the DCMTK ExternalProject with FetchContent + add_subdirectory so DCMTK is configured in ITK's own CMake scope (the GDCM model). DCMTK now consumes ITK's codec libraries as the live imported targets (ITK::itktiff/itkpng/zlib/itkjpeg) through the standard *_LIBRARIES variables -- no $<TARGET_FILE:> extraction or :::-separated CMAKE_ARGS. itk_module_use() is called up front so the codec variables are populated before DCMTK is configured. FetchContent_MakeAvailable(dcmtk) does the add_subdirectory; EXCLUDE_FROM_ALL is not used because on the in-scope DCMTK directory it leaks into ITK's own test targets and drops them from the ALL build. Charset conversion honors the DCMTK_USE_ICU opt-in, wiring ICU_ROOT through when set and otherwise using DCMTK's built-in oficonv data. Build-tree namespace aliases are a placeholder pending full module-target export.
Replace the placeholder build-tree aliases with itk_module_target(), which applies ITK's output naming (itk<lib>-X.Y), creates the namespaced ITK::<lib> aliases that itk_module_impl() links ITKDCMTKModule against, and appends DCMTK's targets to ITK's build-tree targets file. The targets file variable is set during module enablement, so this works before itk_module_impl(). Installation is deferred, hence NO_INSTALL.
Disable warnings for the DCMTK subdirectory with itk_module_warnings_disable before it is configured. ITK builds at /W4 while DCMTK builds at /W3, so every DCMTK source previously emitted an MSVC D9025 flag-override warning on top of DCMTK's own diagnostics. itk_module_impl() disables warnings for third-party modules, but DCMTK is added before that call, so apply it here.
Drop NO_INSTALL so itk_module_target() installs the DCMTK libraries into ITK's library directory and export set, and install each DCMTK module's public headers (<module>/include/dcmtk) plus the generated config headers into ITK's include tree so consumers of an installed ITK can include <dcmtk/...>. install(EXPORT ITKTargets) generates cleanly: the DCMTK targets' interface dependencies are ITK's exported codec targets, other DCMTK targets, or system libraries.
f08a836 to
f3fa220
Compare
|
@blowekamp. This ia an attempt to use FetchContent for DCMTK as you previously indicated would be desirable. I don't have a good use case for this, so I would like to leave it in your hands to review and determine next steps. 1). I am happy to abandon this work if it is not what you were hoping for. Hans |
Building DCMTK in ITK's shared CMake scope (FetchContent + add_subdirectory) runs DCMTK's configure in that scope, with two side effects on sibling third-party modules: - Leftover CMAKE_REQUIRED_* state from DCMTK's probes. Snapshot and restore it around FetchContent_MakeAvailable(dcmtk). - DCMTK's GenerateDCMTKConfigure.cmake globally redefines standard CMake check commands (CHECK_FUNCTION_EXISTS on Windows, CHECK_CXX_SYMBOL_EXISTS). CMake commands are global, so those overrides leak into ITK modules configured afterward: their CHECK_FUNCTION_EXISTS calls run DCMTK's header-less check_symbol_exists, report the function missing, and the module trips a #error -- MINC on tmpnam, GDCM on _strnicmp, depending on configure order. Restore the real implementations after DCMTK by including a copy of each module under a fresh path (include_guard(GLOBAL) blocks a plain re-include), fixing every dependent module regardless of order. The ExternalProject build never hit either because DCMTK configures in a separate CMake process.
f3fa220 to
db0fcf2
Compare
|
Assuming this work is not a desirable path, so closing this PR. |
|
I would like to come back to this to revisit. It looked like very good progress was made, but I have not had time to look closely. |
Builds DCMTK with
FetchContent+ in-scopeadd_subdirectoryinstead ofExternalProject_Add, so DCMTK is configured in ITK's own CMake scope and consumes ITK's codec libraries as the live imported targets (ITK::itktiff/itkpng/zlib/itkjpeg) — the GDCM model @blowekamp described in #6393, with no$<TARGET_FILE:>marshalling or:::-separatedCMAKE_ARGS.This is the full FetchContent alternative to #6393 (the surgical ExternalProject fix). Structured as one commit per integration hurdle so each can be reviewed independently.
Commits (one per hurdle)
COMP: Build DCMTK in-scope with FetchContentFetchContent_MakeAvailable+itk_module_use()dependency bootstrap + codec-variable wiring +DCMTK_USE_ICU-honoring charset configCOMP: Export DCMTK targets through ITK's module namespaceitk_module_target()naming,ITK::<lib>aliases, build-tree targets fileCOMP: Silence DCMTK third-party compiler warningsitk_module_warnings_disable(DCMTK compiles in ITK's/W4scope)COMP: Install DCMTK libraries and headers with ITKCOMP: Build in-scope DCMTK alongside MINC on MSVCCMAKE_REQUIRED_*; assert MSVCHAVE_TMPNAMso MINC's shared-cache probe is not poisonedWhy DCMTK differs from GDCM (and why this needs FetchContent)
GDCM is
add_subdirectory()'d, so it already runs in ITK's scope and can take ITK's imported targets directly. DCMTK was anExternalProject— a separate CMake process where imported targets can't cross the boundary, forcing the$<TARGET_FILE:>+:::marshalling.FetchContent_MakeAvailableis essentially "fetch thenadd_subdirectory", which puts DCMTK in ITK's scope and removes that marshalling.EXCLUDE_FROM_ALLis intentionally not used on the in-scope DCMTK directory: it leaked into ITK's own test targets and dropped them from theALLbuild. DCMTK's libraries are required byITKIODCMTK(so they belong inALL) and DCMTK builds no apps (BUILD_APPS OFF) or tests, so nothing extraneous is added.Validation (Windows / MSVC)
install(EXPORT ITKTargets)(where install/export-set inconsistencies surface).ITKIODCMTKlinks; DCMTK libraries are ITK-named (itkdcmdata-6.0.lib…).D9025warning bleed drops to zero after the warnings commit.AI assistance
ITKIODCMTK, exit 0) before pushing.Relates to #6393, #5539; supersedes the ExternalProject approach if the team prefers FetchContent.