ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MSYS2搭建Qt开发环境:MinGW、qwt与OpenCV集成指南

MSYS2搭建Qt开发环境:MinGW、qwt与OpenCV集成指南 简介面向 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 # 单独装cmaketoolchain组里的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.exeC:\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 Creator3.1 用pacman装Qt库与Qt CreatorMSYS2的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是MSYS2Qt这套组合里最常见也是最关键的一步。自动检测不到时把下面几条路径填进去Qt Creator的Kits页面里编译器C对应C:\msys64\mingw64\bin\g.exeC对应gcc.exe调试器对应gdb.exe。Qt版本对应qmake路径C:\msys64\mingw64\bin\qmake.exeCMake命令对应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库编译进exetarget机器上不需要装任何运行环境单文件直接跑。但静态构建有两个前置条件缺一不可第一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和静态Qtfind_package找到哪个完全取决于CMAKE_PREFIX_PATH里的路径先后。静态构建时确保这个变量里只有静态Qt的路径。4.3 两种模式的选型对比对比项动态库模式静态库模式安装包默认的mingw-w64-qt5-base需额外装qt5-staticexe体积几百KB十几MB到几十MB发布文件数exe几十个dll单exe更新Qt版本替换dll即可需重新编译全工程调试体验可直接调试Qt内部代码需额外配符号文件兼容性依赖目标机器VC运行库单文件免依赖我自己的习惯公司内部工具用动态库模式发布包小、出问题好替换dll交付给现场客户的独立软件一定会跑一遍静态构建省去对方工业电脑上缺各种dll的售后电话。5. 避坑清单MSYS2Qt环境里反复出现的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 Designerqwt在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里直接调用官方FindOpenCVcmake_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这个坑我踩过至少三次。希望帮到你。本文还有配套的精品资源点击获取
返回列表