Skip to content

ENH: Configure the ObjectFactory autoload symbol name (backport of #6787) - #6795

Merged
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:release-5.4from
hjmjohnson:backport-itkload-symbol-54
Aug 27, 2026
Merged

ENH: Configure the ObjectFactory autoload symbol name (backport of #6787)#6795
hjmjohnson merged 1 commit into
InsightSoftwareConsortium:release-5.4from
hjmjohnson:backport-itkload-symbol-54

Conversation

@hjmjohnson

@hjmjohnson hjmjohnson commented Aug 25, 2026

Copy link
Copy Markdown
Member

Backport of #6787 to release-5.4. ObjectFactoryBase looked up the autoload entry point by string literal while plugins define it by name; both now derive from ITK_LOAD_FUNCTION_NAME, configured once into itkConfigure.h. No behavior change — the default is itkLoad.

Byte-identical change set. Every added and removed line matches #6787 exactly — verified by comparing the two patches with context stripped: 53 changed lines on each side, zero differences. Both are 9 files, +39/−14. The only variation in the raw diffs is two context lines at the top-level CMakeLists.txt insertion point, because the surrounding text differs between branches (details below).

Merge after #6787. This should not land before its main counterpart.

Related work Status
main counterpart #6787
Namespace mechanism decision #6786
Slicer plugin uses the macro Slicer#9374
Slicer's fork-side patch this supersedes Slicer/ITK#14

Why release-5.4 matters: it is the branch 3D Slicer builds against. This is enabling work with no improvement today — it makes one of four names configurable so independently-distributed ITK builds can eventually coexist in one process, as PyPI itk wheels (py_itk), SimpleITK (simple_itk) and Slicer (slicer_itk). The namespace mechanism question is #6786 and is not decided here.

Equivalence with #6787, and the one legitimate difference

Comparing only added/removed lines, ignoring context and hunk headers:

main-side changed lines: 53
5.4-side  changed lines: 53
==> ACTUAL CHANGES IDENTICAL

The two raw patches differ in exactly two context lines, in the top-level CMakeLists.txt hunk:

context above the inserted block
main set(ITK_LIBRARY_NAMESPACE "ITK") / endif()
release-5.4 configure_file(CMake/ITKConfigVersion.cmake.in ...)

ITK_LIBRARY_NAMESPACE does not exist on release-5.4 — it is a main-only feature — so the cache variable lands at the structurally equivalent slot (after ITKConfigVersion, before CMAKE_INSTALL_LIBDIR) rather than beside a sibling that is not there. Context lines describe the base, not the change.

An earlier revision of this PR also carried an ITKConfig.cmake.in export; it was removed from #6787 on review (no CMake logic consumes the load symbol name) and removed here in the same pass, so ITKConfig.cmake.in is untouched by both PRs.

Reviewer note: which files a static build exercises

The plugin-facing code is only reachable with BUILD_SHARED_LIBS=ON. ITK guards both factory plugin targets behind if(ITK_BUILD_SHARED_LIBS), so 3 of the 9 changed files are compiled only in a shared build (itkFactoryTestLib.h, itkFactoryTestLib.cxx, itkFileFreeImageIOFactory.cxx), and a static build does not register itkIOPluginTest. Of the remainder, 2 are CMake and 4 compile in both configurations.

Why extern "C" needs its own mechanism

extern "C" names carry no C++ namespace, so no namespace scheme reaches this entry point:

$ nm -gU libexternc.so
__ZN3itk2v67cppFuncEv     # C++ inside `inline namespace v6` -> mangled, namespaced
_itkLoad                  # extern "C"                       -> untouched

VTK hit the same thing and ships VTK_ABI_NAMESPACE_MANGLE(x) for it.

Verification on this branch

macOS 15 arm64, Apple clang via the pixi cxx environment, Release. All four phases run against release-5.4, not inherited from #6787.

1. BUILD_SHARED_LIBS=ON, default — build clean, itkIOPluginTest PASS.

plugin export:  000000000000717c T _itkLoad

2. BUILD_SHARED_LIBS=ON, -DITK_LOAD_FUNCTION_NAME=slicer_itkLoad — build clean, itkIOPluginTest PASS.

generated:      #define ITK_LOAD_FUNCTION_NAME slicer_itkLoad
plugin export:  000000000000717c T _slicer_itkLoad

3. Validation — a value that is not a valid C identifier fails configure:

ITK_LOAD_FUNCTION_NAME must be a valid C identifier, got 'bad name'

4. BUILD_SHARED_LIBS=OFF — build clean, 5/5 ObjectFactory + itkIOPluginTest tests PASS.

release-5.4 predates .pre-commit-config.yaml, so the pre-commit run --all-files gate does not apply on this branch.

@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Core Issues affecting the Core module area:IO Issues affecting the IO module labels Aug 25, 2026
@hjmjohnson
hjmjohnson force-pushed the backport-itkload-symbol-54 branch from 23cbcb4 to 94bf629 Compare August 25, 2026 01:30
@blowekamp

Copy link
Copy Markdown
Member

In the current build/configuration of 3D Slicer this change I don't think is needed. See: Slicer/Slicer#8947 for the issue. They disabled adding the itkLoad function to the problematic ImageIO in 3DSlicer.

There is still SimpleITK and ITKPython which can try to load libraries and check for the itkLoad symbol. This can cause problems with the versions or build configuration of ITK does not match.With underlying issue reported above it is unclear to me if loading the library causes broad symbol conflict or if just creating an ITK object from the separate build.

We should consider making a more robust solution to the underlying problem. Perhaps adding a ITK version or build number automatically to the name to more broadly prevent the issue with loading itkLoad.

ObjectFactoryBase looked up the autoload entry point by string
literal while plugins defined it by name, so the two agreed only
by convention. Both now derive from ITK_LOAD_FUNCTION_NAME,
configured once into itkConfigure.h.

The name is configurable because extern "C" names carry no C++
namespace, so a build that renames ITK's symbols cannot reach this
entry point through the namespace. Setting it in the generated
header keeps the loader and every plugin consistent by
construction.

No behavior change; the default is itkLoad.

Co-Authored-By: Bradley Lowekamp <blowekamp@mail.nih.gov>
@hjmjohnson
hjmjohnson force-pushed the backport-itkload-symbol-54 branch from 328e713 to 423c834 Compare August 25, 2026 20:29
@hjmjohnson

Copy link
Copy Markdown
Member Author

In the current build/configuration of 3D Slicer this change I don't think is needed. See: Slicer/Slicer#8947 for the issue. They disabled adding the itkLoad function to the problematic ImageIO in 3DSlicer.

There is still SimpleITK and ITKPython which can try to load libraries and check for the itkLoad symbol. This can cause problems with the versions or build configuration of ITK does not match.With underlying issue reported above it is unclear to me if loading the library causes broad symbol conflict or if just creating an ITK object from the separate build.

We should consider making a more robust solution to the underlying problem. Perhaps adding a ITK version or build number automatically to the name to more broadly prevent the issue with loading itkLoad.

See larger discussion in 6787. This is an enabling set of changes that does not, by itself, provide benefits. It does, however, make future work easier and more self-contained.

@hjmjohnson
hjmjohnson marked this pull request as ready for review August 25, 2026 20:59
@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This change makes the ObjectFactory plugin entry-point name configurable while preserving itkLoad as the default. A shared build configured with ITK_LOAD_FUNCTION_NAME=slicer_itkLoad built the focused plugin targets and passed the real itkIOPluginTest autoload flow. The generated configuration header, exported plugin symbol, and runtime lookup all used the configured name consistently.

T-Rex validation blocked

An independent runtime check of the default itkLoad configuration did not complete because the separate build was interrupted by an execution time limit. The renamed-symbol flow completed successfully.

Confidence Score: 5/5

The completed shared-library plugin autoload test supports merging this change safely.

No defects remain in the review output. The configured-symbol path was exercised end to end: the generated header, plugin export, and runtime autoload behavior all agreed on slicer_itkLoad.

Files Needing Attention: No files require changes from this review. The separate default-name runtime check did not complete, while the unchanged default value remains covered by the implementation's default setting.

T-Rex T-Rex Logs

What T-Rex did

  • Built the focused shared-library targets with ITK_LOAD_FUNCTION_NAME=slicer_itkLoad, using cmake --build /tmp/itk-trex-shared --target ITKIOImageBaseTestDriver FileFreeTestLib --parallel 4, and the build completed successfully.
  • Ran ctest for the itkIOPluginTest in the shared library build, and the test passed 1 of 1 tests.
  • Inspected the generated header and plugin to verify that slicer_itkLoad is defined, the plugin exports slicer_itkLoad, and the test auto-load wiring uses that symbol.
  • Validated the exact renamed-symbol build and runtime results, including the target builds, test run output, and EXIT_CODE: 0 confirmations.
  • Noted an environment blocker labeled agent execution limit that prevented completing the default-name build and its ctest run, though it does not block the renamed-symbol validation outcome.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (1): Last reviewed commit: "ENH: Configure the ObjectFactory autoloa..." | Re-trigger Greptile

@hjmjohnson

Copy link
Copy Markdown
Member Author

This is byte-identical to @6787 backport needed for supporting both builds of Slicer.

@hjmjohnson
hjmjohnson requested a review from dzenanz August 27, 2026 13:43
@hjmjohnson
hjmjohnson merged commit 5dc13f4 into InsightSoftwareConsortium:release-5.4 Aug 27, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Core Issues affecting the Core module area:IO Issues affecting the IO module type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants