ITK icon indicating copy to clipboard operation
ITK copied to clipboard

ITKInternalEigen3 not installed when using CMake 3.28.0 | 3.28.1 downloaded from CMake releases (reproduced in Windows)

Open kislinsk opened this issue 1 year ago • 41 comments

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.

kislinsk avatar Jan 17 '24 17:01 kislinsk

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)

kislinsk avatar Jan 17 '24 17:01 kislinsk

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.

phcerdan avatar Jan 17 '24 18:01 phcerdan

Cannot reproduce in Windows either with master ITK, nor with v5.4rc02. All the files are there, and the demo project configures ok.

phcerdan avatar Jan 17 '24 20:01 phcerdan

Maybe something specific to MITK?

phcerdan avatar Jan 17 '24 20:01 phcerdan

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.

kislinsk avatar Jan 17 '24 22:01 kislinsk

build from scratch

cmake.exe --version
3.23.2

Let me try with latest...

phcerdan avatar Jan 17 '24 22:01 phcerdan

Ok, I can reproduce it with v3.28.1 in Windows

phcerdan avatar Jan 17 '24 22:01 phcerdan

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.

kislinsk avatar Jan 18 '24 00:01 kislinsk

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!).

phcerdan avatar Jan 18 '24 00:01 phcerdan

Nothing relevant from the diff of CMake v3.28.1 versus v3.28.0 that I can see...

phcerdan avatar Jan 18 '24 09:01 phcerdan

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.

kislinsk avatar Jan 18 '24 09:01 kislinsk

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.

kislinsk avatar Jan 18 '24 09:01 kislinsk

No, that change only affects build time. I'll take a look here.

mathstuf avatar Jan 18 '24 13:01 mathstuf

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?

mathstuf avatar Jan 18 '24 14:01 mathstuf

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

phcerdan avatar Jan 18 '24 16:01 phcerdan

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.

phcerdan avatar Jan 18 '24 16:01 phcerdan

Is it somewhere else in the install tree?

mathstuf avatar Jan 18 '24 21:01 mathstuf

Is it somewhere else in the install tree?

No

phcerdan avatar Jan 18 '24 22:01 phcerdan

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.cmake install the file?

mathstuf avatar Jan 19 '24 12:01 mathstuf

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?

mathstuf avatar Jan 19 '24 22:01 mathstuf

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.

phcerdan avatar Jan 20 '24 01:01 phcerdan

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?

mathstuf avatar Jan 20 '24 21:01 mathstuf

Any update here?

mathstuf avatar Jan 25 '24 12:01 mathstuf

Any update here?

I've been swamped, trying now.

phcerdan avatar Jan 25 '24 13:01 phcerdan

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!

phcerdan avatar Jan 25 '24 14:01 phcerdan

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...

phcerdan avatar Jan 25 '24 14:01 phcerdan

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()


phcerdan avatar Jan 25 '24 14:01 phcerdan

Having a look at the macro itk_module_impl, which is controlling the cmake installation of the module:

phcerdan avatar Jan 25 '24 14:01 phcerdan

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.

bradking avatar Jan 25 '24 20:01 bradking

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)?

phcerdan avatar Jan 26 '24 11:01 phcerdan