Create config file for CMake project

大城市里の小女人 提交于 2021-02-10 15:10:19

问题


I am trying to generate a config CMake file for a sample project I have. My example is made of two CMake projects: a library, which uses spdlog internally and eigen in its interface and an application, which uses the library. The idea is to learn how to create a Config.cmake file so the application can find the library. This is what I have:

cmake_minimum_required(VERSION 3.16)
project(tutorial-4 CXX)

set(CMAKE_CXX_STANDARD 14)

find_package(Eigen3 REQUIRED)

set(LIBRARY_SOURCES
    Lib/lib.cpp)

set(LIBRARY_HEADERS
    Lib/lib.h)

add_library(smalllib-4
    SHARED
    ${LIBRARY_SOURCES}
    ${LIBRARY_HEADERS}
    )

find_package(spdlog REQUIRED)
find_package(Eigen3 REQUIRED)

target_link_libraries(smalllib-4
    PRIVATE spdlog::spdlog
    PUBLIC Eigen3::Eigen)

target_include_directories(smalllib-4 PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  $<INSTALL_INTERFACE:include>
)

set_target_properties(smalllib-4 PROPERTIES PUBLIC_HEADER ${LIBRARY_HEADERS})

install(TARGETS smalllib-4
        EXPORT smalllib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib/static
        PUBLIC_HEADER DESTINATION include/Lib)

install(EXPORT smalllib NAMESPACE smalllib:: DESTINATION share/smalllib)
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/smalllibConfig.cmake
    INSTALL_DESTINATION share/smalllib
    )

install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/smalllibConfig.cmake
    DESTINATION share/smalllib
    )

This generates succesfuly a smalllibConfig.cmake, but when I try to do find_package(smalllib REQUIRED), I get the following error:

CMake Error at CMakeLists.txt:10 (add_executable):
  Target "smallapp" links to target "Eigen3::Eigen" but the target was not
  found.  Perhaps a find_package() call is missing for an IMPORTED target, or
  an ALIAS target is missing?

This happens because in the generated smalllib.cmake, I have the following

add_library(smalllib::smalllib-4 SHARED IMPORTED)

set_target_properties(smalllib::smalllib-4 PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "Eigen3::Eigen"
)

but Eigen3::Eigen is not defined here.

Eigen is a dependency of the library, so adding it to the application doesn't seem to be the correct way to go using modern CMake. What is the generic way to create my config files for CMake?


回答1:


The config file for smalllib package should define Eigen3::Eigen target. The most direct approach is to use find_dependency macro for Eigen3 as you use find_package in the CMakeLists.txt for the package itself:

Config.cmake.in (this file is used as a template for the resulted config file):

# Get definition of 'find_dependency' macro
include(CMakeFindDependencyMacro)
# Find Eigen3. This will create 'Eigen3::Eigen' target
find_dependency(Eigen3)

# Include CMake-generated config file for the 'smalllib' target
# which uses 'Eigen3::Eigen' target.
include(${CMAKE_CURRENT_LIST_DIR}/smalllib.cmake)

This way is described in the CMake documentation about the packaging.




回答2:


From the description, it seems like the generated smalllibConfig.cmake is missing a call to find_package(Eigen3 REQUIRED) before the targets file gets included.



来源:https://stackoverflow.com/questions/62519433/create-config-file-for-cmake-project

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!