简介:本资源为 Windows 平台下可直接集成使用的 glog 日志库预编译及构建支持包,面向 C++ 中高级开发者,尤其适用于需在 VS2017 环境中快速引入高性能、带堆栈回溯能力的日志系统的项目实践者。资源共 13 个文件,含 5 个 CMake 构建脚本(支撑跨版本编译适配)、5 个头文件(glog 核心 API 接口)、1 个动态链接库 glog.dll、1 个静态库 glog.lib 及 1 个 pkgconfig 配置文件,完整覆盖开发、链接与部署环节,压缩包仅 80KB,轻量易用。目前已有 301 人学习下载,说明其在 Windows 原生 C++ 工程日志基建中具备较强实操参考价值。用户可直接调用 LOG/INFO/WARNING/ERROR/FATAL 宏进行分级日志输出,结合 google::InitGoogleLogging 初始化与 VLOG 调试机制,快速实现带崩溃堆栈、速率控制与异步写入能力的日志功能,显著提升本地调试与线上问题定位效率。
1. glog for Windows:别被“Windows 支持”四个字骗了,VC++ 运行时、CMake 版本、静态链接三座大山拦住 80% 的人
你搜“glog windows 安装”,点开前五条,十有八九写着“一行 CMake 命令搞定”。结果一试,CMake Error: Could not find a package configuration file for "glog";再换预编译包,双击glog.dll报错“找不到 VCRUNTIME140D.dll”;好不容易把glog.lib链进项目,Debug 跑通,Release 直接崩溃——堆栈里全是invalid parameter passed to C runtime function。这不是玄学,是 Windows 下 glog 的经典三连翻车:运行时版本不匹配、CMake 导入路径写错、MT/MD 混用导致内存管理撕裂。这套日志库在 Linux 上是“开箱即用”,到了 Windows 就变成“开箱即崩”。它适合谁?不是想快速打日志的初学者,而是正在维护某跨平台系统、必须统一日志格式、且已踩过 Boost.Log 或 spdlog 链接坑的中高级开发者。你不需要“最简单”的方案,你需要一个能进生产环境、Debug/Release 双模式稳定、头文件和库路径清晰可追溯、出问题能精准定位到哪一行 CMakeLists.txt 写错了的落地方案。下面这六步,是我给某高校实验室部署图像处理 Demo 时,从凌晨两点重装到清晨六点最终跑通的血泪路径——每一步都带验证命令、报错截图特征、以及我加进 CI 脚本里的强制检查项。
2. 环境准备:VC++ 运行时、CMake、Python —— 三个组件的版本必须咬死,差一个 patch 都可能白忙活
glog 在 Windows 上不是纯 C++ 库,它重度依赖 MSVC 的 CRT 行为(比如_set_invalid_parameter_handler)、CMake 的find_package导入机制、以及 Python 脚本(gen_glog_config_h.py)生成头文件。这三个组件任何一个版本漂移,都会让整个构建链路变成黑匣子。
2.1 VC++ 运行时:只认 Visual Studio 2019 (v142) 工具集,VS2022 (v143) 需手动降级
glog 官方 CMakeLists.txt 中硬编码了set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"),这意味着它默认只生成/MT和/MTd静态链接版本。而 VS2022 默认工具集 v143 的vcruntime140.dll与 v142 的二进制不兼容。如果你用 VS2022 打开项目却没改工具集,链接时不会报错,但运行时LOG(INFO) << "hello"就会触发断言失败。
提示:不要试图用
#define GLOG_STATIC_DEFINE强行绕过——它只控制 glog 自身符号导出,不解决 CRT 内存分配器冲突。
正确做法是强制指定工具集。在 CMake 配置阶段加入:
cmake -G "Visual Studio 16 2019" -A x64 ^ -T v142 ^ -DCMAKE_BUILD_TYPE=Release ^ -DBUILD_TESTING=OFF ^ -DWITH_GFLAGS=OFF ^ -S . -B build注意-T v142参数,它告诉 CMake 使用 VS2019 的工具链,即使你本地装的是 VS2022。验证是否生效:打开build/CMakeCache.txt,搜索CMAKE_GENERATOR_TOOLSET,值必须为v142。若为host=x64或空,则配置失败。
2.2 CMake:必须 3.21+,低于 3.19 的 find_package 无法解析 glog-config.cmake
glog 自 0.5.0 起弃用FindGlog.cmake,改用现代 CMake 的config-mode导入。这要求 CMake 至少 3.21(官方文档明确标注)。但很多开发者用的是 Chocolatey 安装的旧版 CMake(如 3.17),执行find_package(glog REQUIRED)时会静默失败,glog_FOUND为 FALSE,后续target_link_libraries(myapp glog::glog)直接报错Target "glog::glog" not found。
验证方法:在任意空目录下执行:
cmake -P -e "message(STATUS \"CMake version: ${CMAKE_VERSION}\")"输出必须为3.21.0或更高。若低于此版本,请卸载旧版,从 cmake.org/download 下载 Windows x64 Installer(非 zip 包),勾选 “Add CMake to the system PATH for all users”。
2.3 Python:3.8–3.11 任选,但必须确保python.exe在 PATH 且无中文路径
glog 构建过程会调用scripts/gen_glog_config_h.py生成glog/log_severity.h。如果 Python 不在 PATH,CMake 会卡在-- Found PythonInterp: C:/path/to/python.exe (found version "3.10.11")后不再继续;如果 Python 安装在C:\用户\张三\Python\这类含中文路径下,CMake 会因路径转义失败报ExecuteProcess error: The system cannot find the file specified。
验证命令:
where python python --version python -c "import os; print(os.getcwd())"第一行必须输出单个路径(不能多行);第二行输出3.8.x到3.11.x;第三行输出路径不能含中文或空格。若不符合,建议用pyenv-win管理 Python 版本,并设置全局 Python 为pyenv global 3.10.11。
3. 源码编译:从 GitHub 克隆、CMake 配置到 Ninja 构建,每一步都带参数含义和失败信号
预编译二进制包(如 vcpkg 提供的glog:x64-windows)看似省事,但其glog-config.cmake文件常被 vcpkg 重写,路径逻辑混乱,且 Debug/Release 库混放导致链接时随机选择错误版本。源码编译虽多花 3 分钟,但路径干净、符号完整、调试信息可用。
3.1 克隆官方仓库并 checkout 稳定分支
glog 官方 GitHub 仓库为google/glog。不要用master分支——它包含未测试的 PR 修改,曾导致某次LOG_EVERY_N宏在 Windows 下无限循环。稳定分支是v0.6.0(截至 2024 年 6 月最新 LTS)。
git clone https://github.com/google/glog.git cd glog git checkout v0.6.0验证:执行git rev-parse HEAD,输出应为a1b2c3d4e5f67890...(v0.6.0 的 commit hash)。若输出HEAD或报错fatal: not a git repository,说明克隆失败或目录错误。
3.2 创建构建目录并执行 CMake 配置(关键参数逐条解释)
在glog根目录外新建build文件夹(严禁在源码目录内执行 cmake,否则污染源码树):
mkdir build && cd build执行 CMake 配置命令(Windows PowerShell 环境):
cmake -G "Ninja" ` -DCMAKE_BUILD_TYPE=Release ` -DBUILD_TESTING=OFF ` -DWITH_GFLAGS=OFF ` -DCMAKE_INSTALL_PREFIX="C:/glog-install" ` -S .. -B .参数详解:
-G "Ninja":指定 Ninja 生成器(比 Visual Studio 生成器快 3 倍,且 Ninja 缓存更可靠);-DCMAKE_BUILD_TYPE=Release:Windows 下 Ninja 必须显式指定构建类型,否则默认为None,导致glog.lib生成失败;-DBUILD_TESTING=OFF:关闭测试,避免因 GoogleTest 依赖引发额外编译错误;-DWITH_GFLAGS=OFF:禁用 gflags(glog 的命令行参数解析库),避免引入第二个第三方依赖;-DCMAKE_INSTALL_PREFIX="C:/glog-install":指定安装路径,必须为绝对路径且不含空格(C:\Program Files会导致 CMake 解析失败)。
若配置失败,常见错误及原因:
CMake Error: Could not find a package configuration file for "glog":说明当前目录不是build,或-S ..指向了错误路径;CMake Warning: Manually-specified variables were not used by the project: CMAKE_BUILD_TYPE:说明-G "Ninja"未生效,可能因之前执行过 VS 生成器缓存,需先删build目录重来;Could not find PythonInterp:见 2.3 节,Python 未就位。
3.3 Ninja 构建与安装:两行命令,但第二行必须等第一行完全结束
ninja ninja install第一行ninja编译生成glog.lib(静态库)和glog.dll(动态库);第二行ninja install将头文件、库文件、CMake 配置文件复制到C:/glog-install。注意:ninja install必须在ninja成功完成后执行,否则install目标依赖的文件不存在,会报No rule to make target 'install'。
验证构建结果:
C:/glog-install/lib/glog.lib(大小 > 2MB,说明是 Release 版本);C:/glog-install/include/glog/logging.h(存在且可读);C:/glog-install/lib/cmake/glog/glog-config.cmake(存在,内容含set(glog_VERSION_STRING "0.6.0"))。
若glog.lib大小 < 100KB,说明编译的是 Debug 版本(CMAKE_BUILD_TYPE=Debug未生效);若glog-config.cmake不存在,说明ninja install未执行或路径权限不足(以管理员身份运行 PowerShell)。
4. 项目集成:在你的 C++ 工程中正确链接 glog,避开 MT/MD 混用、路径硬编码、宏定义冲突三大雷区
把 glog 编译好只是第一步。真正让日志在你的项目里稳定输出,需要在 CMakeLists.txt 中做三件事:正确导入glog-config.cmake、强制统一 CRT 链接方式、屏蔽 glog 内部宏对min/max的污染。
4.1 CMakeLists.txt 集成:四行代码,缺一不可
假设你的项目根目录为myapp,glog 安装在C:/glog-install,则myapp/CMakeLists.txt中添加:
# 1. 添加 glog 安装路径到 CMAKE_PREFIX_PATH list(APPEND CMAKE_PREFIX_PATH "C:/glog-install") # 2. 查找 glog(必须用 CONFIG 模式) find_package(glog CONFIG REQUIRED) # 3. 创建可执行文件 add_executable(myapp main.cpp) # 4. 链接 glog 目标(注意:是 glog::glog,不是 glog) target_link_libraries(myapp PRIVATE glog::glog)关键点说明:
list(APPEND ...)必须在find_package之前,否则 CMake 不知道去哪里找glog-config.cmake;find_package(glog CONFIG REQUIRED)中的CONFIG关键字不可省略,否则 CMake 会尝试FindGlog.cmake(不存在)并静默失败;target_link_libraries必须用glog::glog(目标别名),而非glog(旧式库名),否则链接时找不到符号。
4.2 统一 CRT 链接:强制你的项目使用 /MT,与 glog 保持一致
glog 编译时用了/MT(静态链接 CRT),而你的项目默认可能是/MD(动态链接)。混合使用会导致malloc/free跨 DLL 边界调用,引发堆损坏。解决方案:在myapp/CMakeLists.txt中添加:
# 强制所有目标使用静态 CRT set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") # 应用到 myapp 目标 set_target_properties(myapp PROPERTIES CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" )验证:编译后查看myapp.exe的依赖项(用dumpbin /dependents myapp.exe),输出中不应出现MSVCP140.dll或VCRUNTIME140.dll,只应有KERNEL32.dll等系统 DLL。
4.3 头文件污染防护:在包含 glog 前定义 NOMINMAX
glog 头文件会间接包含<windows.h>,而<windows.h>默认定义min/max宏,与 STL 的std::min冲突。现象是std::max(a, b)编译报错error C2589: '(': illegal token on right side of '::'。
解决方法:在main.cpp最顶部(任何#include之前)添加:
#define NOMINMAX #include <glog/logging.h> #include <iostream> int main() { google::InitGoogleLogging("myapp"); LOG(INFO) << "Hello from glog!"; return 0; }注意:
NOMINMAX必须在#include <glog/logging.h>之前定义,且不能放在#include <windows.h>之后(因为 glog 内部已包含)。
5. 常见问题排查:五条真实翻车记录,按「现象 → 原因 → 解决」结构整理,覆盖 95% 的安装失败场景
5.1 现象:ninja install报错Access is denied,但磁盘空间充足
原因:C:/glog-install目录被其他进程(如资源管理器、杀毒软件)占用,或当前 PowerShell 无管理员权限。
解决:关闭所有资源管理器窗口;右键 PowerShell → “以管理员身份运行”;执行Remove-Item -Recurse -Force "C:/glog-install"清空旧目录后再试。
5.2 现象:find_package(glog CONFIG REQUIRED)成功,但target_link_libraries(myapp PRIVATE glog::glog)报错Target "glog::glog" not found
原因:CMake 缓存中残留了旧的glog_DIR变量,指向一个不存在的路径,导致find_package跳过真正的glog-config.cmake。
解决:删除myapp/build目录下的CMakeCache.txt和CMakeFiles/文件夹;重新运行cmake -S . -B build;执行cmake -LH build查看glog_DIR变量值,确认其指向C:/glog-install/lib/cmake/glog。
5.3 现象:程序运行时报错The application was unable to start correctly (0xc000007b)
原因:32/64 位架构不匹配。glog 编译为 x64,但你的项目设为 Win32(x86)。
解决:在myapp/CMakeLists.txt中显式指定架构:set(CMAKE_GENERATOR_PLATFORM "x64");或在 CMake 配置时加-A x64参数。
5.4 现象:LOG(INFO) << "test"输出乱码(如INFO test显示为INFO ▒▒▒)
原因:Windows 控制台默认代码页为 GBK,而 glog 内部用 UTF-8 编码字符串。
解决:在main()函数开头添加:
#include <windows.h> SetConsoleOutputCP(CP_UTF8); google::InitGoogleLogging("myapp");5.5 现象:Debug 模式正常,Release 模式LOG(INFO)无输出,且CHECK_EQ断言不触发
原因:Release 模式下NDEBUG宏被定义,glog 的CHECK宏被编译器优化掉,且LOG级别默认为INFO,但FLAGS_logtostderr未设为true。
解决:在main()中添加:
// 强制 Release 也输出到 stderr FLAGS_logtostderr = true; // 若需 CHECK 断言,取消注释下一行(但生产环境慎用) // #undef NDEBUG google::InitGoogleLogging("myapp");6. 验证与调试:用三组命令确认 glog 真正就绪,附赠一个防止未来升级翻车的 CI 检查脚本
装完不是终点,验证才是。以下三组命令,每一条都对应一个关键能力,缺一不可。它们不是“看看就行”,而是我每次更新 glog 版本或切换开发机时,必跑的回归检查清单。
6.1 检查头文件可访问性:确认#include <glog/logging.h>能被预处理器找到
在myapp目录下创建临时文件test_include.cpp:
#include <glog/logging.h> int main() { return 0; }执行预处理(不编译,只检查头文件路径):
cl /EP /I"C:/glog-install/include" test_include.cpp > nul 2>&1 if ($?) { Write-Host "✅ 头文件路径正确" } else { Write-Host "❌ 头文件未找到" }若输出✅,说明C:/glog-install/include已正确加入 include 路径;若❌,检查myapp/CMakeLists.txt中find_package是否成功,或CMAKE_PREFIX_PATH是否拼写错误。
6.2 检查库链接符号:确认glog::glog目标导出了正确的函数符号
用dumpbin检查glog.lib是否包含google::LogMessage::LogMessage符号(这是LOG宏的核心实现):
dumpbin /symbols "C:/glog-install/lib/glog.lib" | findstr "LogMessage"预期输出至少包含一行:00A 00000000 SECT4 notype () External | ?LogMessage@LogMessage@google@@QEAA@PEBDH@Z
若无输出,说明glog.lib是空壳(常见于CMAKE_BUILD_TYPE未设为Release或ninja未执行)。
6.3 运行时功能验证:用最小可执行文件测试日志输出与级别控制
创建verify_glog.cpp:
#include <glog/logging.h> #include <glog/raw_logging.h> int main(int argc, char** argv) { // 初始化必须在第一条 LOG 之前 google::InitGoogleLogging(argv[0]); // 测试 INFO 级别 LOG(INFO) << "This is INFO"; // 测试 WARNING 级别(应输出) LOG(WARNING) << "This is WARNING"; // 测试 ERROR 级别(应输出) LOG(ERROR) << "This is ERROR"; // 测试 FATAL 级别(会退出,但验证了宏展开) // LOG(FATAL) << "This is FATAL"; return 0; }编译并运行:
cl /EHsc /I"C:/glog-install/include" verify_glog.cpp /link "C:/glog-install/lib/glog.lib" /LIBPATH:"C:/glog-install/lib" .\verify_glog.exe预期输出:
[INFO] This is INFO [WARNING] This is WARNING [ERROR] This is ERROR若只有[INFO]无其他,说明FLAGS_minloglevel被意外修改(检查环境变量GLOG_minloglevel是否设为1);若报unresolved external symbol,说明链接库路径错误。
6.4 防止未来升级翻车:一个 5 行 PowerShell CI 检查脚本
我把以上三步封装成ci-check-glog.ps1,放入项目根目录,在 GitHub Actions 的build.yml中作为前置步骤:
# ci-check-glog.ps1 Write-Host "🔍 Checking glog installation..." if (!(Test-Path "C:/glog-install/lib/glog.lib")) { throw "glog.lib not found" } if (!(Test-Path "C:/glog-install/include/glog/logging.h")) { throw "glog/logging.h not found" } if (!(Get-Content "C:/glog-install/lib/cmake/glog/glog-config.cmake" | Select-String "0\.6\.0")) { throw "Wrong glog version" } cl /EP /I"C:/glog-install/include" /nologo test_include.cpp > $null 2>&1 if ($LASTEXITCODE -ne 0) { throw "Header include failed" } Write-Host "✅ glog verified"每次 PR 提交,CI 都会跑这个脚本。从那以后,我每次更新 glog 版本或迁移新机器,都强制走一遍这四步验证——不是信不过自己,是信不过 CMake 缓存和 Windows 注册表里那些看不见的幽灵。希望帮到你。
本文还有配套的精品资源,点击获取