Search code examples
c++c++11cmakeeigen3

Avoid CMake subcommand after ExternalProject is already installed


The project that I'm working on has a dependency on Eigen3. Previously, I was just having the end user specify the path to the Eigen3 headers manually during the configure step, but this has become cumbersome, and I'd like to take some of that responsibility off the user. I've set up a CMake External project to grab the HG repository via:

message( STATUS "Looking for Eigen3 ")
find_package(Eigen3)
if(EIGEN3_FOUND)
  message( STATUS "Looking for Eigen3 - found!")
else()
  find_file(EIGEN3_IN_DEPS Eigen/Core ${PROJECT_BINARY_DIR}/deps/include/eigen3)
  if(NOT EIGEN3_IN_DEPS)
    message( STATUS "Looking for Eigen3 - not found!")
    ExternalProject_Add(eigen3
      PREFIX "${PROJECT_BINARY_DIR}/deps/eigen3"
      HG_REPOSITORY "https://bitbucket.org/eigen/eigen"
      CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/deps"
      "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
      "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
      UPDATE_DISCONNECTED 1)
  endif()
endif()

The problem I'm having is that now my CMake generated Makefile always runs the Eigen3 configure step every time I recompile my problem. Granted, this is not generally a problem for the end user, only developers. I'd rather not have to wait for this configure every time I recompile, is there a way to specify that the only time I should try to configure Eigen3 from the HG Repo is the initial build?


Solution

  • An obvious if less-than-ideal answer: run CMake again. The 1st time you run CMake and build, Eigen3 will be fetched, configured and built. When running CMake a 2nd time, find_package will locate Eigen3 and the resulting Makefile won't need to configure and build Eigen3. This assumes ExternalProject_Add puts Eigen3 in a place it will be found by find_package, which can be accomplished by adding the Eigen3 prefix to your CMAKE_PREFIX_PATH following these guidelines.

    Although I cringe at a "run it again" answer, it's not so bad in this case. Running cmake a second time isn't required and your build will always work the first time as expected. The second invocation would be an optimization.