【问题标题】:Create config file for CMake project为 CMake 项目创建配置文件
【发布时间】:2020-10-12 14:38:36
【问题描述】:

我正在尝试为我拥有的示例项目生成配置 CMake 文件。我的示例由两个 CMake 项目组成:一个在内部使用 spdlog 并在其界面中使用 eigen 的库和一个使用该库的应用程序。这个想法是学习如何创建一个 Config.cmake 文件,以便应用程序可以找到该库。这就是我所拥有的:

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
    )

这会成功生成一个 smalllibConfig.cmake,但是当我尝试执行 find_package(smalllib REQUIRED) 时,我收到以下错误:

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?

发生这种情况是因为在生成的 smalllib.cmake 中,我有以下内容

add_library(smalllib::smalllib-4 SHARED IMPORTED)

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

但是这里没有定义Eigen3::Eigen

Eigen 是库的依赖项,因此将其添加到应用程序似乎不是使用现代 CMake 的正确方法。 为 CMake 创建配置文件的通用方法是什么?

【问题讨论】:

    标签: cmake


    【解决方案1】:

    根据描述,生成的smalllibConfig.cmake 似乎在包含目标文件之前缺少对find_package(Eigen3 REQUIRED) 的调用。

    【讨论】:

    • 我期待这会自动发生,或者库目标已经添加了所有 INTERFACE 属性,因此不再需要调用 Eigen3::Eigen。这是常见的做法吗?
    【解决方案2】:

    smalllib 包的配置文件应该定义Eigen3::Eigen 目标。最直接的方法是对 Eigen3 使用 find_dependency 宏,就像在 CMakeLists.txt 中对包本身使用 find_package 一样:

    Config.cmake.in(此文件用作生成的配置文件的模板):

    # 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)
    

    这种方式在CMake documentation关于包装的描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-16
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多