-1

我有一个依赖于 spdlog 的项目 A。这是结构:

|--- dir A
...|---src
......|---CMakeLists.txt
...|---include
...|---CMakeLists.txt
|---external/3rd_party/spdlog

我正在尝试通过添加子目录来访问项目 A 中的 spdlog。这是我的A/CMakeLists.txt样子:

cmake_minimum_required(VERSION 3.9.3 FATAL_ERROR)
project(GLOBAL CXX)
add_subdirectory(../external/3rd_party/spdlog   ${CMAKE_BINARY_DIR}/spdlog  EXCLUDE_FROM_ALL)
add_subdirectory(src)

这是我的A/src/CMakeLists.txt样子:

cmake_minimum_required(VERSION 3.9.3 FATAL_ERROR)
project(Alib CXX)

if(NOT TARGET spdlog)
   # Stand-alone build
   find_package(spdlog_header_only REQUIRED)
endif()
add_librray(A A.cpp)
target_link_libraries(A PUBLIC spdlog_header_only)

install(TARGETS A
   EXPORT ATargets
   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(EXPORT ATargets
    NAMESPACE A::
    FILE ATargets.cmake
    DESTINATION ${INSTALL_CONFIGDIR})

install(FILES AConfig.cmake DESTINATION ${INSTALL_CONFIGDIR})

当我尝试构建它时,我收到以下错误:

CMake Error: install(EXPORT "ATargets" ...) includes target "A" which requires target "spdlog_header_only" that is not in the export set.

请你能建议我如何解决它吗?

出于某种原因,我需要维护上面显示的相同目录结构。这是一个相关的问题,但没有答案:这里

4

1 回答 1

1

错误的含义

由于您在将库 ( ) 与PUBLIC链接时使用关键字,因此 CMake 预计您的库的用户也需要此链接。因此,当您为库创建配置文件时(使用),CMake 也会将与目标的链接添加到配置文件中。像Aspdlog_header_onlyinstall(EXPORT)spdlog_header_only

# [ATargets.cmake]
target_link_libraries(A::A PUBLIC spdlog_header_only)

与目标链接意味着存在此目标,但您不安装 spdlog_header_only目标。因此,为您的库创建的配置文件将不起作用。这就是 CMake 在错误消息中告诉您的内容。

简单修复

最简单的解决方法是使用PRIVATEspdlog_header_only目标的链接,这样链接就不会成为配置文件的一部分。请注意,在这种情况下,您(已安装)库的用户将无法访问spdlog. (但用户可以通过其他方式获取这些标头。)

硬修复

但是,如果您希望您的库的用户能够访问spdlog标头(或者更糟糕的是,您的库的公共#include标头用于来自 的标头spdlog),那么您不能删除PUBLIC链接。在这种情况下,您也需要安装 spdlog_header_only目标。例如通过启用SPDLOG_INSTALL选项

set(SPDLOG_INSTALL ON)

add_subdirectory(../external/3rd_party/spdlog   ${CMAKE_BINARY_DIR}/spdlog  EXCLUDE_FROM_ALL)

(请注意,除了启用SPDLOG_INSTALL选项之外,还需要进行其他一些调整才能使配置文件使您的库正常工作。)

于 2020-07-30T15:53:23.273 回答