Skip to content

COMP: Expose itkeigen subdir in ITKEigen3_INCLUDE_DIRS for external consumers#6223

Merged
hjmjohnson merged 1 commit intoInsightSoftwareConsortium:mainfrom
hjmjohnson:eigen-include-itkeigen-path
May 6, 2026
Merged

COMP: Expose itkeigen subdir in ITKEigen3_INCLUDE_DIRS for external consumers#6223
hjmjohnson merged 1 commit intoInsightSoftwareConsortium:mainfrom
hjmjohnson:eigen-include-itkeigen-path

Conversation

@hjmjohnson
Copy link
Copy Markdown
Member

@hjmjohnson hjmjohnson commented May 6, 2026

Add ${ITKEigen3_SOURCE_DIR}/src/itkeigen to ITKEigen3_INCLUDE_DIRS so external consumers using the upstream Eigen include convention (<Eigen/<header>>) resolve against the vendored Eigen via ITK's IMPORTED targets — currently they get fatal error: Eigen/Dense: No such file or directory. Unblocks InsightSoftwareConsortium/ITKTotalVariation # 57's modern-target-interfaces refactor for proxTV. Independent of and complementary to #6176 (the Eigen 5 update); the architecture issue predates that PR.

Root cause

ITK ships its vendored Eigen3 headers at:

Modules/ThirdParty/Eigen3/src/itkeigen/Eigen/<header>

ITK's own internal code uses ITK_EIGEN(<header>) from itk_eigen.h, which expands to <itkeigen/Eigen/<header>>. With include path ${ITKEigen3_SOURCE_DIR}/src (the parent of itkeigen/), the compiler appends /itkeigen/Eigen/<header> and resolves correctly. ITK proper has always built fine.

Modules/ThirdParty/Eigen3/CMakeLists.txt:58 (vendored case, before this PR):

set(ITKEigen3_INCLUDE_DIRS ${ITKEigen3_SOURCE_DIR}/src)

That single path flowed into INTERFACE_INCLUDE_DIRECTORIES of both ITK::ITKEigen3Module and ITK::eigen_internal. External consumers using the upstream <Eigen/<header>> convention got the wrong root and failed to resolve. The Eigen3::Eigen IMPORTED target produced by Eigen's own export does have the correct path, but it's declared as add_library(Eigen3::Eigen ALIAS eigen) — an in-source-scope alias, invisible to FetchContent sub-builds (verified empirically).

Fix

Single-block change to Modules/ThirdParty/Eigen3/CMakeLists.txt:58:

-  set(ITKEigen3_INCLUDE_DIRS ${ITKEigen3_SOURCE_DIR}/src)
+  set(
+    ITKEigen3_INCLUDE_DIRS
+    ${ITKEigen3_SOURCE_DIR}/src
+    ${ITKEigen3_SOURCE_DIR}/src/itkeigen
+  )

ITK's own <itkeigen/Eigen/<header>> consumers continue to find their headers via the first entry. External consumers using <Eigen/<header>> find theirs via the second. Both flow into INTERFACE_INCLUDE_DIRECTORIES of the IMPORTED ITK::ITKEigen3Module so the fix applies in-tree and to find_package(ITK) consumers identically.

Local verification

Full ITK build with Module_TotalVariation=ON pinned at ITKTotalVariation # 57's tip (39e849e, which previously failed lapackFunctionsWrap.cpp:11:10: fatal error: Eigen/Dense: No such file or directory):

Step Result
Configure (ITK_BUILD_DEFAULT_MODULES=ON, Module_TotalVariation pinned at PR # 57 tip) ✅ clean
Build ninja -j16 6165/6165 targets, 0 failures
libitkproxTV-6.0.so produced
bin/TotalVariationTestDriver linked
ctest -R ProxTV itkProxTVImageFilterTest passes
lapackFunctionsWrap.cpp.o compile flags include -isystem .../Eigen3/src/itkeigen ✅ (the vendored path resolves <Eigen/Dense>)
Compile flags do not include -isystem /usr/include/eigen3 ✅ (no longer falling back to system Eigen)

Compile-commands receipt for lapackFunctionsWrap.cpp:

-I/tmp/itk-eigen-include-fix-build/_deps/proxtv_fetch-src/src
-I.../Eigen3/src
-I.../build/Modules/ThirdParty/Eigen3/src
-isystem .../Eigen3/src/itkeigen        ← the new include dir from this PR
Relationship to other PRs

…onsumers

ITK ships its vendored Eigen3 headers at
  Modules/ThirdParty/Eigen3/src/itkeigen/Eigen/<header>

ITK code accesses these via the ITK_EIGEN(<header>) macro
defined in itk_eigen.h, which expands to
  <itkeigen/Eigen/<header>>

When ITK_USE_SYSTEM_EIGEN=OFF, the prior ITKEigen3_INCLUDE_DIRS
contained only ${ITKEigen3_SOURCE_DIR}/src — sufficient for the
macro form (the compiler then appends /itkeigen/Eigen/<header>) but
not for the upstream Eigen convention <Eigen/<header>>, which needs
${ITKEigen3_SOURCE_DIR}/src/itkeigen on the include path.

External consumers that legitimately use the upstream pattern hit
'fatal error: Eigen/Dense: No such file or directory' as soon as
they link against ITK::ITKEigen3Module or ITK::eigen_internal.
This blocks the modern-target-interfaces refactor in
InsightSoftwareConsortium/ITKTotalVariation#57: proxTV's
lapackFunctionsWrap.cpp uses #include <Eigen/Dense> and so cannot
build against the vendored Eigen via either of ITK's exported
imported targets.

Add the itkeigen subdirectory to ITKEigen3_INCLUDE_DIRS so both
include conventions resolve.  ITK's own consumers continue to find
<itkeigen/Eigen/<header>> via the first entry; external consumers
now find <Eigen/<header>> via the second.  Both entries flow into
INTERFACE_INCLUDE_DIRECTORIES of the IMPORTED ITK::ITKEigen3Module
target, so the fix applies in-tree and to find_package(ITK)
consumers alike.

The Eigen3::Eigen IMPORTED target produced by Eigen's own export
already exposes the correct path, but it is in-source-scope only
(declared as add_library(Eigen3::Eigen ALIAS eigen)) and therefore
invisible to FetchContent sub-builds; relying on it is not an
option for downstream remote modules that pull proxTV via
FetchContent.

This change is independent of the Eigen 5 vendored update in
PR InsightSoftwareConsortium#6176; the architectural mismatch predates that PR and applies
to upstream/main as-is.
@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 May 6, 2026
@dzenanz dzenanz requested a review from blowekamp May 6, 2026 19:06
@hjmjohnson hjmjohnson marked this pull request as ready for review May 6, 2026 19:12
@greptile-apps

This comment was marked as resolved.

Comment thread Modules/ThirdParty/Eigen3/CMakeLists.txt
@hjmjohnson
Copy link
Copy Markdown
Member Author

Tracking issue for the SYSTEM-include macro cleanup is now open: #6224 — captures the macro-plumbing diagnosis, the three approaches in increasing scope, and the recommended sequencing (investigate the existing eigen_internal SYSTEM INTERFACE first; only touch ITKModuleMacros.cmake if needed).

@hjmjohnson hjmjohnson merged commit 1976a3a into InsightSoftwareConsortium:main May 6, 2026
16 of 18 checks passed
# ${ITKEigen3_SOURCE_DIR}/src uses the macro form; external
# consumers (proxTV, anything else that includes Eigen the
# standard way) need the parent of <Eigen/X>, which is
# ${ITKEigen3_SOURCE_DIR}/src/itkeigen.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This comment is too long, and not efficient for humans to understand.

@blowekamp
Copy link
Copy Markdown
Member

PR #57 was not blocked because of a compilation error it was blocked because of incompatible ITK versioning infrastructure.

@seanm
Copy link
Copy Markdown
Contributor

seanm commented May 7, 2026

I haven't bisected yet, but looking at what changed in ITK since yesterday, I suspect this change broke my build:

In file included from /some/path/ITK-install/include/ITK/itkAffineTransform.h:21:
In file included from /some/path/ITK-install/include/ITK/itkMatrixOffsetTransformBase.h:24:
In file included from /some/path/ITK-install/include/ITK/itkTransform.h:24:
In file included from /some/path/ITK-install/include/ITK/itkSymmetricSecondRankTensor.h:29:
/some/path/ITK-install/include/ITK/itkSymmetricEigenAnalysis.h:23:10: fatal error: 'itkeigen/Eigen/Eigenvalues' file not found
#include ITK_EIGEN(Eigenvalues)
         ^~~~~~~~~~~~~~~~~~~~~~

@seanm
Copy link
Copy Markdown
Contributor

seanm commented May 7, 2026

Bisect results:

There are only 'skip'ped commits left to test.
The first bad commit could be any of:
bc87d16
64ddc66
We cannot bisect more!

@seanm
Copy link
Copy Markdown
Contributor

seanm commented May 7, 2026

So in fact it was MR #6176 I'll move comments there...

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.

4 participants