InsightSoftwareConsortium / ITKTotalVariation

External Module for Total Variation Algorithms, providing wrap for https://github.com/albarji/proxTV

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Eigen compilation problems with in-source builds

bpaniagua opened this issue · comments

Hi @phcerdan

I am getting an Eigen problem while trying to compile ITK with the module Total Variation. Shouldnt this dependency be downloaded and compiled automatically as part of the superbuild?

Thank you!
Bea

Hi @bpaniagua.
Eigen is provided/handled by ITK itself. The module just reuse it. https://github.com/InsightSoftwareConsortium/ITKTotalVariation/blob/master/CMakeLists.txt#L28-L36

Do you only have problems in Ubuntu 16.04?

Hm, I see. @thewtex what is happening!?

Yes, only in Ubuntu 16.04. Mac os 10.14 works 👍

Thank you!

@bpaniagua is ITK in the Linux build the latest and greatest? @phcerdan made Eigen magic for ITK 5. 🚀

Boo. The issue remains at configuring the ITK build, when the TV module is set to ON.

Version of ITK:

commit c376cf6bd17b07e730ee1f146c9e06846dc6aaa7
Merge: 70d5257 f071cff
Author: Matt McCormick matt.mccormick@kitware.com
Date: Wed Jul 31 18:10:21 2019 -0400

Merge pull request #1127 from thewtex/doxygen-cmake-variable

BUG: Use ITK_BUILD_DOCUMENTATION to enable Doxygen builds

Error
CMake Error at /work/Sw/ITK/ITK-build/_deps/proxtv_fetch-src/CMakeLists.txt:61 (get_target_property):
get_target_property() called with non-existent target "Eigen3::Eigen".

in the CMakeList of the external library proxTV: _deps/proxtv_fetch-src/CMakeLists.txt:61:

  find_package(Eigen3 REQUIRED)
  get_target_property(EIGEN_INCLUDE_DIR Eigen3::Eigen
    INTERFACE_INCLUDE_DIRECTORIES)
  message(STATUS "Eigen Found: ${EIGEN_INCLUDE_DIR}")

And Eigen3_DIR (used by find_package(Eigen3)) is set in the ITKTotalVariation CMakeLists.txt:
In set(Eigen3_DIR "${_internal_cmake_eigen3}/itkeigen")

if(TotalVariation_proxTV_USE_EIGEN)
  if(NOT ITK_USE_SYSTEM_EIGEN)
    # Set Eigen3_DIR to the internal ITKEigen3 module.
    set(_internal_cmake_eigen3)
    list(GET ITKEigen3_INCLUDE_DIRS 0 _internal_cmake_eigen3)
    set(Eigen3_DIR "${_internal_cmake_eigen3}/itkeigen")
  endif()
  find_package(Eigen3 REQUIRED)
  set(${PROJECT_NAME}_EXPORT_CODE_INSTALL
"${${PROJECT_NAME}_EXPORT_CODE_INSTALL}
set(Eigen3_DIR \"${Eigen3_DIR}\")
find_package(Eigen3 REQUIRED CONFIG)
")
  set(${PROJECT_NAME}_EXPORT_CODE_BUILD
"${${PROJECT_NAME}_EXPORT_CODE_BUILD}
if(NOT ITK_BINARY_DIR)
  set(Eigen3_DIR \"${Eigen3_DIR}\")
  find_package(Eigen3 REQUIRED CONFIG)
endif()
")
else()
...

I am not having problems though...
Question:

  1. Are you using system Eigen, if yes, what version?

called with non-existent target "Eigen3::Eigen".
That target exists for modern Eigens (including the one bundled in ITK...)
That's weird!

This is a long shot, but, are you on a fresh build folder of ITK? If not, could you try in a fresh one please?
Thanks @bpaniagua!

The build was freshly started this morning, after I read Matt's comment.
I aint get any fresher than that!

Haha nice, but I mean, did you rm -r ./build?. Did you provide any option to it, like using ITK_SYSTEM_EIGEN?

Yep, this is what i meant by saying "freshly started" it wasnt rm -r ./build but rm -rf * inside the build folder. :D

ITK_USE_SYSTEM_EIGEN is OFF
Module_TotalVariation is ON

Ok! Just double checking :)
Can you build with Module_TotalVariation OFF first, and then switching it on...?

I did that very thing this morning, saw that it was working, but removed the comment realizing that I hadnt set the TV module on.

So yes, I tried and it worked fine.

I can reproduce it!

It seems that the variable set in Eigen3/CMakeLists.txt:
message(WARNING "ITKEigen3_INCLUDE_DIRS: ${ITKEigen3_INCLUDE_DIRS}")

It is not available in the ITKTotalVariation/CMakeLists.txt.
Even though, the module ITKEigen3 is the list of DEPENDS of ITKTotalVariation, and that variable is in the ITKModuleMacros.cmake

@thewtex did something change in the module system lately? Or any suggestion? I will have a look at it later tomorrow.
Thanks @bpaniagua for the report!

@phcerdan outstanding analysis. Yes, that does not sound like it is behaving as expected. Is TotalVariation_proxTV_USE_EIGEN set as expected, too?

Thanks @thewtex! Yes, TotalVariation_proxTV_USE_EIGEN is set in itk-module-init.cmake:L8

Found:

# Populate module variables
if(NOT ITK_SOURCE_DIR)
  include(ITKModuleExternal)
else()
  set(ITK_DIR ${CMAKE_BINARY_DIR})
  itk_module_impl()
endif()

was called at the end of the CMake... so no modules variables were populated.
Fixing it...

I guess I would need to call twice the itk_module_impl()?
I need the variables of the DEPENDS modules.
But also I need to "save" the variables TotalVariation_INCLUDE_DIRS et al.

Is there any other way to load the variables from the the DEPENDS variables? If yes, I could call that at the beginning of the cmake.
If not, calling twice itk_module_impl() should be ok? Testing it...

Ok, I see the problem. The module is not handling correctly the case of being built internally ITK_SOURCE_DIR. Externally works good, but internally find_package(Eigen3) cannot be used, because Eigen was built internally...

    /build/Modules/ThirdParty/Eigen3/src/itkeigen/Eigen3Targets.cmake

  was generated by the export() command.  It may not be used as the argument
  to the include() command.  Use ALIAS targets instead to refer to targets by
  alternative names.

@phcerdan nice catch!

@bpaniagua I would suggest to download this module out of the ITK source and build it pointing to your current ITK build.

mkdir ITKTotalVariation; cd ITKTotalVariation
git clone https://github.com/InsightSoftwareConsortium/ITKTotalVariation src
mkdir build; cd build
ccmake ../src -DITK_DIR:PATH=/path/ITK-build

Or use an external eigen, ITK_USE_SYSTEM_EIGEN:BOOL=ON then you could build it in-source.
I will have a look at some point, but I fear this is not going to be easy to solve.

We can fork and modify proxTV and instead of using the regular #include <Eigen/xxx>, use the ITK macro for doing it... but then... well, the original idea was to avoid that approach and allow easy integration with libraries that are already using Eigen.