简介:面向 Windows 开发者、嵌入式与桌面工程师,这份技术文档系统讲解如何借助 MSYS2 自带的 pacman 包管理器,搭建 MinGW-w64 与 Qt 开发环境:既覆盖 32 位与 64 位两套编译工具链,也说明动态库与静态库两种编译形式的区别与选择;除核心的 Qt 开发库与 Qt Creator 之外,还集成 Qwt 绘图插件、OpenCV 视觉库等常用组件,兼顾科研与工业。文档从 MSYS2 与 MinGW-w64 的渊源讲起,介绍软件源与包管理器更新策略、编译环境变量配置、磁盘空间规划、安装路径选取等实操要点,并对镜像源失败、依赖缺失等常见坑点给出解决提示。资源为单个 docx 文档(约 2.63MB),命令与配置说明清晰,可直接照做,也可作排错参考,已有 549 人下载学习。
1. 为什么绕开Qt在线安装器:MSYS2这条路的真实价值
很多人第一次装Qt开发环境,第一反应都是去Qt官网下载在线安装器,勾选MinGW组件,然后等一个多小时。这套流程本身没毛病,但放到国内网络环境下,在线安装器经常卡在“下载qtbase”这种大组件上,进度条半天不动,重试几次还可能断掉,最后装出来的是一个带着商业授权提示、组件散乱的半成品。而MSYS2是另一条路:它是一个类Unix的软件发行平台,用pacman包管理器直接把MinGW-GCC编译器、Qt库、qwt、opencv这些二进制包全装到本地,所有依赖自动解析,装完直接能在Qt Creator里建Kit编译。
这背后最实在的价值有三个:第一,包管理器解决依赖,不用手动去mingw官网下载GCC再折腾环境变量;第二,二进制包预编译,省掉你自己编译OpenCV和Qwt的时间;第三,32位和64位分别对应独立包名,想双目标构建也不用装两套环境。这篇笔记适合被Qt在线安装器折磨过的人,也适合需要qwt绘图控件和opencv图像库但不想手动编译的C++开发者。
2. 用MSYS2装MinGW:换源、核心包与32/64位共存
2.1 先给pacman换源:装得快才走得下去
MSYS2默认的软件源在国外,直接执行pacman安装时,下载速度能让你怀疑人生。这一步必须先行,否则后面每个包都要等很久。常见做法是编辑/etc/pacman.d/mirrorlist.msys和mirrorlist.mingw64,把清华或中科大的镜像地址顶到文件最前面。
# 备份原始镜像列表 cp /etc/pacman.d/mirrorlist.mingw64 /etc/pacman.d/mirrorlist.mingw64.bak # 删除原文件里的全部镜像源,只保留清华源,避免pacman随机选到慢速源 echo "Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/x86_64" > /etc/pacman.d/mirrorlist.mingw64 # 同步安装源数据库,并强制刷新所有未生效的包 pacman -Sy这里有个容易忽略的点:pacman -Sy只是刷新数据库,不升级系统。如果你在安装时报“无法找到软件包”,多半是源里元数据没更新到,可以再执行一次pacman -Syy强制刷新。
镜像替换完成后,测试一下pacman -S vim这类小包能不能流畅下载。如果卡住,检查mirrorlist.msys是否也替换了——MSYS2自己的工具链(比如pacman本体、bash)走的是msys源,只换mingw源解决不了全部问题,两个源都要处理。
2.2 装MinGW工具链与32/64位选择
MSYS2里MinGW工具链的包名分两套:mingw-w64-x86_64-前缀对应64位,mingw-w64-i686-前缀对应32位。这个命名规则是整个MSYS2环境里理解一切包名的关键,后面装qwt、opencv都是同样的规律。
# 安装64位MinGW编译器全家桶,包含gcc、g++、gfortran、binutils、make、cmake pacman -S mingw-w64-x86_64-toolchain # 单独装cmake,toolchain组里的cmake版本有时候偏旧 pacman -S mingw-w64-x86_64-cmake # 如果需要32位目标,再装一套i686的编译器,两套共存互不干扰 pacman -S mingw-w64-i686-toolchainmingw-w64-x86_64-toolchain是一个虚拟组包,它会把GCC编译器、汇编器、链接器、gdb调试器一次装齐。这里要注意:给用户安装时别图省事只装gcc,因为MSYS2里单独装gcc只会装到msys环境下的编译器,生成的是依赖msys-2.0.dll的Windows程序,跑起来很别扭——必须装mingw前缀的包。
装完之后,C:\msys64\mingw64\bin下会出现gcc.exe和g++.exe,C:\msys64\mingw32\bin下是32位版本。这两套编译器的Windows路径不同、pacman包名也不同,安装在同一台机器上没有任何冲突。
2.3 工具链合法性验证:gcc与cmake版本
装完编译器不是终点,先验证工具链能正常产出Windows原生程序,再往上层搭Qt,否则后面报错会分不清是Qt的问题还是编译器的问题。
# 查看GCC版本,确认是MinGW-W64的构建而非MSYS2原生gcc gcc --version # 写一个最小可执行程序,验证编译链完整 printf '#include <stdio.h>\nint main(){printf("mingw ok\\n");return 0;}\n' > test.c gcc test.c -o test.exe ./test.exe注意gcc的输出是gcc.exe (Rev2, Built by MSYS2 project) x86_64-posix-seh-rev1这种格式。这里我一般会看两点:posix线程模型和seh异常模型。MSYS2的版本是posix-seh,如果你从mingw官网下载的旧版可能是win32-sjlj,两者在C++异常处理和标准线程库支持上有差异。用Qt时如果涉及QtConcurrent或std::thread相关崩溃,先检查是不是混用了不同来源的编译器。
这条验证路走通之后,你已经有了一个干净的MinGW环境。很多人在这一步就急着装Qt,结果Qt Creator里自动检测不到编译器,其实根因在于把PATH里配成了msys目录下的gcc,而不是mingw64目录下的。
3. 在MSYS2里装Qt并配好Qt Creator
3.1 用pacman装Qt库与Qt Creator
MSYS2的Qt包同样按前缀区分位数,而且有Qt5和Qt6两套体系。对于要带qwt和opencv的传统桌面项目,qt5仍是更稳妥的选择——qwt对Qt6的官方支持一直不太积极,装上能用但偶尔有编译告警。命令如下:
# 安装64位Qt5库:widgets模块、gui模块、core网络模块 pacman -S mingw-w64-x86_64-qt5-base mingw-w64-x86_64-qt5-winextras # 安装Qt5的多媒体与图表模块,后面qwt也可能依赖 pacman -S mingw-w64-x86_64-qt5-qtmultimedia mingw-w64-x86_64-qt5-graphicaleffects # 安装Qt Designer独立窗口(界面设计必需) pacman -S mingw-w64-x86_64-qt5-qttools # 安装Qt Creator IDE本体,注意不是mings64前缀包,而是普通msys包 pacman -S qtcreatorpacman -S qtcreator装的是MSYS2维护的Qt Creator,它能自动检测到MinGW编译器。但这里有坑:qtcreator这个包刚装完启动时,默认会用MSYS2的QBS构建系统,或者找不到MinGW套件。打开Qt Creator后,在工具-选项-Kits里检查编译器是否被自动识别,如果识别到上一节装的gcc,直接新建Kit即可;如果识别不到,说明需要手动添加。
Qt5的库文件默认在C:\msys64\mingw64\lib\cmake下提供CMake配置文件,在C:\msys64\mingw64\lib下提供dll库。装完任何qt5的子模块库,都要确认这个目录里出现了对应的qt5XXX.dll,否则说明包没装全。
3.2 Qt Creator里接MSYS2的MinGW编译器
手动配Kit是MSYS2+Qt这套组合里最常见也是最关键的一步。自动检测不到时,把下面几条路径填进去:
Qt Creator的Kits页面里,编译器C++对应C:\msys64\mingw64\bin\g++.exe,C对应gcc.exe,调试器对应gdb.exe。Qt版本对应qmake路径C:\msys64\mingw64\bin\qmake.exe,CMake命令对应C:\msys64\mingw64\bin\cmake.exe。
实际配置里还有个隐蔽问题:如果你之前装过Qt官方在线安装器里的MinGW,那个gcc.exe在D:\Qt\Tools\mingw810_64\bin下,和MSYS2的gcc完全混在一起。Qt Creator会自动扫描到两套编译器,选错一套会导致后面编译出的程序在运行时缺少libgcc_s_seh-1.dll。我有一次就是程序在Qt Creator里跑得好好的,拷到别的机器就闪退,最后发现是两套MinGW的运行时库串了。配置Kit时,务必确认路径是msys64\mingw64开头。
3.3 第一个程序验证平台插件
配好Kit后,第一件事不是写界面,而是跑一个只依赖QWidget的空窗口来验证Qt平台插件。很多人在这里遇到经典的qt.qpa.plugin: could not find the Qt platform plugin "windows"报错,然后开始怀疑环境装坏了。
#include <QApplication> #include <QLabel> int main(int argc, char *argv[]) { QApplication app(argc, argv); // 标签窗口可跨平台,只要platforms插件正常就能显示 QLabel label("MSYS2 Qt works"); label.resize(320, 200); label.show(); return app.exec(); }用Qt Creator直接构建运行,如果程序能弹出窗口,说明platform插件路径被正确加载。如果报平台插件错误,原因基本只有两种:一是PATH里没有C:\msys64\mingw64\bin,导致运行时找不到qwindows.dll依赖的库;二是debug和release目录下缺少platforms/qwindows.dll。
提示:在Qt Creator里运行的前提下,优先查PATH,不要急着去手动拷贝qwindows.dll。因为MSYS2的Qt程序在启动时,会先加载libgcc_s_seh-1.dll、libstdc++-6.dll、libwinpthread-1.dll这些运行时库,这些库都在mingw64\bin下,PATH里没有这一项,platform插件加载自然失败。
4. 动态库与静态库:用MSYS2配出两套构建能力
4.1 动态库模式:默认状态与PATH传递
MSYS2的mingw64安装包,默认全部以共享库(DLL)方式链接。也就是说,你装的mingw-w64-x86_64-qt5-base里,Qt5Core.dll、Qt5Widgets.dll是单独存在的,你的程序exe只记录了对这些dll的导入表。
CMake项目里,动态库构建只需维持默认开关:
cmake_minimum_required(VERSION 3.16) project(shared_demo) set(CMAKE_CXX_STANDARD 17) # BUILD_SHARED_LIBS会传递给add_library,不写就是平台默认(MSYS2下默认ON) set(BUILD_SHARED_LIBS ON) find_package(Qt5 REQUIRED COMPONENTS Widgets) add_executable(app_demo src/main.cpp) target_link_libraries(app_demo Qt5::Widgets)编译完成后,可执行文件旁边不会自动生成各种dll。运行前把C:\msys64\mingw64\bin加入PATH,或者把生成的exe拷到C:\msys64\mingw64\bin目录下运行,否则会报“找不到Qt5Widgets.dll”。
发布动态库程序时,Qt官方有对应工具:在Qt Creator的构建目录里执行C:\msys64\mingw64\bin\windeployqt.exe app_demo.exe,它会自动把需要的Qt库、平台插件、编译器运行时dll全部拷到exe同目录。注意windeployqt不会拷贝第三方库的dll,比如opencv_world.dll,需要自己手动处理。
4.2 静态库模式:-static与mingw的依赖
静态库构建是另一个方向:所有Qt库编译进exe,target机器上不需要装任何运行环境,单文件直接跑。但静态构建有两个前置条件,缺一不可:
第一,MSYS2的mingw64包默认不提供静态库版的Qt。你需要额外安装mingw-w64-x86_64-qt5-static这个包。
第二,CMake里必须找到静态Qt的安装路径,否则find_package会优先匹配到动态库版本。
cmake_minimum_required(VERSION 3.16) project(static_demo) set(CMAKE_CXX_STANDARD 17) # 静态构建必须关掉BUILD_SHARED_LIBS, 否则cmake仍会链接dll导入库 set(BUILD_SHARED_LIBS OFF) # 告诉cmake去静态Qt的cmake配置目录里找包 set(CMAKE_PREFIX_PATH "C:/msys64/mingw64/lib/cmake") find_package(Qt5 REQUIRED COMPONENTS Widgets) add_executable(app_static src/main.cpp) # 静态Qt要求程序接管所有Qt库,必须额外链接winpthread等运行时库 target_link_libraries(app_static Qt5::Widgets -static -static-libgcc -static-libstdc++)这里的-static-libgcc和-static-libstdc++是关键参数,否则GCC的C++运行库仍会以动态dll方式链接,发布时依然要多带三个dll文件。-static告诉链接器优先使用lib*.a静态库而非dll导入库。
提示:MSYS2官方文档里,静态Qt包的位置确实是C:\msys64\mingw64\lib\cmake\Qt5*,它和动态库包在同一个父目录下。此时如果同时装了动态Qt和静态Qt,find_package找到哪个完全取决于CMAKE_PREFIX_PATH里的路径先后。静态构建时,确保这个变量里只有静态Qt的路径。
4.3 两种模式的选型对比
| 对比项 | 动态库模式 | 静态库模式 |
|---|---|---|
| 安装包 | 默认的mingw-w64-qt5-base | 需额外装qt5-static |
| exe体积 | 几百KB | 十几MB到几十MB |
| 发布文件数 | exe+几十个dll | 单exe |
| 更新Qt版本 | 替换dll即可 | 需重新编译全工程 |
| 调试体验 | 可直接调试Qt内部代码 | 需额外配符号文件 |
| 兼容性 | 依赖目标机器VC++运行库 | 单文件免依赖 |
我自己的习惯:公司内部工具用动态库模式,发布包小、出问题好替换dll;交付给现场客户的独立软件,一定会跑一遍静态构建,省去对方工业电脑上缺各种dll的售后电话。
5. 避坑清单:MSYS2+Qt环境里反复出现的5个问题
5.1 qmake能跑但程序报“could not find the Qt platform plugin”
现象:在Qt Creator里构建成功,双击exe报qt.qpa.plugin: could not find the Qt platform plugin "windows",但qmake --version、gcc --version都正常。
原因:PATH里没有C:\msys64\mingw64\bin,程序启动时找不到libgcc、libstdc++和Qt5Core.dll。这个报错被伪装成“平台插件找不到”,实际是程序连最基础的运行库都没加载起来。
解决:在Windows系统环境变量PATH里追加C:\msys64\mingw64\bin,重启Qt Creator。验证方法很简单:在cmd里输入gcc --version,如果提示找不到命令,说明PATH没生效。
5.2 链接期报“cannot find -lpublic”这类库名错位
现象:CMake工程完全照抄网上教程,target_link_libraries里写了opencv_highgui,链接时报cannot find -lopencv_highgui。
原因:MSYS2里OpenCV的包名带位数前缀,lib前缀会生成libopencv_highgui.dll.a文件,但链接器找库时按-lopencv_highgui找的是libopencv_highgui.a(静态库文件名)或者opencv_highgui.dll。MSYS2环境里lib目录下只有dll和它的导入库,没有纯静态lib。
解决:检查C:\msys64\mingw64\lib下实际文件,一般叫libopencv_highgui.dll.a。在CMake里不要手写库名,直接用find_package(OpenCV REQUIRED)生成变量,或者用target_link_libraries(app ${OpenCV_LIBS})。
5.3 32位和64位包混装导致符号错乱
现象:程序编译时正常,运行时崩溃或者找不到某个符号;甚至链接时出现“relocation truncated to fit: R_X86_64_PC32 against symbol”。
原因:MSYS2同一目录下可以共存32位和64位包,但如果一次装包时不注意,用了64位的编译器去链接32位的库,或者反之,就会出现这种错位。尤其麻烦的是,C:\msys64\usr\bin里有一些MSYS2自带的工具,它们既不是纯32位也不是纯64位,一旦PATH顺序先匹配到usr/bin,会用错工具。
解决:装包前确认你要的到底是mingw-w64-x86_64-还是mingw-w64-i686-前缀。Windows PATH里C:\msys64\mingw64\bin必须排在C:\msys64\usr\bin和C:\msys64\mingw32\bin之前,因为这个顺序决定Qt Creator调用gcc时用的是哪一套。
5.4 老项目配新版GCC导致的ABI兼容问题
现象:用MSYS2当前版本GCC 13编译一个基于Qt 5.12的老项目,编译通过了但运行时随机崩溃,或者信号槽连接不上。
原因:MSYS2滚动更新频繁,当前GCC版本和Qt 5.12系列原本配的GCC版本相差过大,C++ ABI在某些边界上出现了不兼容。这不是MSYS2的锅,是任何滚动发行版都会有的问题。
解决:两种方案。一是锁定MSYS2的包版本,在pacman里用IgnorePkg固定GCC大版本;二是换用Qt 5.15 LTS系列,它对新版GCC的适配好得多。我一般会在项目根目录放一个msys2-packages.txt记录当时的包版本列表,方便环境重装时对齐。
5.5 make 和 cmake 的生成器混用
现象:CMake配置时选择“MinGW Makefiles”,但编译时提示sh: mingw32-make: command not found;或者用cmake --build .没问题,直接输make报错。
原因:MSYS2的make是GNU make的MSYS2移植版,CMake生成器默认调用的是mingw32-make.exe,两者不完全等价。MSYS2里可能只装了make,没装mingw-w64-x86_64-make。
解决:装mingw-w64-x86_64-make;或者在CMake配置时明确指定生成器-G "MinGW Makefiles",它会自动去找mingw32-make.exe。
6. qwt与opencv:最后一公里的安装与验证
6.1 用一条命令装好qwt并接进Qt Designer
qwt在MSYS2里有现成包,不用手动编译。安装命令:
# 64位qwt控件库,注意版本号随仓库更新,这里装的通常是6.x系列 pacman -S mingw-w64-x86_64-qwt # 确认qwt的dll已在mingw64/bin下生成 ls /mingw64/bin | grep qwt装完后qwt的插件位置在C:\msys64\mingw64\plugins\designer\qwt_designer_plugin.dll。Qt Creator默认会扫描这个插件目录,如果打开Designer后左侧控件面板里没有QwtPlot,检查Qt Creator的“工具-选项-环境-Paths”-Plugin目录里有没有包含C:\msys64\mingw64\plugins。
qwt在CMake里的链接需要走它自己的cmake配置:
find_package(Qwt REQUIRED) # 链接到qwt库,不手写路径和库名 target_link_libraries(app Qwt::Qwt)注意:MSYS2的qwt包默认构建版本在选择Qt5还是Qt6时可能有差异,如果find_package报告找不到QwtConfig.cmake,去C:\msys64\mingw64\lib\cmake\Qwt目录确认实际文件名。有这个目录但没有生成cmake文件时,多半是你之前的Qt库装得不完整。
6.2 opencv的MSYS2包与一个最小验证程序
OpenCV在MSYS2里同样是预编译二进制包,正常情况下几分钟装完,远比自己编译省事。
# 安装opencv主库(含highgui、imgproc、core) pacman -S mingw-w64-x86_64-opencv装完后lib目录里会出现一大串libopencv_*.dll.a导入库文件,bin目录里有对应的dll。CMake里直接调用官方FindOpenCV:
cmake_minimum_required(VERSION 3.16) project(opencv_test) find_package(OpenCV REQUIRED) add_executable(read_img main.cpp) target_link_libraries(read_img ${OpenCV_LIBS})验证程序写一个最简图像读取:
#include <opencv2/core.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> int main() { // 从文件读图,灰度模式 cv::Mat img = cv::imread("test.jpg", cv::IMREAD_GRAYSCALE); if (img.empty()) return 1; cv::imwrite("out.jpg", img); return 0; }这个程序能跑通,说明动态库的加载、CMake的链接路径、OpenCV头文件路径全都没问题。到这里,MSYS2这套环境已经完整覆盖了Qt、qwt、opencv三条线,而且全部由pacman统一维护,卸载时不会像官网安装器那样留一堆注册表垃圾。
我自己的习惯是把这套环境固定下来:Windows系统更新重装后,按顺序执行三组pacman命令就能恢复全部开发环境,总共不超过半小时。MSYS2的滚动更新有时会破坏某种组合,所以我会定期记录已安装包名清单作为后悔药,遇到新项目就直接用这个清单复现环境,比在官网找历史版本靠谱得多。
最后分享一个细节:在Qt Creator里新建项目时,如果Kit选到了MSYS2的MinGW但构建套件显示红色感叹号,九成是qmake路径选成了msys目录下的qmake。检查qmake路径,确认指向C:\msys64\mingw64\bin\qmake.exe,这个坑我踩过至少三次。希望帮到你。
本文还有配套的精品资源,点击获取