Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

FetchContent_Declare 是 CMake 3.11+ 引入的模块,用于在配置阶段下载和管理外部依赖项。它是 ExternalProject的轻量级替代方案,更简单易用。

1. 基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cmake_minimum_required(VERSION 3.14)
project(MyProject)

# 启用 FetchContent 模块
include(FetchContent)

# 声明要获取的内容
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.11.0
)

# 使内容可用
FetchContent_MakeAvailable(googletest)

# 使用依赖项
add_executable(my_test test.cpp)
target_link_libraries(my_test gtest_main)

2. 主要参数详解

2.1. Git 仓库

1
2
3
4
5
6
7
8
9
10
11
FetchContent_Declare(
mylib
GIT_REPOSITORY https://github.com/user/repo.git
GIT_TAG v1.0.0 # 标签
# 或
GIT_TAG main # 分支
# 或
GIT_TAG abc1234 # 提交哈希
GIT_SHALLOW TRUE # 浅克隆(仅最近提交)
GIT_PROGRESS TRUE # 显示克隆进度
)

2.2. 压缩包下载

1
2
3
4
5
6
7
8
9
FetchContent_Declare(
mylib
URL https://example.com/library-1.0.0.tar.gz
URL_HASH SHA256=abc123... # 可选,验证完整性
# 或直接指定多个备用 URL
URLS
https://mirror1.com/lib.tar.gz
https://mirror2.com/lib.tar.gz
)

2.3. SVN 仓库

1
2
3
4
5
FetchContent_Declare(
mylib
SVN_REPOSITORY https://svn.example.com/repo
SVN_REVISION -r12345
)

3. 高级用法

3.1. 覆盖选项

1
2
3
4
5
6
7
8
9
10
11
FetchContent_Declare(
mylib
GIT_REPOSITORY https://github.com/user/mylib.git
GIT_TAG main
# 在配置时设置 CMake 选项
CMAKE_ARGS
-DBUILD_SHARED_LIBS=OFF
-DCMAKE_CXX_STANDARD=17
# 覆盖默认设置
OVERRIDE_FIND_PACKAGE
)

3.2. 手动控制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 声明但不立即获取
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 8.1.1
)

# 稍后手动获取
FetchContent_GetProperties(fmt)
if(NOT fmt_POPULATED)
FetchContent_Populate(fmt)
# 手动添加子目录
add_subdirectory(${fmt_SOURCE_DIR} ${fmt_BINARY_DIR})
endif()

3.3. 多个依赖

1
2
3
4
5
6
7
# 声明多个依赖
FetchContent_Declare(lib1 ...)
FetchContent_Declare(lib2 ...)
FetchContent_Declare(lib3 ...)

# 一次性全部获取
FetchContent_MakeAvailable(lib1 lib2 lib3)

4. 完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
cmake_minimum_required(VERSION 3.14)
project(MyApp)

include(FetchContent)

# 示例1: 获取 Google Test
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.13.0
CMAKE_ARGS
-DCMAKE_CXX_STANDARD=17
-DBUILD_GMOCK=ON
)

# 示例2: 获取 nlohmann/json
FetchContent_Declare(
nlohmann_json
URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz
URL_HASH SHA256=6bea5870bae7c4b53e6e9d7b8d58c5c4d7c5b9a1c5a5a5a5a5a5a5a5a5a5a5a
)

# 示例3: 获取 spdlog
FetchContent_Declare(
spdlog
GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.11.0
GIT_SHALLOW TRUE
)

# 一次性获取所有依赖
FetchContent_MakeAvailable(googletest nlohmann_json spdlog)

# 使用依赖
add_executable(my_app main.cpp)
target_link_libraries(my_app
PRIVATE
nlohmann_json::nlohmann_json
spdlog::spdlog
)

# 测试
enable_testing()
add_test(NAME my_test COMMAND my_app_test)

5. 注意事项

  1. 缓存目录: 默认下载到 ${CMAKE_BINARY_DIR}/_deps
  2. 网络问题: 配置时需要网络连接
  3. 版本控制: 推荐使用特定版本标签,避免意外更新
  4. 离线模式: 可以使用 -DFETCHCONTENT_FULLY_DISCONNECTED=ON 禁用下载

6. 与 find_package 比较

1
2
3
4
5
6
7
8
9
10
11
# 优先使用系统包
find_package(Boost 1.70 QUIET)

# 如果没找到,则从网络获取
if(NOT Boost_FOUND)
FetchContent_Declare(
Boost
URL https://boostorg.jfrog.io/artifactory/main/release/1.81.0/source/boost_1_81_0.tar.bz2
)
FetchContent_MakeAvailable(Boost)
endif()

使用 FetchContent_Declare 可以方便地管理项目依赖,特别适合小型到中型项目。

评论