windows中使用MSYS2作为编译链工具注意事项
一、抛弃vcpkg选择MSYS2的原因
本来,我的初衷是在项目中使用grpc和protobuf来实现不同工控机间的通信,但是新版grpc和protobuf的编译过于困难(编译时间长、依赖复杂以及github时常连接失败),让我不得不去寻找一个简便的方法使用该库。在尝试了vcpkg后,我实在受不了那龟速的下载速度以及杂乱的编译流程,便转而将目光投向了MSYS2上,在折腾了一天后,便有了这篇文章。
二、MSYS2安装使用grpc
使用下列命令安装:
# 查询包
pacman -Ss grpc
# 安装
pacman -S mingw-w64-ucrt-x86_64-grpc
关于 utrc64版本与 mingw64版本的区别(来自DeepSeek):
MSYS2 提供了多种工具链环境,其中 UCRT64 和 MINGW64 是最常用的两种。它们的核心区别在于底层使用的 C 运行时库(C Runtime Library) 和 目标系统兼容性 。以下是关键区别对比:
1. 运行时库(核心区别)
特性 MINGW64 UCRT64 C 运行时库 (CRT) 传统 msvcrt.dll(旧版 Windows 兼容)现代 ucrtbase.dll(Windows 10+ 标准)C++ 标准库 libstdc++-6.dll(GCC)libstdc++-6.dll(GCC)来源 MinGW-w64 项目 微软官方 Universal CRT
2. 系统兼容性
特性 MINGW64 UCRT64 最低 Windows 版本 Windows XP Windows 10 旧系统兼容性 ✅ 支持旧系统(如 Win7) ❌ 仅 Win10+(需手动安装 UCRT 补丁) 新系统优化 基础兼容 ✅ 原生支持 Win10/11 新特性
3. 工具链特性
特性 MINGW64 UCRT64 C11/C17 标准支持 部分支持(旧 CRT 限制) ✅ 完整支持 Unicode 处理 依赖 libiconv✅ 原生 UTF-8 支持(无转换开销) 路径分隔符 /(Unix 风格)“(Windows 风格) 环境变量 继承 MSYS2 环境 更接近原生 Windows
4. 使用场景推荐
场景 推荐工具链 原因 兼容旧版 Windows ✅ MINGW64 无需额外运行时,支持 Win7/XP Win10/11 开发 ✅ UCRT64 原生支持新 API,更好的性能 跨平台项目移植 ✅ MINGW64 路径/行为更接近 Unix,减少移植成本 依赖现代 C 特性 ✅ UCRT64 完整支持 C11/C17 标准
5. 实际使用差异示例
编译命令对比
# MINGW64 编译(传统路径) g++ -o app.exe app.cpp -I/mingw64/include -L/mingw64/lib # UCRT64 编译(Windows 风格路径) g++ -o app.exe app.cpp -IC:/msys64/ucrt64/include -LC:/msys64/ucrt64/lib运行时依赖
- MINGW64 程序:需
libgcc_s_seh-1.dll+libstdc++-6.dll+libwinpthread-1.dll- UCRT64 程序:需
ucrtbase.dll+libstdc++-6.dll+libgcc_s_seh-1.dll总结 选 MINGW64 如果:
- 需要兼容 Windows 7/8 或旧系统
- 项目依赖传统 MinGW 库
选 UCRT64 如果:
- 仅面向 Windows 10/11
- 需要完整 C11/C17 支持
- 追求更好的性能和现代 API
⚠️ 重要提示:避免混合使用两种环境编译的库!同一项目的所有依赖必须使用同一工具链编译,否则会出现 clock_gettime64等符号冲突错误。
三、在clion中使用MSYS2
首先添加工具链:

然后修改cmake的工具链,并添加cmake选项,将CMAKE_PREFIX_PATH定位到utrc所在目录:

做完上述步骤后就可以使用了。
注意事项:
在cmake中,如果使用了find_package(gRPC REQUIRED),不要在前面再次find_package(Protobuf REQUIRED),否则会报错:
CMake Error at D:/Environment/MSYS2/ucrt64/lib/cmake/protobuf/protobuf-targets.cmake:42 (message):
Some (but not all) targets in this export set were already defined.
Targets Defined: protobuf::libprotobuf-lite, protobuf::libprotobuf,
protobuf::libprotoc, protobuf::protoc
Targets not yet defined: protobuf::libupb, protobuf::protoc-gen-upb,
protobuf::protoc-gen-upbdefs
这是由于包重定义,导致冲突:grpc的包会自动寻找protobuf,如果在之前就包含protobuf包,会出现版本不匹配的问题。
四、在vs中使用MSYS2
vs中配置cmake项目使用MSYS2的方法是需要额外配置一个文件,具体如下:
在vs中新建一个cmake项目,结构如下:

要使用MSYS2,需要修改CMakePresets.json文件:
{
"version": 3,
"configurePresets": [
{
"name": "MSYS2-UCRT64-Base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "D:/Environment/MSYS2/ucrt64/bin/gcc.exe",
"CMAKE_CXX_COMPILER": "D:/Environment/MSYS2/ucrt64/bin/g++.exe",
"CMAKE_MAKE_PROGRAM": "D:/Environment/MSYS2/ucrt64/bin/ninja.exe",
"CMAKE_RC_COMPILER": "D:/Environment/MSYS2/ucrt64/bin/windres.exe"
},
"environment": {
"PATH": "D:/Environment/MSYS2/ucrt64/bin;%PATH%"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "ucrt64-debug",
"displayName": "UCRT64 Debug",
"inherits": "MSYS2-UCRT64-Base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_C_FLAGS": "-g",
"CMAKE_CXX_FLAGS": "-g"
}
},
{
"name": "ucrt64-release",
"displayName": "UCRT64 Release",
"inherits": "MSYS2-UCRT64-Base",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"CMAKE_C_FLAGS": "-O3",
"CMAKE_CXX_FLAGS": "-O3"
}
}
],
"buildPresets": [
{
"name": "ucrt64-debug",
"configurePreset": "ucrt64-debug",
"displayName": "Build UCRT64 Debug"
},
{
"name": "ucrt64-release",
"configurePreset": "ucrt64-release",
"displayName": "Build UCRT64 Release"
}
]
}
然后就可以使用了。