记录一次UT编译std::mutex 报错的排查过程

5 阅读2分钟

Windows 下 C++ 编译工具链详解:从一个 std::mutex 报错说起

问题现象

项目编译时报错:


error: no member named 'mutex' in namespace 'std'

环境是 Windows 平台,已经添加了 #include <mutex>,也配置了 C++14。

排查过程

  1. 确认 #include <mutex> 已添加
  2. 检查 CMakeCache.txt-std=c++14 已配置
  3. 检查 compile_commands.json,编译参数正确
  4. 直接调用 g++ 测试,问题复现
  5. 运行 g++ -v,发现输出中有 --enable-threads=win32

根因

MinGW 有两种线程模型:win32 和 posix。其中 win32 模型不支持 std::mutexstd::thread 等 C++11 线程库。当前用的是 win32 版本。

解决方案

下载 posix 线程模型的 MinGW64,设置环境变量。


背景知识

两大编译器生态

生态C 编译器C++ 编译器调试器链接器
LLVMclangclang++LLDBLLD
GNUgccg++GDBld

GNU 工具链组件

工具全称作用
ldLink eDitor链接器
asASsembler汇编器
arARchive打包静态库

GNU 工具链组件

MinGW

MinGW(Minimalist GNU for Windows)是 GNU 工具链在 Windows 上的移植,提供 GCC 编译器和标准库。


源码编译流程


.cpp → 预处理(宏替换、引入头文件)→ .s → 汇编器 → .obj → 链接器 → .exe

CMake 构建流程


CMakeLists.txt  
↓ cmake 读取  
CMakeCache.txt + compile_commands.json + Makefile  
↓ make 执行  
调用编译器 → .obj → 链接标准库 → .exe


为什么 Clang++ 需要 MinGW

Clang 在 Windows 上不自带 C++ 标准库和链接器,需要借用:

  • MSVC 后端:用 Microsoft STL + link.exe
  • MinGW 后端:用 libstdc++ + ld

使用 -target x86_64-pc-windows-gnu 时,Clang++ 编译代码,但标准库和链接器来自 MinGW。

所以 MinGW 的线程模型配置会影响 Clang++ 的编译结果。


静态库与动态库

库类型静态库动态库

总结

g++ 和 clang++ 是不同的编译器,但在 Windows 上可以共享 MinGW 的标准库和链接器。MinGW 用 win32 线程模型时,std::mutex 不可用,换成 posix 版本即可解决。