談談 Qt 程序安裝包的大小竟终,以及簡要打包指南

(本文是水木社區(qū)KDE與Qt編程技術版版主的文章,我覺得寫的很好克懊,就轉載過來了,原文地址:http://hgoldfish.com/blogs/article/103/

經称咧看到網上有些論調說 Qt 程序無比龐大谭溉,甚至拿 .NET 程序來比,說 Qt 程序打包以后跟 .NET 安裝包差不多大橡卤。由此影響了很多人對 Qt 的選擇扮念。我覺得有必要對此做一些澄清——

顯然這個說法是錯誤的!碧库!

很容易理解柜与,雖然 Qt 提供了很多組件,但并非所有的組件都會被程序使用嵌灰,也并非所有的組件都需要打包到程序安裝包里面弄匕。以 Qt 5.7 為例,一個可以正常使用的 helloworld.exe 程序未壓縮不過 20M沽瞭,使用 lzma 壓縮算法迁匠,壓縮率 25%,壓縮完才 6M驹溃!

那盛傳的 Qt 上百 M 的容量又是怎么回事呢城丧?

這事從頭說起。

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

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

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

Windows 平臺還有一個特殊的問題「甏危現(xiàn)在 Qt 的圖形架構調用 OpenGL ES 2.0 進行底層的渲染,但剛安裝完的 Windows 只支持到 OpenGL 1.1筒扒,針對這個問題怯邪,早期的 Qt 在 configure 階段提供了兩種選項,一是使用與 Chromium 一樣的 ANGLE花墩,把 OpenGL 調用翻譯成 DirectX 調用悬秉,二者假定用戶的系統(tǒng)安裝了顯卡驅動,能夠支持 OpenGL 2.0冰蘑。前者需要包含幾個 ANGLE 的 DLL和泌,直接又增加了 17M 的容量!

所幸這些事情現(xiàn)在都解決了祠肥。

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

其次美尸,QML 一些奇怪的依賴現(xiàn)在也去掉了垒拢。所以現(xiàn)在無論使用 QtWidgets 還是使用 QML,未壓縮時都只有 20M 左右的容量火惊。

最后一個,現(xiàn)在有多少用戶的電腦是沒有安裝顯卡驅動的呢奔垦?好吧屹耐,好像還真有,vmware 的虛擬機椿猎。但我覺得正常直接用系統(tǒng)自帶的 OpenGL 驅動足矣惶岭。Qt 現(xiàn)在會在運行的時候自動探測 ANGLE 是否存在,如果存在犯眠,就使用 ANGLE按灶,如果不存在,就使用系統(tǒng)自帶的 OpenGL筐咧,不必像以前那樣在 configure 階段就配置好鸯旁。另外,QtWidgets 沒有使用 OpenGL量蕊,所以使用 QtWidgets/C++ 的程序也可以把 ANGLE 的 DLL 都去掉铺罢。

說這么多,具體怎么操作呢残炮。非常簡單韭赘,用 Qt 5.7 來說,現(xiàn)在提供了一個名為 windeployqt.exe 的程序势就,位于 Qt 的 bin 目錄里面泉瞻。運行這個程序,后面帶程序名稱就行了:

  1. 創(chuàng)建一個 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,除非用戶的系統(tǒng)連 DirectX 支持都不完整——虛擬機環(huán)境就是這樣——不然這個文件也完全沒有用碉怔。 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 已經發(fā)布了啦粹。在這個版本里面偿荷,不再依賴于 OpenGL ES 2.0,而是繞過 ANGLE唠椭,直接調用 DirectX 渲染遭顶,到 Qt 5.10 還要直接支持 Vulkan API。不過目前仍然是試驗性的泪蔫,有興趣的話可以看看 configure 的說明棒旗。

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

參考資料:

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

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

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

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市餐曹,隨后出現(xiàn)的幾起案子逛拱,更是在濱河造成了極大的恐慌,老刑警劉巖台猴,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朽合,死亡現(xiàn)場離奇詭異俱两,居然都是意外死亡,警方通過查閱死者的電腦和手機曹步,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門宪彩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讲婚,你說我怎么就攤上這事尿孔。” “怎么了筹麸?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵活合,是天一觀的道長。 經常有香客問我物赶,道長白指,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任酵紫,我火速辦了婚禮侵续,結果婚禮上,老公的妹妹穿的比我還像新娘憨闰。我一直安慰自己,他們只是感情好需五,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布鹉动。 她就那樣靜靜地躺著,像睡著了一般宏邮。 火紅的嫁衣襯著肌膚如雪泽示。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天蜜氨,我揣著相機與錄音械筛,去河邊找鬼。 笑死飒炎,一個胖子當著我的面吹牛埋哟,可吹牛的內容都是我干的。 我是一名探鬼主播郎汪,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赤赊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了煞赢?” 一聲冷哼從身側響起抛计,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎照筑,沒想到半個月后吹截,有當地人在樹林里發(fā)現(xiàn)了一具尸體瘦陈,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年波俄,在試婚紗的時候發(fā)現(xiàn)自己被綠了晨逝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弟断,死狀恐怖咏花,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情阀趴,我是刑警寧澤昏翰,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站刘急,受9級特大地震影響棚菊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜叔汁,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一统求、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧据块,春花似錦码邻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至边篮,卻和暖如春己莺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背戈轿。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工凌受, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人思杯。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓胜蛉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親色乾。 傳聞我的和親對象是個殘疾皇子腾么,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容

  • 界面 主窗口界面設計 標題欄:直接設Window-Title屬性;Window-icon屬性可加圖標杈湾。底部狀態(tài)欄:...
    碼園老農閱讀 3,753評論 1 13
  • Qt是屬于一個跨平臺的GUI開發(fā)軟件解虱,支持的平臺有Unix、Linux漆撞、Windows/WinCE殴泰、IOS等于宙。 Q...
    一葉之界閱讀 8,162評論 0 17
  • 「博客搬家」 原地址: CSDN 原發(fā)表時間: 2016-06-04 本文討論在 Windows 平臺下編譯成...
    雪中亮閱讀 7,549評論 0 10
  • 第一次做Qt,這里把主要的坑列出來悍汛。 連接Mysql Qt連接mysql的時候捞魁,會遇到: QSqlDatabase...
    偷風箏的人_閱讀 3,500評論 1 3
  • How many roads must a man walk down ,一個男人要走多遠的路,Before th...
    楚少寒閱讀 406評論 0 0