c++visual-studiocmaketargeteigen3

How to prevent Eigen targets to show up in the main app in a CMake project


I have a CMake project with the following top level CMakeLists.txt.

cmake_minimum_required(VERSION 3.24)
project(myapp VERSION 1.0.0)

add_subdirectory(external/eigen)

add_executable(myapp)
target_sources(myapp PRIVATE src/main.cpp)
target_link_libraries(myapp PUBLIC Eigen3::Eigen)

external/eigen/CMakeLists.txt is defined as follows.

cmake_minimum_required(VERSION 3.24)
project(libeigen VERSION 1.0.0)

FetchContent_Declare(eigen
        GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git)
FetchContent_MakeAvailable(eigen)
cmake_print_variables(eigen_SOURCE_DIR eigen_BINARY_DIR)

set(EIGEN_BUILD_DOC OFF)
# note: To disable eigen tests,
# you should put this code in a add_subdirectory to avoid to change
# BUILD_TESTING for your own project too since variables are directory
# scoped
set(BUILD_TESTING OFF)
set(EIGEN_BUILD_PKGCONFIG OFF)
set( OFF)

I am using Visual Studio to build the project. All the eigen targets show up in the Target View of the Solution Explorer. There are so many of them and it is difficult to find the main app target.

enter image description here

Is there any way to prevent the Eigen targets to show up in the main app?


Solution

  • Per Getting Started

    the header files in the Eigen subdirectory are the only files required to compile programs using Eigen... It is not necessary to use CMake or install anything.

    I.e. you don't really want FetchContent to do anything apart from bring the files in. I "hack" FetchContent_Declare using SOURCE_SUBDIR to tell it to look for a CMakeLists.txt where there isn't one, bypassing the configure stage.

    FetchContent_Declare(Eigen3 SYSTEM
        GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
        GIT_TAG 3147391d946bb4b6c68edd901f2add6ac1f31f8c # 3.4.0
        GIT_SHALLOW TRUE
        SOURCE_SUBDIR cmake) # no CMakeLists.txt in cmake, so this turns off configure
    # Recommend also add `FIND_PACKAGE_ARGS CONFIG` so that FetchContent checks to see if Eigen is installed on the system, via the o/s, or a package manager
    
    FetchContent_MakeAvailable(Eigen3)
    
    if(NOT TARGET Eigen3::Eigen)
        add_library(Eigen3::Eigen INTERFACE IMPORTED)
        set_target_properties(Eigen3::Eigen PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${eigen3_SOURCE_DIR})
    endif()
    

    You can put this in your top-level CMakeLists.txt. Note, best to use an SHA to fix the code you're getting, and shallow clone as you're not interested in the history.

    Better still would be to use a package manager, such as vcpkg or conan, as recommended in the comments. The way this is set up, your CMake code can stay the same if you use a package manager. (You can just add the FIND_PACKAGE_ARGS CONFIG args so FetchContent preferentially brings in an already-installed Eigen rather than going to gitlab.)

    (An issue with eigen 3.4.0, used above, is that the code to check whether the project is top-level is not yet released. However it looks like you're getting latest, so I'm a little puzzled as to why you're still seeing all those eigen targets. I don't use Visual Studio so can't check.)