使用 add-subdirectory 访问外部项目导致 CMake Error related to export set
Accessing an external project with add-subdirectory results in CMake Error related to export set
我有一个依赖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.
你能建议我如何解决吗?
出于某种原因,我需要保持与上面所示相同的目录结构。
这是一个相关问题,但没有答案:here
错误的含义
由于您在 link 您的库 (A
) 中使用 spdlog_header_only
时使用 PUBLIC
关键字,CMake 预计此 linking 也需要用于您图书馆的 用户 。因此,当您为库创建配置文件时(使用 install(EXPORT)
),CMake 也会将带有 spdlog_header_only
目标的 linking 添加到配置文件中。喜欢
# [ATargets.cmake]
target_link_libraries(A::A PUBLIC spdlog_header_only)
与目标链接意味着存在该目标,但您未安装 spdlog_header_only
目标。因此,为您的库创建的配置文件将不起作用。这是 CMake 在错误消息中告诉您的内容。
简单修复
最简单的修复方法是将 PRIVATE
linking 与 spdlog_header_only
目标一起使用,这样 linking 就不会成为配置文件的一部分。请注意,在这种情况下,您(已安装)库的用户将无法访问 spdlog
的 header 文件。
(但用户可以通过其他方式获得这些 header。)
硬修复
但是,如果您希望图书馆的用户能够访问 spdlog
header(或者更糟的是 public headers of your library use #include
for headers from spdlog
), then you cannot drop PUBLIC
linking.在这种情况下,您还需要 install spdlog_header_only
目标。例如。通过启用 SPDLOG_INSTALL
选项
set(SPDLOG_INSTALL ON)
之前
add_subdirectory(../external/3rd_party/spdlog ${CMAKE_BINARY_DIR}/spdlog EXCLUDE_FROM_ALL)
(请注意,除了启用 SPDLOG_INSTALL
选项外,还需要进行其他几项调整才能使您的库的配置文件正常工作。)
我有一个依赖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.
你能建议我如何解决吗?
出于某种原因,我需要保持与上面所示相同的目录结构。 这是一个相关问题,但没有答案:here
错误的含义
由于您在 link 您的库 (A
) 中使用 spdlog_header_only
时使用 PUBLIC
关键字,CMake 预计此 linking 也需要用于您图书馆的 用户 。因此,当您为库创建配置文件时(使用 install(EXPORT)
),CMake 也会将带有 spdlog_header_only
目标的 linking 添加到配置文件中。喜欢
# [ATargets.cmake]
target_link_libraries(A::A PUBLIC spdlog_header_only)
与目标链接意味着存在该目标,但您未安装 spdlog_header_only
目标。因此,为您的库创建的配置文件将不起作用。这是 CMake 在错误消息中告诉您的内容。
简单修复
最简单的修复方法是将 PRIVATE
linking 与 spdlog_header_only
目标一起使用,这样 linking 就不会成为配置文件的一部分。请注意,在这种情况下,您(已安装)库的用户将无法访问 spdlog
的 header 文件。
(但用户可以通过其他方式获得这些 header。)
硬修复
但是,如果您希望图书馆的用户能够访问 spdlog
header(或者更糟的是 public headers of your library use #include
for headers from spdlog
), then you cannot drop PUBLIC
linking.在这种情况下,您还需要 install spdlog_header_only
目标。例如。通过启用 SPDLOG_INSTALL
选项
set(SPDLOG_INSTALL ON)
之前
add_subdirectory(../external/3rd_party/spdlog ${CMAKE_BINARY_DIR}/spdlog EXCLUDE_FROM_ALL)
(请注意,除了启用 SPDLOG_INSTALL
选项外,还需要进行其他几项调整才能使您的库的配置文件正常工作。)