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

6

我有一个依赖于外部库(如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方法”来完成?


1
这取决于外部库提供的构建方式。例如,如果它使用cmake构建,您可以通过add_subdirectory(${libname_SOURCE_DIR})调用将该库添加到您的构建中。我快速查看了一下SDL。看起来它不是使用cmake构建的。在这种情况下,您可以尝试使用https://cmake.org/cmake/help/latest/command/add_custom_target.html来构建SDL(使用COMMAND关键字调用SDL的本地构建cmd),然后配置自定义目标,以便其他目标可以依赖它。一个很好的写作:https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/ - Matt
1
@Matt 所以基本上如果这个库是基于CMake的,我只需要使用 add_subdirectory 命令,让CMake来完成工作。否则,我就必须使用 add_custom_target 命令手动构建它。这很好知道,你可以把你的评论变成一个答案 :) - Ignorant
我已经发布了一个答案。仔细查看SDL后,似乎它确实可以使用cmake构建...也许我使用的是过时的版本,或者最初查看了错误的存储库。所以这应该会使它更容易集成到您的构建中。 - Matt
1个回答

3

建议构建外部库的最佳方式是将其作为构建的一部分从源代码构建,具体取决于外部库提供的构建方式。

使用cmake构建外部库

如果外部库使用cmake进行构建,则可以通过add_subdirectory(${libname_SOURCE_DIR})调用将库添加到您的构建中。这样,cmake将构建外部库作为子文件夹(“子项目”)。外部库的CMakeLists.txt文件中将有一些add_library(ext_lib_name ...)语句。为了在您的目标中(一个依赖于外部库的应用程序或库)使用外部库,您可以简单地调用target_link_libraries(your_application <PRIVATE|PUBLIC|INTERFACE> 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等自行设置对客户端重要的目标属性...以下是一篇非常好的文章,介绍了如何开始使用这些工具:https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接