spdlog需用header-only模式或正确链接预编译库,避免undefined reference;glog必须首行调用google::InitGoogleLogging,否则静默失效。

spdlog 在 C++ 项目里怎么快速跑起来
直接用 spdlog,不用自己写日志封装,但得避开几个典型编译和链接雷区。它默认不带源码编译,推荐用 header-only 模式或预编译库,否则容易卡在 undefined reference to spdlog::xxx。
常见错误现象:error: 'spdlog' has not been declared 或链接时报一堆 spdlog::logger::log 未定义。
- 确认头文件路径已加到
CMAKE_INCLUDE_DIRECTORIES或编译器-I参数(比如spdlog/include) - 如果用预编译版本(如 Ubuntu 的
libspdlog-dev),必须链接-lspdlog,且顺序放在你自己的目标之后 - header-only 模式更省事:下载
include/spdlog整个目录,#define SPDLOG_COMPILED_LIB不要定义,直接#include - Windows 下用 MSVC + vcpkg 安装的,注意是否启用了
SPDLOG_FMT_EXTERNAL—— 若项目也用了fmt库,版本不一致会触发multiple definition of fmt::v8::...
glog 初始化失败、日志不输出的硬伤点
glog 看似简单,但不调 google::InitGoogleLogging 就完全静默,连 FATAL 都不打;而且默认只写文件,stderr 要手动开。
使用场景:适合需要结构化日志路径、严重等级过滤、或已有 Google 生态(如 protobuf)的项目。
- 必须在
main()开头第一件事调用google::InitGoogleLogging(argv[0]),漏掉就等于没启用 - 想让
INFO级别也输出到终端?得加FLAGS_stderrthreshold = google::GLOG_INFO(注意是FLAGS_前缀) - 日志文件默认存在
/tmp/(Linux)或当前目录(Windows),路径由FLAGS_log_dir控制;若该目录不可写,日志直接丢弃,无提示 - 多线程下安全,但
google::ShutdownGoogleLogging()不是必须调用——进程退出时自动清理,强行调可能引发 double-free
spdlog 和 glog 日志级别、格式、性能差异在哪
不是“哪个更好”,而是“哪条路更少返工”。spdlog 默认支持异步、多 sink、运行时重配置;glog 更重稳定性、等级语义严格(INFO/WARNING/ERROR/FATAL),但格式定制弱。
参数差异与性能影响:
-
spdlog::basic_logger_mt("name", "file.log")是同步写入;换成spdlog::basic_logger_st可减小锁开销,但多线程下需自行保证线程安全 -
glog的LOG(INFO) 是宏展开,无函数调用开销,但字符串拼接总执行 —— 即便日志被级别过滤掉,operator 仍会构造临时对象 -
spdlog支持spdlog::set_level()运行时调整,glog的FLAGS_minloglevel只在初始化时读取一次 - 高频打日志(如每毫秒一次)时,
spdlog异步模式(spdlog::thread_pool)可压测出 3–5 倍吞吐提升;glog没原生异步,得自己套线程队列
CMake 中正确链接 spdlog/glog 的写法
写错 target_link_libraries 顺序或 scope,是日志库集成失败最隐蔽的原因之一。CMake 不报错,但链接器沉默失败。
关键点:依赖关系必须显式声明,不能靠“看起来好像能连上”。
- 用
find_package(spdlog REQUIRED)后,必须target_link_libraries(your_target PRIVATE spdlog::spdlog)(注意双冒号);写成spdlog或libspdlog会链接失败 - glog 用
find_package(glog REQUIRED)后,链接项是glog::glog(CMake 3.14+),老版本需用glog并手动加include_directories(${GLOG_INCLUDE_DIRS}) - 如果你的 target 是
INTERFACE库,别直接 link 日志库——下游可能不需要,改用target_compile_definitions+target_include_directories暴露头文件即可 - 静态链接
glog时,确保libglog.a编译时没开-fPIC(否则链接 shared library 会报relocation R_X86_64_32 against ... cannot be used when making a shared object)
事情说清了就结束。真正麻烦的从来不是“怎么加一行日志”,而是当 core dump 出现在生产环境、而日志既没落盘也没进 stderr 的时候——那会儿再翻 FLAGS_log_dir 权限或 spdlog::flush_on 设置,就晚了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











