Qt 程序發布指南


Qt 程序發布指南

威武的濤哥 的博客文章地址 https://jaredtao.github.io/2019/09/02/Qt%E5%AE%9E%E7%94%A8%E6%8A%80%E8%83%BD6-%E7%A8%8B%E5%BA%8F%E5%8F%91%E5%B8%83%E6%8C%87%E5%8D%97/

知乎文章地址 https://zhuanlan.zhihu.com/p/80919147

 

簡介

本文是《Qt實用技能》系列文章的第六篇,濤哥在這里討論發布Qt應用程序的知識點。

(第五篇《Qt實用技能5-掌握信號槽使用細節》還在整理中,過幾天會發)

背景

有很多人向濤哥詢問,Qt程序發布的相關問題,網絡上雖然可以搜到一大堆教程,但是可靠的比較少。

所以這次盡我所能,全面、詳細地整理一些Qt程序發布的知識點,希望能幫助到更多人。

對老手來說,很多坑都踩過了,無非就是把正確的dll放在正確的路徑。

對新手來說,細節上能多說幾句,都將是莫大的幫助,少走彎路,節省幾個小時、甚至幾天都是有可能的。

如果有疏漏、錯誤,也歡迎大家補充、指正。

Qt的安裝

Qt官網下載地址在這: http://download.qt.io/official_releases

離線安裝包 或者 在線安裝包 都行。

關於Qt版本的選擇,濤哥建議:

體驗新特性,就用最新版本;項目開發,用長期支持版(LTS)的最后一個修正版本,穩定、bug最少。

可以在Qt官方wiki上查看相關信息 https://wiki.qt.io/Main

目前為止(2019/9/2),最新版為5.13.0,LTS版本有5.9 和 5.12, 而5.9最后一個修正版本是5.9.8, 5.12則是到5.12.4

例如上圖是5.9.8的離線安裝包,提供了windows、mac以及linux三種系統的可執行程序。

其中windows的安裝程序”qt-opensource-windoiws-x86-5.9.8.exe”, 大小有2.4G,里面

包含了msvc_x86、msvc_x64、mingw、Android等多個版本的Qt工具鏈。在下載完成,安裝

過程中可以分別勾選。其它版本也是類似的。

如何安裝Qt,就不細說了,搞不定的去參考入門級教程吧…

Qt的目錄結構

這里假設大家都裝好了Qt,先來了解一下Qt的安裝路徑都有哪些東西。

濤哥用的是Windows 10系統,安裝的Qt版本是5.12.4,以此為例來說明,其它系統和版本以實際為准。

Qt安裝路徑

濤哥安裝在了D:\Qt\Online 路徑下, 如圖:

其中“vcredist”文件夾包含了msvc2015 和 msvc2017的運行時庫安裝程序(后面會說怎么用,不是msvc編譯器不需要)

“Tools”文件夾,包括QtCreator、OpenSSL庫(可選)以及兩種版本MinGW(可選)。

(圖中還有Qt3DStudio,可忽略)

“5.12.4”文件夾,是Qt的核心路徑, 里面包含多個版本的Qt工具鏈、頭文件、動態鏈接庫等

這里濤哥安裝了msvc2017、msvc2017_64、mingw73_64以及android_x86.

注意msvc2017是x86架構的Qt庫,msvc2017_64則是x64架構的。

如果有msvc2013、msvc2015也同理。

Qt核心路徑

接下來看一下重點,Qt的核心路徑, 以msvc2017_64文件夾為例

bin文件夾包含了Qt提供的各種工具exe程序,以及動態鏈接庫的dll

其中工具包括qmake.exe 和 windeployqt.exe,windeployqt.exe是我們今天主要討論的工具。

動態鏈接庫全部是兩份dll,比如Qt5Cored.dll和Qt5Core.dll,文件名末尾帶’d’表示debug版本的,另一個不帶’d’的是release版本。

debug版本和release版本的主要區別:debug沒有開編譯器優化、攜帶了調試信息,release開了編譯器優化O2,去掉了多余的信息

(圖中還有pdb文件,是濤哥單獨安裝的,用來調試Qt源碼,可以忽略)

和bin同級的,還有plugins文件夾,包含一些Qt用到的插件

比如imageformats文件夾中提供了jepg、gif、webp等圖片格式的功能支持的插件,platforms文件夾則提供了平台插件,特別是

qwindows.dll這一個,在windows平台是必不可少的。

和bin同級的,另外一個文件夾是’qml’文件夾,包含Qml的各種功能模塊。

和bin同級的其它文件夾,resources是WebEngine模塊專用的,translations提供了

Qt內置的翻譯文件,剩下的和發布無關,就不多說了。

HelloDeploy

這里新建一個簡單的Hello World程序,名字就叫”HelloDeploy”。

同時為了說明問題,濤哥添加一些常用的模塊。

在pro文件中,QT += 那一行該寫的都寫上:

在main.cpp中包含一下各個模塊的頭文件,再分別創建一個對象實例,調用一些簡單的函數:

這樣一個多模塊依賴的程序就寫好了。

Window編譯和發布

Window 編譯

這里要特別注意,編譯器的選擇, 以及編譯用的是debug模式還是release模式。

濤哥這里是msvc2017_x64版本

一般發布用release模式。

編譯完成后,默認在build-xxxx-release/release/文件夾中會生成我們的exe程序。

我們將這個exe復制出來,新建一個release文件夾,放進去

這時候可以嘗試雙擊運行它,會提示缺少dll

Window 發布

發布程序,其實就是把exe程序依賴的dll和相關資源都放在一起,保證雙擊運行即可。

我們前面提過的windeployqt.exe,是Qt提供的命令行工具,能幫助我們自動把需要的dll或資源復制過來。

  1. 我們先打開一個命令行

可以從開始菜單找到Qt提供的命令行

注意選對版本。這種命令行在啟動時已經設置好了QT的環境變量,可以直接輸入windeployqt.exe

也可以用普通的命令行,使用windeployqt.exe時帶上絕對路徑即可。

濤哥一般用普通的命令行,因為絕對路徑不易出錯。

  1. cd到release目錄

這里說一個windows啟動命令行的小技巧:在release文件夾中,按住鍵盤shift鍵,然后按鼠標右鍵,彈出的右鍵菜單,

會比普通的右鍵菜單多一個“在此處打開命令窗口”,點擊就能在release文件夾打開命令行窗口。

如果沒有這個功能,就得手動輸入cd指令,進入release路徑。

  1. 執行windeployqt命令

這里通過絕對路徑來使用windeployqt:

d:\qt\Online\5.12.4\msvc2017_64\bin\windeployqt.exe HelloDeploy.exe

HelloDeploy這個程序還用到了Qml,用到Qml的程序,要給windeployqt加上qmldir參數,寫上相應的msvc2017_64\qml文件夾

(沒用到qml的程序,不要加這一步)

d:\qt\Online\5.12.4\msvc2017_64\bin\windeployqt.exe HelloDeploy.exe –qmldir d:\qt\Online\5.12.4\msvc2017_64\qml

寫好windeployqt命令后按回車執行

正確執行后,release文件夾下,多了很多dll,以及一些文件夾。

這時候我們雙擊運行HelloDeploy.exe, 就可以正常啟動了。

將整個文件夾壓縮或拷貝到其它沒有Qt環境的電腦上,也是可以啟動的。

只要dll齊備了,制作安裝包也不是問題。(后續有時間,我再寫安裝包制作的教程)

VS運行時庫

如果是VS編譯的程序,需要將QT路徑下對應的vcredist_xxx.exe帶上。

如果其它電腦上有vs運行時則可以直接運行,如果沒有,就需要運行一下vs運行時安裝包。

經常玩一些單機游戲的同學應該都知道這個問題。

有的電腦環境特殊,可能運行時庫無法安裝上去,這時候需要一些變通的方法,

直接將運行時庫安裝包里面的dll復制出來即可。

怎么取出來?在能安裝的電腦上裝一遍,然后就有dll了,名字是vcruntime140.dll、

msvcp140.dll之類的,這里就不展開說了。

常見的錯誤處理

一般使用windeployqt,大部分庫都能自動拷貝,不需要手動處理,

只有極少數情況下,windeployqt跑完,會缺失一些庫,還要手動處理一下。

遇到這種情況,用依賴檢查工具Dependencies即可快速定位問題。

Dependencies下載鏈接: https://github.com/lucasg/Dependencies

下面列舉一些常見的錯誤信息

應用程序無法正常啟動

最容易出現這種錯誤的情況是,程序是64位編譯出來的,而同級目錄下的dll是32位的,

或者同級目錄下沒有dll,但是環境變量中指向了32位的dll。(所以濤哥沒有設置環境變量)

32位和64位倒過來也是。

如果dll版本是匹配的,還有可能出現的情況是缺少第三方庫。

這里說一個檢查依賴的方法:

將HelloDeploy.exe重命名為HelloDeploy.dll,然后用Dependencies打開,就可以查看少哪些庫

如上圖,紅色問號的表示缺少的庫。

找齊了依賴的庫,再把程序的擴展名改回exe即可。

啟動失敗 - no Qt platform plugin

這種情況,是QT路徑下的 plugins/platforms/qwindows.dll文件沒有復制過來。

注意這個dll文件直接復制到exe同級是不起作用的,要放在exe程序同級的platforms文件夾里,或者同級

的plugins/platforms文件夾里

OpenGL Context 創建失敗

這種情況,一般是OpenGL相關的庫沒有復制過來,補上就好了

整理

我們看到,exe同級目錄下,windeployqt將一堆的文件夾放在了那里,有些混亂。

濤哥觀察並驗證了一下,其實可以做個簡單的整理。

Qt開頭的文件夾都是qml的模塊,剩下的文件夾除了translations都是Qt的插件,

所以新建兩個文件夾qml和plugins, 分別把qml模塊和插件歸入其中。

這樣的結構,和QT安裝路徑下的結構是相似的。

這也正是Qt支持的插件加載路徑、qml模塊加載路徑。

同級的dll則是windows系統默認的動態庫加載規則,不方便修改

可以參考msdn:

https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order

簡單裁剪

如果你熟悉Qt的各個模塊,可以進行一些裁剪。以下都是些個人經驗。

不熟悉請慎重!

不熟悉請慎重!

不熟悉請慎重!

(當然靜態編譯也是一種裁剪的途徑)

刪減dll

首先可以把單元測試的dll去掉

Qt5Test.dll

Qt5QuickTest.dll

如果沒用到windows擴展,Qt5WinExtras.dll也可以去掉

其次,如果你不需要內置的翻譯文件,translations文件夾也可以刪掉

刪減plugins

再來看一下plugins:

其中platforms是必不可少的,剩下的HelloDeploy都沒用到,可以去掉。

常見程序會用的包括:

imageformats 圖片格式支持

iconengines 小圖標功能

sqldrivers 數據庫驅動,這個保留用到的數據庫足夠了

其他的看情況刪減。

刪減qml

最后看一下Qml文件夾,如果程序完全沒用qml,直接刪掉就好了。

按windeployqt給HelloDeploy提供的這些,逐個文件夾來說:

  • Qt/labs 一般不推薦Qml中引入labs中的實驗品,但是有些情況下功能缺失,只能引入。

如果Qml中使用了Quick.Dialog(不是labs.Dialog),它本身還是依賴的labs中的東西,一般是folderlistmodel和settings,

這時候還是不要動labs了,就按照windeployqt給的放着。

  • Qt/WebSockets Qml的Websocket功能,用了就放着,沒用可以刪掉。

  • QtGraphicalEffects Qml的一些ShaderEffect特效,用了就放着,沒用到可以刪掉

  • QtMultimedia Qml的多媒體模塊,用了就放着,沒用到可以刪掉

  • QtQml/Models.2 數據Model, 經常用。

  • QtQuick 這里面大部分都是Qml中常用的,QtQuick/Extras可以按情況刪掉

  • QtQuick.2 常用的

  • QtTest 單元測試,刪掉吧

  • QtWinExtras Windows擴展,沒用到可以去掉

 

=========================================

來源 https://blog.csdn.net/liyuanbhu/article/details/60147904

參考 http://hgoldfish.com/blogs/article/103/

 

Qt4.4 引入了 Webkit 方便程序員往自己的程序里面嵌入 HTML 頁面。剛開始倒也沒事,反正不主動包含到項目里面的話,程序安裝包並不會變大。那會兒,Qt 程序只要 8M(壓縮到3M)就搞定了。到了 Qt5 的時候 Webkit 換成了 Chromium 內核 Blink,名字改成了 QtWebEngine. Qt 開發者發現 Blink 使用的 ICU,提供了比舊版本 Qt 更完整的國際化能力。於是,據說是因為一個誤會,Qt 開發者就在 Qt 5.0 里面強制依賴於 ICU 了。這個 ICU 包含了大量的國際化元信息,一下子增長了近 30M 的容量。。

導致 Qt 容易增長還有另外一個重要原因,也就是 Qt 自從 4.7 以后引入的 QML。這是一個基於 ECMAScript 改造的語言。從此以后,Qt 開發就有兩種流派,一者使用原來的 C++ 語言進行開發,另外一種使用 QML 語言進行開發。兩者共享一樣的底層設施,比如各種數據結構與事件循環 QtCore 和 帶有 OpenGL 支持的 QtGui。但在上層,Qt 為 C++ 開發者們提供了 QtWidgets,又為 QML 開發者提供了獨立的 QtQuick.

QtQuick 本身只有簡單的布局語言,Qt 又在這個基礎上提供了 QtControls 模擬 Android,iOS 和 Windows 程序的外觀。早期的 Qt5 沒有設計好,導致使用 QML 時要引入一大堆程序可能用到的組件。所以一個 helloworld 下來,相當巨大。而且很奇怪的事,以 QtWidgets/C++ 的方式使用了 QtWebEngine 的話,也會引入幾乎所有的 QML 模塊,那會兒一個簡單的程序會達到一百多兆的大小!

Windows 平台還有一個特殊的問題。現在 Qt 的圖形架構調用 OpenGL ES 2.0 進行底層的渲染,但剛安裝完的 Windows 只支持到 OpenGL 1.1,針對這個問題,早期的 Qt 在 configure 階段提供了兩種選項,一是使用與 Chromium 一樣的 ANGLE,把 OpenGL 調用翻譯成 DirectX 調用,二者假定用戶的系統安裝了顯卡驅動,能夠支持 OpenGL 2.0。前者需要包含幾個 ANGLE 的 DLL,直接又增加了 17M 的容量!

所幸這些事情現在都解決了。

首先,Qt 5 的早期版本已經提供了一個 configure 選項,可以不把 ICU 編譯到 Qt 里面,但是官方下載版本仍然默認包含 ICU,后來 Qt 直接去掉了對 ICU 的依賴。現在的 Qt 在運行時找到 ICU 的 DLL 就會使用 ICU,否則調用系統的 API,如果都沒有,就湊合着用 Qt 內置的算法處理國際化。

其次,QML 一些奇怪的依賴現在也去掉了。所以現在無論使用 QtWidgets 還是使用 QML,未壓縮時都只有 20M 左右的容量。

最后一個,現在有多少用戶的電腦是沒有安裝顯卡驅動的呢?好吧,好像還真有,vmware 的虛擬機。但我覺得正常直接用系統自帶的 OpenGL 驅動足矣。Qt 現在會在運行的時候自動探測 ANGLE 是否存在,如果存在,就使用 ANGLE,如果不存在,就使用系統自帶的 OpenGL,不必像以前那樣在 configure 階段就配置好。另外,QtWidgets 沒有使用 OpenGL,所以使用 QtWidgets/C++ 的程序也可以把 ANGLE 的 DLL 都去掉。

用 Qt 5.7 來說,現在提供了一個名為 windeployqt.exe 的程序,位於 Qt 的 bin 目錄里面。運行這個程序,后面帶程序名稱就行了:

  1. 創建一個 dist 目錄
  2. 把編譯好的 qttest.exe 復制到 dist 目錄。
  3. 打開 cmd.exe,cd 到 dist 目錄
    4.1 運行 c:\qt5\bin\windeployqt.exe qttest.exe
    4.2 對於 QML 程序,需要指定 QML 目錄: c:\qt5\bin\windeployqt.exe –qmldir d:\qttest qttest.exe

這時候就會看到 qt 已經把需要用到的 DLL 都復制過來了。我會在這個基礎上再根據需要去掉一些東東:

  1. libEGL.dll, libGLESV2.dll 這兩個文件是 ANGLE 的文件,可以去掉。opengl32sw.dll 是軟件模擬 OpenGL,除非用戶的系統連 DirectX 支持都不完整——虛擬機環境就是這樣——不然這個文件也完全沒有用。 QtWidgets/C++ 程序都不用 OpenGL,所以直接去掉即可。可在調用 windeployqt.exe 時加”–no-angle” 和 “–no-opengl-sw” 這兩個參數。
  2. 如果沒有使用 svg 的話,iconengines\qsvgicon.dll, imageformats\qsvg.dll, Qt5Svg.dll 這三個文件也可以刪掉
  3. 如果沒有國際化用戶的話,translations 里面的翻譯文件也可以刪掉。
  4. QML 程序沒有使用 QtWidgets/C++ 可以刪掉 Qt5Widgets.dll
  5. 如果 imageformats 目錄里面有幾種圖像格式沒用上,也可以刪掉。我自己通常把整個目錄都刪掉,Qt已經編譯了 png 的支持,能讀寫程序包含的圖標就夠,其它格式不重要。
  6. qmltooling 和 Qt5Network.dll 是用於 QML 調試用的,可以刪掉。

經過以上裁剪,使用 7zip 壓縮完以后,一個 QtWidgets/C++ helloworld 程序最終只剩下 5.64M,一個 QtControls 程序是 5.86M, QtQuick 程序還會更小一些。

 

附注:

截止本文寫作時,Qt 5.8 已經發布了。在這個版本里面,不再依賴於 OpenGL ES 2.0,而是繞過 ANGLE,直接調用 DirectX 渲染,到 Qt 5.10 還要直接支持 Vulkan API。不過目前仍然是試驗性的,有興趣的話可以看看 configure 的說明。

新的 Qt 5.8 重寫了 configure 系統,能夠更深入地裁剪 Qt。最小未壓縮 5M 即可布署一個 QML 程序。

參考資料:

Qt 5 ICU
https://wiki.qt.io/Qt_5_ICU
http://wiki.qt.io/Qt-5-QLocale

Dynamically Loading Graphics Drivers
http://doc.qt.io/qt-5/windows-requirements.html

Qt Lite
http://blog.qt.io/blog/2017/01/23/qt-5-8-released/

 

============== End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM