使用MSYS2的静态Qt版本进行Widgets项目编译时需要注意的问题

项目场景:

需要编译一个静态版本的应用程序,并用upx进行压缩,以便减少携带的动态链接库,生成每个文件不超过10MB的轻量级绿色发布包。使用动态库不利于发布。准备发布的环境,是学校的教学中心的学生计算机。学生计算机的每一台机器都可能安装有不同版本的Qt,且时常污染环境变量(PATH),导致链接了其他版本Qt的程序启动时遇到问题。不能为每一种Qt发布包编译一个发行版。


问题描述

当使用 MSYS2 Mingw64 Qt6 static 进行编译的时候,无论 qmake 还是 cmake,都会报错。

QMAKE 会报链接错误:

txt 复制代码
... undefined reference to `__imp_mng_get_userdata'
......

CMake 也会报错:

txt 复制代码
CMake Error in CMakeLists.txt:
  IMPORTED_IMPLIB not set for imported target "harfbuzz::harfbuzz"
  configuration "Release".

原因分析:

MSYS2 的Qt静态发行版并没有完全遵循"静态链接"的要求。很多库依旧需要用动态链接的资源来引入。这种不一致性使得Qt为主流win32静态连编(如VC编译器)准备的库编译脚本、客户程序构建脚本,不适用于MSYS2静态编译环境。客户程序还需要加入额外的信息,以链接相关的库。


解决方案:

通过搜索缺失的函数入口所对应的库,可以较快找齐所有的依赖。

  1. 对QMAKE,建议加入:
qmake 复制代码
#################### taskbusplatform.pri
#Qt6 Widgets static link in MSYS2 need extra dependencies.
contains(QT, widgets){
MSYSTEM_PREFIX=$$(MSYSTEM_PREFIX)
greaterThan(MSYSTEM_PREFIX,' '){
contains(CONFIG, static) {
	message("STATIC Qt6 with MSYS2. Extra patch should be introduced.");
	QMAKE_LIBS += -ltiff  -lmng.dll -ljpeg -ljbig -ldeflate  -lzstd -llerc -llzma  -lgraphite2 -lbz2 -lusp10 -lRpcrt4 -lsharpyuv -lOleAut32
}
}
}


########################submodules
QT       += core gui network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
include (../../../taskbusplatform.pri)

注意,如果不想使用pri文件,则需要在每个widgets项目都包含这个配置。也可以放在pri文件里一并包含

  1. CMake
    由于CMAKE会记忆构建树的历史变量,相对较为方便。在所有子项目开始前,执行下面这段脚本
cmake 复制代码
#FIX MINGW64 Qt6 static link problems.
find_package(QT NAMES Qt6 COMPONENTS Core Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets  REQUIRED)
if (QT_FEATURE_static STREQUAL "ON" AND WIN32 AND MINGW)
	set_property(TARGET harfbuzz::harfbuzz PROPERTY
				 IMPORTED_IMPLIB ${harfbuzz_DIR}../../../libharfbuzz.dll.a )
endif()

参考:

MINGW-packages issue 18966

相关推荐
朝九晚五ฺ4 分钟前
从零到实战:鲲鹏平台 HPC 技术栈与并行计算
java·开发语言
CUIYD_19895 分钟前
Freemarker 无法转译 & 字符
java·开发语言·spring
superman超哥13 分钟前
Rust Vec的内存布局与扩容策略:动态数组的高效实现
开发语言·后端·rust·动态数组·内存布局·rust vec·扩容策略
Evand J16 分钟前
【MATLAB例程,附代码下载链接】基于累积概率的三维轨迹,概率计算与定位,由轨迹匹配和滤波带来高精度位置,带测试结果演示
开发语言·算法·matlab·csdn·轨迹匹配·候选轨迹·完整代码
Yuiiii__17 分钟前
一次并不简单的 Spring 循环依赖排查
java·开发语言·数据库
野槐19 分钟前
java基础-面向对象
java·开发语言
遇见~未来31 分钟前
JavaScript构造函数与Class终极指南
开发语言·javascript·原型模式
foundbug99943 分钟前
基于MATLAB的TDMP-LDPC译码器模型构建、仿真验证及定点实现
开发语言·matlab
X***07881 小时前
从语言演进到工程实践全面解析C++在现代软件开发中的设计思想性能优势与长期生命力
java·开发语言
毕设源码-钟学长1 小时前
【开题答辩全过程】以 基于Python的车辆管理系统为例,包含答辩的问题和答案
开发语言·python