如何构建使用 CMake FetchContent 下载的外部库?

Posted

技术标签:

【中文标题】如何构建使用 CMake FetchContent 下载的外部库?【英文标题】:How to build an external library downloaded with CMake FetchContent? 【发布时间】:2020-08-31 08:50:21 【问题描述】:

我有一个依赖于外部库(例如 SDL)的程序。我希望 CMake 为我处理这种依赖关系,所以我正在研究 FetchContent。据我了解,该模块只是下载源代码,以便在配置时提供有关外部库的信息。例如:

include(FetchContent)

FetchContent_Declare(sdl
  GIT_REPOSITORY <...>
)

FetchContent_GetProperties(sdl)

# sdl_POPULATED, sdl_SOURCE_DIR and sdl_BINARY_DIR are ready now

if(NOT sdl_POPULATED)
  FetchContent_Populate(sdl)
endif()

但是,在某些时候,我想构建该源代码并将其链接到我的主可执行文件。如何以“现代 CMake 方式”做到这一点?

【问题讨论】:

这取决于外部库提供的构建方式。例如。如果它使用 cmake 构建,您可以通过 add_subdirectory($libname_SOURCE_DIR) 调用将 lib 添加到您的构建中。我快速浏览了 SDL。看起来它不是用 cmake 构建的。在这种情况下,您可以尝试使用 cmake.org/cmake/help/latest/command/add_custom_target.html 构建 SDL(使用 COMMAND 关键字调用 SDL 的本机构建 cmd),然后配置自定义目标,以便其他目标可以依赖它。一篇很棒的文章如何做到这一点:pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right @Matt 所以基本上如果库是基于 CMake 的库,我可以 add_subdirectory 让 CMake 为我完成这项工作。否则我必须用add_custom_target“手工”构建它。很高兴知道,您可以将您的评论变成答案:) 我已经发布了答案。在再次查看 SDL 之后,它似乎实际上 确实 使用 cmake 构建......也许我登陆了一个过时的版本,或者最初查看了错误的 repo。因此,这有望使其更容易集成到您的构建中。 【参考方案1】:

作为构建的一部分从源代码构建外部库的推荐方法取决于外部库提供的构建方式。

使用 cmake 构建外部库

如果外部库是使用 cmake 构建的,那么您可以通过 add_subdirectory($libname_SOURCE_DIR) 调用将该库添加到您的构建中。这样,cmake 会将外部库构建为子文件夹(“子项目”)。外部库的CMakeLists.txt 文件将包含一些add_library(ext_lib_name ...) 语句。为了在您的目标中使用外部库(依赖于外部库的应用程序或库),您只需调用target_link_libraries(your_application &lt;PRIVATE|PUBLIC|INTERFACE&gt; ext_lib_name)https://cmake.org/cmake/help/latest/command/target_link_libraries.html

我快速浏览了这个 github repo https://github.com/rantoniello/sdl -(如果您指的是另一个库,请告诉我)它实际上看起来像是使用 cmake 构建的,并且它允许客户端静态或动态链接它:https://github.com/rantoniello/sdl/blob/master/CMakeLists.txt#L1688-L1740

因此,理想情况下,您的应用程序应该能够做到

add_executable(myapp ...)
target_link_libraries(myapp PRIVATE SDL2-static) // Statically link againt SDL2

由于他们的 CMakeLists.txt 文件,SDL2-static 带有属性(包括目录、链接器标志/命令),这些属性将自动分配给 myapp

外部库不使用 cmake 构建

如果没有使用 cmake 构建外部库,则可以尝试使用 add_custom_target https://cmake.org/cmake/help/latest/command/add_custom_target.html 构建库。大致如下:

add_custom_target(myExternalTarget COMMAND <invoke the repo's build system>)

然后,您需要通过适当的 cmake 函数 set_target_propertiestarget_include_directories 自己设置对客户很重要的目标属性...如何开始使用这些东西的好文章:@987654325 @

【讨论】:

以上是关于如何构建使用 CMake FetchContent 下载的外部库?的主要内容,如果未能解决你的问题,请参考以下文章

通过 CMake FetchContent 设置 Qt5

为啥 FetchContent 更喜欢子目录包含而不是安装依赖项?

Cmake:对包含方法的未定义引用

CMake 快速入门

CMake 快速入门

CMake 快速入门