4、第一个示例:使用FetchContent下载spdlog库、编写CMakeLists.txt、编译与运行验证

好,咱们直接动手。理论说再多,不如跑一个完整的例子来得实在。

这一节,我会带你从零开始,用 FetchContent 下载一个真实的三方库——spdlog,然后把它集成到你的项目里,编译、运行、验证结果。

spdlog 是个啥?说白了就是一个超好用的 C++ 日志库,头文件为主,依赖简单,非常适合用来做 FetchContent 的入门练习。

4.1 项目结构设计

我个人习惯,每个实验项目都单独建一个目录,结构清晰,方便后面复用。

咱们这次的项目结构如下:

fetch_spdlog_demo/
├── CMakeLists.txt          # 主构建文件
├── main.cpp                # 测试代码
└── build/                  # 构建目录(手动创建)

你可以在任意位置创建 fetch_spdlog_demo 文件夹,里面放两个文件就行。

💡 小提示: 我建议你把项目名和文件夹名保持一致,这样 CMake 的 project() 命令看起来更顺眼。纯属个人习惯,不强求。

4.2 编写 CMakeLists.txt

这是核心文件。咱们一步步来,别急。

cmake_minimum_required(VERSION 3.14)
project(FetchSpdlogDemo LANGUAGES CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 开启 FetchContent 模块
include(FetchContent)

# 声明 spdlog 的下载信息
FetchContent_Declare(
    spdlog
    GIT_REPOSITORY https://github.com/gabime/spdlog.git
    GIT_TAG        v1.12.0
)

# 获取并展开源码
FetchContent_MakeAvailable(spdlog)

# 生成可执行文件
add_executable(${PROJECT_NAME} main.cpp)

# 链接 spdlog 库
target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog)

嗯,这里要注意几个关键点:

  • cmake_minimum_required 版本必须 ≥ 3.14,因为 FetchContent 是从这个版本开始稳定的。低于这个版本,你可能会遇到奇奇怪怪的问题。
  • GIT_TAG 我指定了 v1.12.0,这是一个稳定版本。我在项目中遇到过有人不写 TAG,结果每次构建拉下来的版本都不一样,最后排查问题排查到崩溃……
  • FetchContent_MakeAvailable 这一行干了三件事:下载、配置、构建。一步到位,非常省心。
⚠️ 避坑指南: 我曾经在 Windows 上忘记安装 Git,结果 FetchContent 直接报错。请确保你的开发环境已经安装了 Git,并且能在命令行中直接调用 git 命令。

4.3 编写 main.cpp

测试代码很简单,就是初始化 spdlog,然后打印一条日志。

#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>

int main() {
    // 设置全局日志级别
    spdlog::set_level(spdlog::level::info);

    // 打印一条 info 日志到控制台
    spdlog::info("欢迎来到 FetchContent 实战课程!");
    spdlog::warn("这是一条警告信息");
    spdlog::error("这是一条错误信息");

    // 创建一个文件日志记录器
    auto file_logger = spdlog::basic_logger_mt("file_logger", "logs/demo.txt");
    file_logger->info("这条日志写入了文件");

    spdlog::info("所有日志输出完成。");

    return 0;
}

你看,spdlog 的 API 非常直观。你想想看,如果不用 FetchContent,你得先去官网下载源码,解压,配置,编译……现在一行 FetchContent_MakeAvailable 全搞定。

4.4 编译与运行

打开终端,进入项目目录,执行以下命令:

# 进入项目目录
cd fetch_spdlog_demo

# 创建构建目录并进入
mkdir build && cd build

# 配置 CMake(第一次会自动下载 spdlog)
cmake ..

# 编译
cmake --build .

# 运行
./FetchSpdlogDemo

第一次运行 cmake .. 时,你会看到类似这样的输出:

-- Fetching spdlog
-- spdlog: Downloading...
-- spdlog: Download done
-- Configuring done
-- Generating done

这说明 FetchContent 正在后台帮你下载 spdlog 源码。下载完成后,它会自动配置并生成构建系统。

运行程序后,控制台会输出:

[info] 欢迎来到 FetchContent 实战课程!
[warning] 这是一条警告信息
[error] 这是一条错误信息
[info] 所有日志输出完成。

同时,项目目录下会生成一个 logs/demo.txt 文件,里面记录了文件日志的内容。

✅ 验证成功! 你刚刚用 FetchContent 完成了 spdlog 的自动下载、集成、编译和运行。整个过程不需要手动下载任何东西,CMake 全自动处理。

4.5 核心流程回顾

咱们用一张图来总结刚才发生了什么:

FetchContent 下载 spdlog 核心流程 步骤1:声明 FetchContent_Declare 步骤2:下载 自动 Git Clone 步骤3:集成 add_subdirectory 自动调用 步骤4:链接 target_link_libraries 步骤5:编译运行 cmake --build . && ./app ✅ spdlog 成功集成,日志正常输出 整个过程由 CMake 自动完成,开发者只需编写 CMakeLists.txt

这张图展示了从声明到最终运行的完整链路。你会发现,开发者只需要做两件事:写 CMakeLists.txt写业务代码,剩下的下载、配置、构建全部交给 CMake。

4.6 常见问题与排查

我在带团队的时候,发现新手最容易遇到以下几个问题:

问题 原因 解决方法
下载超时或失败 网络问题,GitHub 被墙 使用代理,或更换为国内镜像源
找不到 spdlog 头文件 忘记 target_link_libraries 检查是否链接了 spdlog::spdlog
编译报错 C++ 标准不匹配 spdlog 需要 C++17 设置 CMAKE_CXX_STANDARD 为 17
重复下载 每次 clean 都会重新下载 使用 FETCHCONTENT_SOURCE_DIR 缓存
🔧 实用技巧: 如果你在公司内网,GitHub 访问慢,可以在 FetchContent_Declare 之前设置环境变量 FETCHCONTENT_QUIET=OFF,这样能看到详细的下载进度。我曾经靠这个定位过一次网络代理配置错误的问题。

好了,第一个示例到这里就结束了。你亲手搭建了一个使用 FetchContent 管理依赖的完整项目。这个模式,后面会反复用到。


公众号:蓝海资料掘金营,微信deep3321