c++cmakeeigenvcpkgfind-package

How do I package vcpkg-imported dependencies along with my CMake library?


I have a project that uses Vcpkg to import third-party dependencies. I am building on Windows. This project has the following <my_target>-config.cmake:

include(CMakeFindDependencyMacro)

# Put dependencies here
#find_dependency(Eigen3)
find_package(Eigen3 3.4 CONFIG REQUIRED NO_MODULE)


include(${CMAKE_CURRENT_LIST_DIR}/<my_target>-targets.cmake)

When I try to consume this target via find_package(<my_target>) from another CMake project, I get the following error:

 CMake Error at path/to/<my_target>-config.cmake:9 (find_package):
        Could not find a package configuration file provided by "Eigen3" (requested
        version 3.4) with any of the following names:

          Eigen3Config.cmake
          eigen3-config.cmake

        Add the installation prefix of "Eigen3" to CMAKE_PREFIX_PATH or set
        "Eigen3_DIR" to a directory containing one of the above files.  If "Eigen3"
        provides a separate development package or SDK, be sure it has been
        installed.
      Call Stack (most recent call first):
        CMakeLists.txt:43 (find_package)


      -- Configuring incomplete, errors occurred!

Clearly, trying to grab Eigen via a find_package call in <my_target>-config.cmake doesn't do the trick. This isn't surprising, since the consumer project does not use vcpkg as part of its toolchain.

My next attempt was to add the following to the install stage of <my_target>:

install(IMPORTED_RUNTIME_ARTIFACTS Eigen3::Eigen
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

This doesn't work, as I get:

  install IMPORTED_RUNTIME_ARTIFACTS given target "Eigen3::Eigen" which is
  not an executable, library, or module.        C:\path/to/my/CMakeLists.txt

Indeed, I scoured my build directory, and couldn't actually find where the Eigen3::Eigen target gets built. I'm not sure what to make of this, but <my_target> can find and link with Eigen, no problem:

find_package(Eigen3 3.4 CONFIG REQUIRED NO_MODULE)
if (NOT Eigen3_FOUND)
    message(FATAL_ERROR "Cannot find Eigen!")
else()
    message(STATUS "Found Eigen")
    message(STATUS "Eigen imported location: ${EIGEN3_ROOT_DIR}")
endif()

So, I tried the following:

install(
    FILES $<TARGET_FILE:Eigen3::Eigen> 
    DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

But this gave me a similar error about the Eigen3::Eigen target not being found. Am I doing something silly? Without a target to even manually copy into my install directory, I have no clue how to supply Eigen, or any of my other third party dependencies, to consumers of my library.


Solution

  • So, the obvious answer here is that Eigen is a header-only library, and therefore has no target. I was confused because previously I'd been linking to the Eigen::Eigen3 target, but this was the same as just adding the proper include directories.

    Installing the Eigen headers to the correct directory using install(DIRECTORY ...) solves my problem, and find_package works just fine now.