How to use FetchContent_Populate with Eigen?

3.1k Views Asked by At

I want to use FetchContent to automatically manage the dependency to Eigen for my project, which works in general. However, when using the recommended method of FetchContent_Declare() and FetchContent_MakeAvailable() a subsequent call to install also installs all Eigen headers and documentation which is not necessary in my case.

To circumvent this behavior, I tried the method suggested in this answer: Disable install for FetchContent

FetchConten_Populate() however fails to fill the variables ${Eigen_SOURCE_DIR} and ${Eigen_BIN_DIR} (which the documentation told me should happen) so that I cannot call add_subdirectory().

Here is a minimal CMakeLists.txt:

cmake_minimum_required (VERSION 3.12)

project (FetchContentExample)

include (FetchContent)

FetchContent_Declare(
  Eigen
  GIT_REPOSITORY https://gitlab.com/libeigen/eigen.git
  GIT_TAG        3.4.0
)

FetchContent_GetProperties(Eigen)
if(NOT Eigen_POPULATED)
  FetchContent_Populate(Eigen)

  message("SRC; ${Eigen_SOURCE_DIR}") # Apparently empty?
  message("BIN: ${Eigen_BINARY_DIR}") # Apparently empty?

  add_subdirectory(${Eigen_SOURCE_DIR} ${Eigen_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()

add_executable(FetchContentExample
  main.cpp
)

target_link_libraries (FetchContentExample
  PRIVATE
  Eigen3::Eigen
)

install(
  TARGETS FetchContentExample
  DESTINATION ${CMAKE_INSTALL_BINDIR}
  COMPONENT Runtime
)

The same setup works fine when I use e.g.

FetchContent_Declare(
  fmt
  GIT_REPOSITORY https://github.com/fmtlib/fmt.git
  GIT_TAG        5.3.0
)

instead of Eigen. What specifically am I doing wrong when it comes to Eigen?

1

There are 1 best solutions below

0
On BEST ANSWER

FetchContent_Populate() however fails to fill the variables ${Eigen_SOURCE_DIR} and ${Eigen_BINARY_DIR} (which the documentation told me should happen).

Actually, FetchContent fills variables ${eigen_SOURCE_DIR} and ${eigen_BINARY_DIR} which names are constructed from the lowercase variant of the project's name. This is written in the documentation:

FetchContent_Populate() will set three variables in the scope of the caller:

<lowercaseName>_POPULATED This will always be set to TRUE by the call.

<lowercaseName>_SOURCE_DIR The location where the populated content can be found upon return.

<lowercaseName>_BINARY_DIR A directory intended for use as a corresponding build directory.

So the correct sequence of commands for EXCLUDE_FROM_ALL inclusion of Eigen would be:

FetchContent_GetProperties(Eigen)
if(NOT eigen_POPULATED)
  FetchContent_Populate(Eigen)

  add_subdirectory(${eigen_SOURCE_DIR} ${eigen_BINARY_DIR} EXCLUDE_FROM_ALL)
endif()