在CMake中导出第三方静态库依赖项的惯用方法是什么



我有以下简化的CMake代码,用于在库中使用Abseil:(用于复制的最小存储库(

cmake_minimum_required(VERSION 3.20)
project(MyProject)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
set(ABSL_PROPAGATE_CXX_STD ON)
find_package(absl REQUIRED)
add_library(MyStaticLibTarget STATIC MyStaticLib.cpp)
target_link_libraries(MyStaticLibTarget absl::strings)
install(TARGETS MyStaticLibTarget EXPORT MyProjectTargets)
install(TARGETS strings EXPORT MyProjectTargets)
if(EXPORT_MYSTATICLIB)
export(TARGETS MyStaticLibTarget FILE lib/cmake/MyProject/MyProjectTargets.cmake)
endif()
# Setup for downstream clients of MyProject?
install(EXPORT MyProjectTargets DESTINATION lib/cmake/MyProject COMPONENT cmake-exports)

但是,当使用运行CMake时,如果我尝试使用export代码路径,我会遇到一个错误,如图所示

cmake -G Ninja -S . -B build -DABSL_ENABLE_INSTALL=ON -DEXPORT_MYSTATICLIB=ON
# CMake Error in CMakeLists.txt:
# export called with target "MyStaticLibTarget" which requires target
#   "strings" that is not in any export set.

我不明白错误信息;在我看来,strings已经是MyProjectTargets的一部分(我认为这是一个导出集?(,所以不应该有任何错误。

也就是说,根据错误消息,我尝试为strings添加一个export行,并过渡地修复了所有错误,最后我得到了

export(TARGETS
strings
strings_internal
type_traits
base
config
throw_delegate
dynamic_annotations
log_severity
base_internal
raw_logging_internal
atomic_hook
core_headers
spinlock_wait
endian
bits
int128
memory
errno_saver
meta
APPEND FILE lib/cmake/MyProject/MyProjectTargets.cmake)

这确实修复了所有错误!在实践中,对于一个更大的图书馆来说,手工操作会非常痛苦。它看起来也像是";错误的";解决方案,因为我手工命名了Abseil的许多内部细节。

  1. 是手动添加目标;右";解决方案
  2. 有没有更好的方法可以达到与上述相同的结果

我有以下限制:

  • 我需要导出MyStaticLibTarget,以便下游客户端可以使用它
  • 我非常确信(在target_link_libraries中(依赖项需要是公共的,因为在实际情况下(这是一个最小的例子(,Abseil头将包含在库的公共头中

TLDR:遵循Conan文档,尤其是cmake_find_package文档,并浏览备忘单。

根据@Tsyvarev在评论中的建议,我使用了不同的设置并完成了这项工作,你可以在conan分支中看到最终结果。

步骤如下:

  1. 使用Conan下载并安装Abseil,使用项目本地conanfile.txt。现在,";安装";是一个可怕的词(我不想修改全局状态(,但柯南本质上只是缓存源代码和构建工件,这意味着你可以在不同的目录中拥有相同库的多个版本,不同的项目可以使用这些不同的版本,它应该"只是工作";。(至少,到目前为止,这是我的基本理解。(
    [requires]         # Which 3rd party conan packages we are using
    abseil/20210324.2
    [generators]       # How to create build system files that capture the dependency information
    cmake_find_package
    cmake_paths
    
    通过以上配置,Conan可以运行:
    conan install . --install-folder build/conan
    # Bunch of CMake files will be available under build/conan
    
  2. 通过在CMakeLists.txt中添加一行,将CMake指向Conan生成的文件。
    include("${CMAKE_BINARY_DIR}/conan/conan_paths.cmake")
    
  3. 使用CMake正常配置。
    cmake -G Ninja -S . -B build -DEXPORT_MYSTATICLIB=ON
    
    (ABSL_ENABLE_INSTALL选项由Conan处理,不再需要。(

最新更新