当前位置: 首页 > news >正文

将 qt 构建为静态库

接以前的博客

之前失败了,现在成功了。
静态链接 qt 失败

配置

使用 ps1 脚本进行配置和构建

$env:CC = "clang"
$env:CXX = "clang++"$skiped_modules = @("qttools""qtdoc""qttranslations""qtlanguageserver""qtdeclarative""qtquicktimeline""qtquick3d""qtgraphs""qtlocation""qtlottie""qtmqtt""qtopcua""qtquick3dphysics""qtquickeffectmaker""qtvirtualkeyboard""qtwebengine""qtwebview"
)Invoke-Expression "../configure.bat -static -skip $($skiped_modules -join ",") -prefix ${install_path}"
if ($LASTEXITCODE)
{throw "$source_path 配置失败"
}cmake -G "Ninja" $source_path `-DCMAKE_C_COMPILER="clang" `-DCMAKE_CXX_COMPILER="clang++" `-DCMAKE_C_STANDARD=17 `-DCMAKE_CXX_STANDARD=20 `-DCMAKE_BUILD_TYPE=Release `-DCMAKE_INSTALL_PREFIX="${install_path}"if ($LASTEXITCODE)
{throw "$source_path 配置失败"
}ninja -j12
if ($LASTEXITCODE)
{throw "$source_path 编译失败"
}ninja install
  • 因为构建老是失败,所以我跳过了一些模块。
  • 构建为静态库地要点是配置时添加 -static 选项。

手动链接

静态链接 qt 时需要手动额外链接一些库,否则会链接错误。下面是我链接的库

target_link_libraries(${target_name} PUBLICsetupapizsynchronizationpcre2-16double-conversionntdllversionharfbuzzb2zstdnetapi32authzws2_32winmmuserenvdwritepngmd4cd3d12dxgid3d11wtsapi32imm32freetypeshcoredwmapid3d9shlwapiruntimeobjectuxtheme
)

此外,还要链接 qt5/plugins/platforms/libqwindows.a

Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);

最终的可执行文件项目要添加如下代码

#include "QtPlugin"Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);

这个宏展开后是:

extern ::QStaticPlugin const qt_static_plugin_QWindowsIntegrationPlugin();namespace
{struct StaticQWindowsIntegrationPluginPluginInstance{StaticQWindowsIntegrationPluginPluginInstance(){qRegisterStaticPluginFunction(qt_static_plugin_QWindowsIntegrationPlugin());}};StaticQWindowsIntegrationPluginPluginInstance staticQWindowsIntegrationPluginInstance;
} // namespace

首先声明了一个函数,然后在匿名命名空间中定义了一个 StaticQWindowsIntegrationPluginPluginInstance 类,在构造函数中会调用

qRegisterStaticPluginFunction(qt_static_plugin_QWindowsIntegrationPlugin());

然后在匿名命名空间中定义了 StaticQWindowsIntegrationPluginPluginInstance 类的对象。

也就是说任何包含了下面这段代码

#include "QtPlugin"Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);

的翻译单元都会声明一次函数,然后创建一个匿名命名空间中的 StaticQWindowsIntegrationPluginPluginInstance 类的对象,利用构造函数去注册所声明的函数。

如果多个翻译单元都包含了这段代码,就会有多个匿名命名空间中的 StaticQWindowsIntegrationPluginPluginInstance 类和它们的对象,造成不必要的代码膨胀。所以这段代码只在一个翻译单元中包含一次就够了,但是不能是在静态库的翻译单元中包含这段代码以期望能够注册 qt 模块,因为静态库中的对象的构造函数不会执行,这个匿名命名空间中的 StaticQWindowsIntegrationPluginPluginInstance 类和它的对象会被链接器丢弃。

所以,最好是在最终的可执行文件项目中的其中一个翻译单元包含一次这段代码。例如可以放在 main.cpp 中。

进行了上述操作后,就可以静态链接 qt 库了,此时已经不需要 qwindows.dll 这个动态库插件了。

http://www.lryc.cn/news/604712.html

相关文章:

  • BGP高级特性之正则表达式
  • vue npm install卡住没反应
  • ISO 26262 汽车功能安全(腾讯混元)
  • 在 CentOS 系统上安装 Docker
  • Kotlin -> Kotlin Lambda 表达式与 Function 接口的关系
  • 深入理解 Kotlin Flow:异步数据流处理的艺术
  • 在线教育场景下AI应用,课程视频智能生成大纲演示
  • Jupyter Notebook 中显示图片、音频、视频的方法汇总
  • Python 使用pandas库实现Excel字典码表对照自动化处理
  • C++:STL中list的使用和模拟实现
  • 《C++二叉搜索树原理剖析:从原理到高效实现教学》
  • CH347使用笔记:CH347作为FPGA下载器的几种方式
  • 大语言模型API付费?
  • 【PZ7020-StarLite 入门级开发板】——FPGA 开发的理想起点,入门与工业场景的双重优选
  • PyTorch API
  • PyTorch 生态四件套:从图片、视频到文本、语音的“开箱即用”实践笔记
  • 汽车电子控制系统开发的整体安全理念
  • 为什么网站需要高防IP?高防IP的优势是什么?
  • 打造高效、安全的期货资管交易平台:开发流程与关键要素解析
  • 企业级应用安全传输:Vue3+Nest.js AES加密方案设计与实现
  • 开发避坑短篇(9):解决升级Vue3后slot attributes废弃警告
  • 从黑箱到理解模型为什么(模型可解释性与特征重要性分析)
  • 力扣54:螺旋矩阵
  • git rebase 操作记录
  • 《Java 程序设计》第 11 章 - 泛型与集合
  • chukonu阅读笔记(2)
  • 【LY88】双系统指南及避坑
  • 阿里云AI代码助手通义灵码开发指导
  • 【读书笔记】设计数据密集型应用 DDIA 第三章:存储与检索
  • OPCap:Object-aware Prompting Captioning