1. 问题背景
1.1 症状
编译 xxx 项目时报错,提示找不到 <mutex> 头文件:
fatal error: mutex: No such file or directory
1.2 根本原因
使用的 MinGW 版本是 win32 线程模型(5.4.0_WIN64),不支持 C++11 的 <thread>、<mutex> 等头文件。需要使用 posix 线程模型 的 MinGW(8.1.0WIN64)。
2. FVG3 构建系统架构
2.1 调用链
fvg3.bat
│
▼
./tools/tcc/python3w.bat ./tools/fvg3/fvg3.py
│
▼
fvg3.py(加载 Less_Llvm 等目标类)
│
▼
less_llvm.py(检查 MINGW64_HOME 环境变量)
│
▼
CMake(读取 CMakeLists.txt,生成 CMakeCache.txt)
│
▼
编译器(MinGW gcc/g++)
2.2 关键文件说明
| 文件 | 作用 | 是否自动生成 |
|---|---|---|
CMakeLists.txt | CMake 项目配置,定义编译规则、依赖 | 否,手动编写 |
CMakeCache.txt | CMake 变量缓存,包含编译器路径等 | 是,cmake 配置时生成 |
compile_commands.json | 编译数据库,记录每个文件的编译命令 | 是,cmake 配置时生成 |
TCC_FVG3_Windows_Local.xml | TCC 工具链默认配置 | 否,项目预设 |
less_llvm.py | fvg3 构建脚本,设置构建环境 | 否,项目预设 |
2.3 两套变量系统
这是最容易混淆的地方:
| 层级 | 环境变量 | 用途 |
|---|---|---|
| Python 脚本层(less_llvm.py) | MINGW64_HOME | 脚本检查此变量,决定用哪个 MinGW |
| CMake 层 | TCC_MINGW64 | CMake 工具链文件使用 |
| TCC 系统默认 | XML 配置文件 | 当环境变量未设置时的 fallback |
关键点:less_llvm.py 在调用 CMake 之前运行,它只检查 MINGW64_HOME:
# less_llvm.py 第 34-44 行
if os.environ.get('MINGW64_HOME'):
self.env.set_value('MINGW64_HOME', os.en...
self.env.append_path(os.path.join(os.en...
else:
raise self.SetupError('llvm need librari...') # 直接报错
3. 排查流程
3.1 检查环境变量是否生效
# 检查 MINGW64_HOME
echo $env:MINGW64_HOME
# 检查编译器版本和线程模型
& "$env:MINGW64_HOME\bin\gcc.exe" -v 2>&1 | Select-String "Thread"
# 应该看到 "Thread model: posix"
3.2 检查 CMakeCache.txt 中的编译器路径
Get-Content build/CMakeCache.txt | Select-String -Pattern "MINGW|GCC|CXX_COMPILER"
3.3 检查 compile_commands.json 中的实际编译命令
Get-Content build/compile_commands.json | Select-String "mingw"
3.4 搜索项目中所有涉及 MinGW 的配置
# 搜索 Python 脚本
Get-ChildItem -Path ./tools -Recurse -Include "*.py" | Select-String "TCC_MINGW64|MINGW" | Select-Object Path, LineNumber, Line
# 搜索 TCC 配置
Get-ChildItem -Path ./tools/tcc -Recurse | Select-String "TCC_MINGW64|MINGW"
4. 解决方案
4.1 方案一:设置 MINGW64_HOME 环境变量(推荐)
临时设置(当前 PowerShell 会话):
$env:MINGW64_HOME = "C:\TCC\Tools\mingw64\8.1.0WIN64"
永久设置:
- 打开系统环境变量设置
- 在 User variables 或 System variables 中点击 New
- 变量名:
MINGW64_HOME - 变量值:
C:\TCC\Tools\mingw64\8.1.0WIN64 - 重启 PowerShell 使其生效
4.2 方案二:修改 TCC XML 配置文件
编辑 ./tools/tcc/TCC_FVG3_Windows_Local.xml 第 132 行:
<!-- 改之前 -->
<SourcePath>TCC\Tools\mingw64\5.4.0_WIN64</SourcePath>
<!-- 改之后 -->
<SourcePath>TCC\Tools\mingw64\8.1.0WIN64</SourcePath>
⚠️ 注意:此文件可能被 git 追踪,修改会影响版本控制。
4.3 方案三:创建符号链接(零侵入)
# 备份旧版本
Rename-Item "C:\TCC\Tools\mingw64\5.4.0_WIN64" "C:\TCC\Tools\mingw64\5.4.0_WIN64_backup"
# 创建符号链接指向新版本
New-Item -ItemType SymbolicLink -Path "C:\TCC\Tools\mingw64\5.4.0_WIN64" -Target "C:\TCC\Tools\mingw64\8.1.0WIN64"
5. 完整编译步骤
# 1. 设置环境变量
$env:MINGW64_HOME = "C:\TCC\Tools\mingw64\8.1.0WIN64"
# 2. 删除旧的 build 目录(清除 CMake 缓存)
Remove-Item -Recurse -Force build
# 3. 重新编译
.\fvg3.bat less_llvm -m full -p cpjxpengEvo -v f30bevo -c Debug -cov on -component ov_lds
6. 关键知识点总结
6.1 为什么必须删除 build 目录?
CMake 在首次配置时会把编译器路径缓存到 CMakeCache.txt。之后即使你修改了环境变量,CMake 也会优先读取缓存,不会重新检测。所以必须删除 build 目录(或至少删除 CMakeCache.txt)让 CMake 重新配置。
6.2 为什么设置 TCC_MINGW64 没用?
因为 less_llvm.py 脚本只检查 MINGW64_HOME,不检查 TCC_MINGW64。变量名必须和脚本里的一致。
6.3 为什么设置环境变量后要重启 PowerShell?
PowerShell 在启动时读取环境变量,之后不会自动刷新。新设置的系统环境变量需要在新的 PowerShell 窗口中才能生效。
6.4 win32 vs posix 线程模型
| 线程模型 | C++11 线程支持 | 适用场景 |
|---|---|---|
| win32 | ❌ 不支持 <thread>, <mutex> 等 | 纯 C 项目或使用 Windows API |
| posix | ✅ 完整支持 | 需要 C++11 多线程的项目 |
7. 排查检查清单
MINGW64_HOME环境变量是否正确设置?- 设置后是否重启了 PowerShell?
- MinGW 是否是 posix 线程模型?(
gcc -v查看) - 是否删除了 build 目录重新编译?
CMakeCache.txt中的编译器路径是否正确?compile_commands.json中的路径是否正确?