iLCSoft / iLCInstall

Python scripts to install iLCSoft software and dependencies
GNU General Public License v3.0
4 stars 26 forks source link

Problem finding Eigen3 #103

Closed osdesy closed 4 years ago

osdesy commented 4 years ago

Hi,

while refactoring MarlinTPC, I discovered several warnings from Eigen3, installed in /usr/include/eigen3, in the compiler output! Setting aside the question, why I get them in compiling MarlinTPC, I checked on the log of my cmake-run, which I put in attachment (cmresmod.txt), and indeed it uses the correct GBL script to find Eigen3, but this then finds the local installation instead of the afs one. This looks similar to the issue with GSL in #83, only that this time all versions seem up-to-date and fitting together:

-- GBL library version 2.2.0
-- Use FindEigen3.cmake from this GBL_DIR: /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/v02-01/GBL/V02-02-00/cmake
-- Found Eigen3: /usr/include/eigen3 (Required is at least version "2.91.0") 

Some time ago, we implemented a special switch for GBL in MarlinTPC's CMakeLists.txt, because in older versions it didn't use Eigen, but root and the version string was not filled properly. However this seems to work as intended here, as the correct GBL-version is identified. So I guess it is something in GBL's find script for Eigen3:

IF( GBL_FOUND )
    ADD_DEFINITIONS( "-DUSE_GBL" )
    #this construct to find the GBL version is neccessary since the GBL cmake package
    #currently does not export its version number variable correctly
    file(GLOB GBLLIBS "${GBL_DIR}/lib/libGBL.so*")
    STRING(REGEX REPLACE ".*so[.]([0-9]+).*" "\\1" GBLVERSIONMAJOR "${GBLLIBS}")
    STRING(REGEX REPLACE ".*so[.]([0-9]+[.][0-9]+[.][0-9]+)" "\\1" GBLLIBVERSION "${GBLLIBS}")
    MESSAGE(STATUS "GBL library version " ${GBLLIBVERSION})
    if ( GBLVERSIONMAJOR GREATER "1" )
        MESSAGE(STATUS "Use FindEigen3.cmake from this GBL_DIR: " ${GBL_DIR}/cmake)
        LIST( APPEND CMAKE_MODULE_PATH ${GBL_DIR}/cmake )
        FIND_PACKAGE(Eigen3 REQUIRED)
        ADD_DEFINITIONS( "-DGBL_EIGEN_SUPPORT_ROOT" )
        INCLUDE_DIRECTORIES( BEFORE ${ROOT_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIR} )
    ELSE()
        MESSAGE(STATUS "GBL version < 2.x, will use ROOT instead of Eigen3.")
    ENDIF()
ELSE()
    MESSAGE( STATUS "GBL not found, track fitting with GBL will not be available." )
ENDIF()

From what I get from the find script in GBL, it could also be, that the find script just refers to the default version of Eigen3 and that is fulfilled by the local installation, and that is why it doesn't bother to look in afs? As you see, we don't have a requirement on Eigen3 version from MarlinTPC. If I require version 3.3.7 (the one from afs installation), indeed cmake crashes:

-- GBL library version 2.2.0
-- Use FindEigen3.cmake from this GBL_DIR: /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/v02-01/GBL/V02-02-00/cmake
-- Eigen3 version 3.3.4 found in /usr/include/eigen3, but at least version 3.3.7 is required
CMake Error at /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/CMake/3.15.5/share/cmake-3.15/Modules/FindPackageHandleStandardArgs.cmake:137 (message):
  Could NOT find Eigen3 (missing: EIGEN3_VERSION_OK) (Required is at least
  version "3.3.7")
Call Stack (most recent call first):
/afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/CMake/3.15.5/share/cmake-3.15/Modules/FindPackageHandleStandardArgs.cmake:378 (_FPHSA_FAILURE_MESSAGE)
/afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/v02-01/GBL/V02-02-00/cmake/FindEigen3.cmake:77 (find_package_handle_standard_args)
  CMakeLists.txt:126 (FIND_PACKAGE)

-- Configuring incomplete, errors occurred!

It also still reports the policy problem CMP0074 with MarlinUtil. As the MarlinUtil_ROOT variable is set there in its MarlinUtilConfig.cmake, the policy switching to OLD or NEW should be in there, shouldn't it? I'm not sure, if that has anything to do with the Eigen3 problem, though.

Environment: I'm compiling on naf-ilc, so centos7 and using the respective installation in afs at:/afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/v02-01 There is no cvmfs version, yet, is there?

gaede commented 4 years ago

@rete how can we fix this ?

rete commented 4 years ago

The ILCSoft.cmake script in /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/v02-01 sets the CMAKE_PREFIX_PATH to a location where Eigen3 can be found, namely:

 `/afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/eigen/3.3.7/share/eigen3/cmake/`

You don't need to use the GBL FindEigen3.cmake macro for that. Find your GBL package and then the Eigen3 package:

find_package( GBL REQUIRED )
find_package( Eigen3 REQUIRED )

Can you have a try like this please?

osdesy commented 4 years ago

Yes, thanks, I will try that. First attempt at least ran through with version 3.3.7 required. However, now I have to figure out how to print that as a message to the cmake output (Version, Path). The previous methods using the script obviously don't work anymore.

rete commented 4 years ago

Eigen3 with this version uses CMake targets as the user interface. It means you have to do something like:

target_link_libraries( MarlinTPC PUBLIC Eigen3::Eigen )

This sets up include directories, library linking if any (not in this case normally) and definitions such as specific compiler flags, etc... For getting target properties, I let you refer to the CMake documentation. The properties sets by Eigen3 in /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/eigen/3.3.7/share/eigen3/cmake/Eigen3Targets.cmake, in addition to the variables defined in /afs/desy.de/project/ilcsoft/sw/x86_64_gcc82_centos7/eigen/3.3.7/share/eigen3/cmake/Eigen3Config.cmake.

osdesy commented 4 years ago

OK, thanks for the pointer. With your suggestion it works and finds the correct version - at least in ilcsoft v02-01. However, I will for the moment still use the deprecated EIGEN3_VERSION_STRING and similar variables, as Eigen3 doesn't seem to be used as a library in MarlinTPC (in contrast to the other dependencies). Only its include directories are used and I need to find out, whether this is historical legacy by now or has a deeper reason. I remember that we had to make all this extra scripting effort, because the GBL version and maybe Eigen was not found correctly in past releases. I think this can be closed a s solved for now.

rete commented 4 years ago

Even if Eigen3 has no compiled library, the CMake command:

target_link_libraries( MarlinTPC PUBLIC Eigen3::Eigen )

still applies. This a bit weird construct in this case, but Eigen3::Eigen is an imported target, so this call will just takes care of doing everything you need under the hood, namely setting up include directories for the MarlinTPC target.

osdesy commented 4 years ago

Yes, I understand, that also for such template libraries that would be the way to go. However, at the moment specifically only the include files get added and only if GBL is found in the right version. Otherwise the entire thing is left out. All other dependencies are simply added in the way you described, in a loop. Maybe that construct breaks, if simply adding Eigen3 to the list - there must have been a reason to do it in such a complicated way. As I said, some historical research and discussion with users is needed. Don't worry, refactoring CMakeList.txt is definitely on the ToDo-list. In fact a completely modernized version was already written a few years ago, just that iLCSoft didn't use the required CMake version at the time, yet, and now other things have changed, as well.