1. 问题背景
1.1 症状
编译 FVG3 项目时报错,提示找不到 <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中的路径是否正确?