4、第一个示例:使用FetchContent下载spdlog库、编写CMakeLists.txt、编译与运行验证
好,咱们直接动手。理论说再多,不如跑一个完整的例子来得实在。
这一节,我会带你从零开始,用 FetchContent 下载一个真实的三方库——spdlog,然后把它集成到你的项目里,编译、运行、验证结果。
spdlog 是个啥?说白了就是一个超好用的 C++ 日志库,头文件为主,依赖简单,非常适合用来做 FetchContent 的入门练习。
4.1 项目结构设计
我个人习惯,每个实验项目都单独建一个目录,结构清晰,方便后面复用。
咱们这次的项目结构如下:
fetch_spdlog_demo/
├── CMakeLists.txt # 主构建文件
├── main.cpp # 测试代码
└── build/ # 构建目录(手动创建)
你可以在任意位置创建 fetch_spdlog_demo 文件夹,里面放两个文件就行。
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 这一行干了三件事:下载、配置、构建。一步到位,非常省心。
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 文件,里面记录了文件日志的内容。
4.5 核心流程回顾
咱们用一张图来总结刚才发生了什么:
这张图展示了从声明到最终运行的完整链路。你会发现,开发者只需要做两件事:写 CMakeLists.txt 和 写业务代码,剩下的下载、配置、构建全部交给 CMake。
4.6 常见问题与排查
我在带团队的时候,发现新手最容易遇到以下几个问题:
| 问题 | 原因 | 解决方法 |
|---|---|---|
| 下载超时或失败 | 网络问题,GitHub 被墙 | 使用代理,或更换为国内镜像源 |
| 找不到 spdlog 头文件 | 忘记 target_link_libraries | 检查是否链接了 spdlog::spdlog |
| 编译报错 C++ 标准不匹配 | spdlog 需要 C++17 | 设置 CMAKE_CXX_STANDARD 为 17 |
| 重复下载 | 每次 clean 都会重新下载 | 使用 FETCHCONTENT_SOURCE_DIR 缓存 |
FetchContent_Declare 之前设置环境变量 FETCHCONTENT_QUIET=OFF,这样能看到详细的下载进度。我曾经靠这个定位过一次网络代理配置错误的问题。
好了,第一个示例到这里就结束了。你亲手搭建了一个使用 FetchContent 管理依赖的完整项目。这个模式,后面会反复用到。
公众号:蓝海资料掘金营,微信deep3321