ITK
ITK copied to clipboard
ITKInternalEigen3 not installed when using CMake 3.28.0 | 3.28.1 downloaded from CMake releases (reproduced in Windows)
Build and install ITK in any configuration but make sure not to use an external/system Eigen dependency.
When any project tries to find the installed ITK, for example with find_package(ITK 5.4 REQUIRED), a CMake error occurs:
CMake Error at D:/ITK-install/lib/cmake/ITK-5.4/Modules/ITKEigen3.cmake:16 (find_package):
Could not find a package configuration file provided by "ITKInternalEigen3"
(requested version 3.3) with any of the following names:
ITKInternalEigen3Config.cmake
itkinternaleigen3-config.cmake
Add the installation prefix of "ITKInternalEigen3" to CMAKE_PREFIX_PATH or
set "ITKInternalEigen3_DIR" to a directory containing one of the above
files. If "ITKInternalEigen3" provides a separate development package or
SDK, be sure it has been installed.
Call Stack (most recent call first):
D:/ITK-install/lib/cmake/ITK-5.4/ITKModuleAPI.cmake:86 (include)
D:/ITK-install/lib/cmake/ITK-5.4/ITKModuleAPI.cmake:31 (itk_module_load)
D:/ITK-install/lib/cmake/ITK-5.4/ITKModuleAPI.cmake:143 (_itk_module_config_recurse)
D:/ITK-install/lib/cmake/ITK-5.4/ITKConfig.cmake:88 (itk_module_config)
CMakeLists.txt:5 (find_package)
The <INSTALL_DIR>/lib/cmake/ITK-5.4/Modules directory contains an ITKEigen3.cmake file, with the following content at the end:
set(ITK_USE_SYSTEM_EIGEN "OFF")
set(ITKInternalEigen3_DIR "${ITK_MODULES_DIR}")
find_package(ITKInternalEigen3 3.3 REQUIRED CONFIG)
However, ITKInternalEigen3 is not installed by ITK and only present in the build directory.
We have this issue in MITK and it was reported by users multiple times already until we noticed it ourselves. Even in a minimal scenario by building and installing "default" ITK and a demo project like the following, the error is reproducible:
cmake_minimum_required(VERSION 3.16.3...3.19.7) # Same as ITK
project(demo)
find_package(ITK 5.4 REQUIRED)
Thanks for raising this up. I cannot reproduce it locally in Linux.
In Linux <INSTALL_DIR>/lib/cmake/ITK-5.4/Modules contains the ITKInternalEigen cmake files:
ITKInternalEigen3Config.cmake
ITKInternalEigen3ConfigVersion.cmake
ITKInternalEigen3Targets.cmake
And ITKInternalEigen3Targets.cmake points to the installed headers in <INSTALL_DIR>/include/ITK-5.4/itkeigen/Eigen/xx
Let me check in Windows, the CMake logic should be the same though.
Cannot reproduce in Windows either with master ITK, nor with v5.4rc02. All the files are there, and the demo project configures ok.
Maybe something specific to MITK?
Thanks for checking. I also reproduced it completely independent from MITK. Did you do clean builds from scratch? If it works for you with v5.4-rc02 maybe the only difference is the CMake version. I used the latest v3.28.1.
build from scratch
cmake.exe --version
3.23.2
Let me try with latest...
Ok, I can reproduce it with v3.28.1 in Windows
I tried also with CMake v3.27.9 and v3.28.0 and both work. So something broke in CMake v3.28.1 I guess. I can even use CMake v3.28.1 in my own project as long as ITK was built and installed with CMake <= v3.28.0.
Good narrowing, I will have a look tomorrow. Pinging @mathstuf in case he can help from the top of his head on the changes from 3.28.0 to 3.28.1 that broke the installation of a module (thanks!).
Nothing relevant from the diff of CMake v3.28.1 versus v3.28.0 that I can see...
Sorry I messed up my bisecting last night I guess. Had the same issue with v3.28.0 today after downgrading my installed version of CMake. I don't know what happened yesterday with the portable versions of CMake. At least I can now 100% confirm that v3.27.9 works, and starting with v3.28.0 it doesn't. Is also makes more sense that there's such a difference between two minor versions instead of patch versions.
Reading the CMake v3.28 release notes, nothing really seems to be related to this issue. Maybe the following item but that's a wild guess:
Generated files, in targets using File Sets, are now considered private by default. Generated public headers must be specified using file sets. This allows Ninja Generators to produce more efficient build graphs. See policy CMP0154.
No, that change only affects build time. I'll take a look here.
3.28.0 with a minimal build on Windows and Linux both install what seem to be the correct file:
> c:\Users\ben.boeckel\code\cmake\build\bin\cmake.exe -GNinja ..\src -DCMAKE_INSTALL_PREFIX=c:/Users/ben.boeckel/code/itk/build/install -DITK_BUILD_DEFAULT_MODULES=OFF -DENABLE_TESTING=OFF -DModule_ITKEigen3=ON -DWITH_GTEST=OFF -DZLIBNG_ENABLE_TESTS=OFF -DITKGroup_Core=OFF --fresh
> ninja install
> dir install\lib\ITK-5.4\Modules
…
01/18/2024 09:37 AM 876 ITKInternalEigen3Config.cmake
01/18/2024 09:37 AM 2,827 ITKInternalEigen3ConfigVersion.cmake
01/18/2024 09:37 AM 4,320 ITKInternalEigen3Targets.cmake
…
Is there something wrong with my configure that it is working here?
Good that it works when only building the module.
I tested with cmake v3.28.1 and just BUILD_TESTING=OFF. The core module depends on the module Eigen3, so it should be pulled along.
cmake.exe ..\src -DCMAKE_INSTALL_PREFIX=\path\install2 -DBUILD_TESTING=OFF --fresh
cmake.exe --build . --target install
I am re-building with this setting as I write this, just in case.
The generator in my case was Visual Studio 16 2019
MSVC 19.29.30146.0
And yes I can still reproduce it:
ls install2/lib/cmake/ITK-5.4/Modules | grep -i Eigen
ITKEigen3.cmake
ITKEigen.cmake
But no ITKInternalEigen3
With your setting except -GNinja, I don't get installed the ITKInternalEigen3 either, I only get ITKEigen3.cmake.
Tested with -GNinja as well, and ninja install, and no ITKInternalEigen3 either.
Is it somewhere else in the install tree?
Is it somewhere else in the install tree?
No
cmake.exe -GNinja ..\src -DCMAKE_INSTALL_PREFIX=\path\install2 -DBUILD_TESTING=OFF
This configure ended up working for me. Will try Visual Studio next.
Other things to investigate on your side in the meantime:
- can you find an install rule for it? (i see it under
ITKInternalEigen3-build/cmake_install.cmake) - does a second install put the file into place (in case something in the install later removes it)
- does
cmake -P ITKInternalEigen3-build/cmake_install.cmakeinstall the file?
cmake.exe ..\src -DCMAKE_INSTALL_PREFIX=\path\install2 -DBUILD_TESTING=OFF
This, using the Visual Studio generator also ends up with files installed properly. Can you please check whether the ITKInternalEigen3-build/cmake_install.cmake code has a reference to these files at all?
ITKInternalEigen3-buil/cmake_install.cmake:
# Install script for directory: C:/Users/Pablo/Software/ITK/src/Modules/ThirdParty/Eigen3/src/itkeigen
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "C:/Users/Pablo/Software/ITK/install3_no_default_only_eigen_ninja")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "Debug")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/Eigen3Targets.cmake")
file(DIFFERENT _cmake_export_file_changed FILES
"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/Eigen3Targets.cmake"
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/CMakeFiles/Export/95419ec2725e671d91b6d99f9f2bf62b/Eigen3Targets.cmake")
if(_cmake_export_file_changed)
file(GLOB _cmake_old_config_files "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/Eigen3Targets-*.cmake")
if(_cmake_old_config_files)
string(REPLACE ";" ", " _cmake_old_config_files_text "${_cmake_old_config_files}")
message(STATUS "Old export file \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/Eigen3Targets.cmake\" will be replaced. Removing files [${_cmake_old_config_files_text}].")
unset(_cmake_old_config_files_text)
file(REMOVE ${_cmake_old_config_files})
endif()
unset(_cmake_old_config_files)
endif()
unset(_cmake_export_file_changed)
endif()
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules" TYPE FILE FILES "C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/CMakeFiles/Export/95419ec2725e671d91b6d99f9f2bf62b/Eigen3Targets.cmake")
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules" TYPE FILE FILES
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/Eigen3Config.cmake"
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/Eigen3ConfigVersion.cmake"
)
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/ITK-5.4/itkeigen/Eigen" TYPE DIRECTORY FILES "C:/Users/Pablo/Software/ITK/src/Modules/ThirdParty/Eigen3/src/itkeigen/Eigen/" REGEX "/[^/]*\\.txt$" EXCLUDE)
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
if(EXISTS "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/ITKInternalEigen3Targets.cmake")
file(DIFFERENT _cmake_export_file_changed FILES
"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/ITKInternalEigen3Targets.cmake"
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/CMakeFiles/Export/95419ec2725e671d91b6d99f9f2bf62b/ITKInternalEigen3Targets.cmake")
if(_cmake_export_file_changed)
file(GLOB _cmake_old_config_files "$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/ITKInternalEigen3Targets-*.cmake")
if(_cmake_old_config_files)
string(REPLACE ";" ", " _cmake_old_config_files_text "${_cmake_old_config_files}")
message(STATUS "Old export file \"$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules/ITKInternalEigen3Targets.cmake\" will be replaced. Removing files [${_cmake_old_config_files_text}].")
unset(_cmake_old_config_files_text)
file(REMOVE ${_cmake_old_config_files})
endif()
unset(_cmake_old_config_files)
endif()
unset(_cmake_export_file_changed)
endif()
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules" TYPE FILE FILES "C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/CMakeFiles/Export/95419ec2725e671d91b6d99f9f2bf62b/ITKInternalEigen3Targets.cmake")
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Unspecified" OR NOT CMAKE_INSTALL_COMPONENT)
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules" TYPE FILE FILES
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/ITKInternalEigen3Config.cmake"
"C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/ITKInternalEigen3ConfigVersion.cmake"
)
endif()
if(CMAKE_INSTALL_COMPONENT)
set(CMAKE_INSTALL_MANIFEST "install_manifest_${CMAKE_INSTALL_COMPONENT}.txt")
else()
set(CMAKE_INSTALL_MANIFEST "install_manifest.txt")
endif()
string(REPLACE ";" "\n" CMAKE_INSTALL_MANIFEST_CONTENT
"${CMAKE_INSTALL_MANIFEST_FILES}")
file(WRITE "C:/Users/Pablo/Software/ITK/build/ITKInternalEigen3-build/${CMAKE_INSTALL_MANIFEST}"
"${CMAKE_INSTALL_MANIFEST_CONTENT}")
Will try the other two suggestions.
It's being installed by that script at least. Something else seems to be interfering. Can you save off the install logs and see if got installed at one point and maybe some other install script wiped the directory afterwards?
Any update here?
Any update here?
I've been swamped, trying now.
can you find an install rule for it? (i see it under ITKInternalEigen3-build/cmake_install.cmake)
Yes
does a second install put the file into place (in case something in the install later removes it)
No
does cmake -P ITKInternalEigen3-build/cmake_install.cmake install the file
Yes!
does cmake -P ITKInternalEigen3-build/cmake_install.cmake install the file Yes!
Is there any .cmake script that controls the execution of that comand? To have a look...
The .cmake file in build/Modules/ThirdParty/Eigen3/cmake_install.cmake is missing reference to the install script of internal module.
# Install script for directory: C:/Users/Pablo/Software/ITK/src/Modules/ThirdParty/Eigen3
# Set the install prefix
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "C:/Users/Pablo/Software/ITK/install3_no_default_only_eigen_ninja")
endif()
string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
# Set the install configuration name.
if(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
if(BUILD_TYPE)
string(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
else()
set(CMAKE_INSTALL_CONFIG_NAME "Release")
endif()
message(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
endif()
# Set the component getting installed.
if(NOT CMAKE_INSTALL_COMPONENT)
if(COMPONENT)
message(STATUS "Install component: \"${COMPONENT}\"")
set(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
else()
set(CMAKE_INSTALL_COMPONENT)
endif()
endif()
# Is this installation the result of a crosscompile?
if(NOT DEFINED CMAKE_CROSSCOMPILING)
set(CMAKE_CROSSCOMPILING "FALSE")
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Development" OR NOT CMAKE_INSTALL_COMPONENT)
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/ITK-5.4/Modules" TYPE FILE FILES "C:/Users/Pablo/Software/ITK/build/Modules/ThirdParty/Eigen3/CMakeFiles/ITKEigen3.cmake")
endif()
if(CMAKE_INSTALL_COMPONENT STREQUAL "Development" OR NOT CMAKE_INSTALL_COMPONENT)
file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/include/ITK-5.4" TYPE FILE FILES "C:/Users/Pablo/Software/ITK/build/Modules/ThirdParty/Eigen3/src/itk_eigen.h")
endif()
Having a look at the macro itk_module_impl, which is controlling the cmake installation of the module:
From https://github.com/InsightSoftwareConsortium/ITK/issues/4407#issuecomment-1898120975:
At least I can now 100% confirm that v3.27.9 works, and starting with v3.28.0 it doesn't.
@kislinsk @phcerdan please try building CMake from source and git bisect between those two versions to get the exact commit in CMake that caused this. One can run bin/cmake right out of the CMake build tree without installing it. That may be easier than trying to directly debug the problem.
ITK Version fixed on: v5.4rc02
Build CMake with:
cmake.exe ../src --fresh
cmake.exe --build .
# Other versions with
cmake.exe --build . --config MinSizeRel
Build and install ITK with:
C:\Users\Pablo\Software\CMake\build\bin\Debug\cmake.exe ../src -DCMAKE_INSTALL_PREFIX=install -DBUILD_TESTING=OFF -DITK_BUILD_DEFAULT_MODULES=OFF -DModule_ITKEigen3=ON -DITKGroup_Core=OFF --fresh
C:\Users\Pablo\Software\CMake\build\bin\Debug\cmake.exe --build . --target install
Checking installation of ITK with CMake v3.27.9: GOOD
ls .\install\lib\cmake\ITK-5.4\Modules\
-a---- 26/01/2024 11:47 1300 Eigen3Config.cmake
-a---- 26/01/2024 11:47 2824 Eigen3ConfigVersion.cmake
-a---- 26/01/2024 11:47 4216 Eigen3Targets.cmake
-a---- 26/01/2024 11:47 616 ITKEigen3.cmake
-a---- 26/01/2024 11:47 1311 ITKInternalEigen3Config.cmake
-a---- 26/01/2024 11:47 2824 ITKInternalEigen3ConfigVersion.cmake
-a---- 26/01/2024 11:47 4320 ITKInternalEigen3Targets.cmake
Checking installation of ITK with CMake v3.28.0: GOOD in CMake --config Debug (default). GOOD with CMake --config Release, GOOD with --config MinSizeRel
Everything good when building CMake from source, but I still get the issue when using the downloaded cmake binary v3.28.1
@mathstuf, could you test with the packaged 3.28.1 please (I haven't tried 3.28.0, but assuming the same issue)?