Qt打包過大

2022-03-15 17:42:27 字數 2943 閱讀 1491

經常看到網上有些論調說 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 開發者發現 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 的容量!

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

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

最後乙個,現在有多少使用者的電腦是沒有安裝顯示卡驅動的呢?好吧,好像還真有,vmware 的虛擬機器。但我覺得正常直接用系統自帶的 opengl 驅動足矣。qt 現在會在執行的時候自動探測 angle 是否存在,如果存在,就使用 angle,如果不存在,就使用系統自帶的 opengl,不必像以前那樣在 configure 階段就配置好。另外,qtwidgets 沒有使用 opengl,所以使用 qtwidgets/c++ 的程式也可以把 angle 的 dll 都去掉。

說這麼多,具體怎麼操作呢。非常簡單,用 qt 5.7 來說,現在提供了乙個名為 windeployqt.exe 的程式,位於 qt 的 bin 目錄裡面。執行這個程式,後面帶程式名稱就行了:

建立乙個 dist 目錄

把編譯好的 qttest.exe 複製到 dist 目錄。

開啟 cmd.exe,cd 到 dist 目錄 4.1 執行 c:qt5binwindeployqt.exe qttest.exe 4.2 對於 qml 程式,需要指定 qml 目錄: c:qt5binwindeployqt.exe --qmldir d:qttest qttest.exe

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

libegl.dll, libglesv2.dll 這兩個檔案是 angle 的檔案,可以去掉。opengl32sw.dll 是軟體模擬 opengl,除非使用者的系統連 directx 支援都不完整——虛擬機器環境就是這樣——不然這個檔案也完全沒有用。 qtwidgets/c++ 程式都不用 opengl,所以直接去掉即可。可在呼叫 windeployqt.exe 時加"--no-angle" 和 "--no-opengl-sw" 這兩個引數。

如果沒有使用 svg 的話,iconenginesqsvgicon.dll, imageformatsqsvg.dll, qt5svg.dll 這三個檔案也可以刪掉

如果沒有國際化使用者的話,translations 裡面的翻譯檔案也可以刪掉。

qml 程式沒有使用 qtwidgets/c++ 可以刪掉 qt5widgets.dll

如果 imageformats 目錄裡面有幾種影象格式沒用上,也可以刪掉。我自己通常把整個目錄都刪掉,qt已經編譯了 png 的支援,能讀寫程式包含的圖示就夠,其它格式不重要。

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 程式。

webpack 打包檔案 vue 過大

在 build webpack.base.conf.js 檔案裡加上 externals 不需要打包的檔案就放寫在這裡,然後在 index.html 外連上這些庫 順便記錄乙個連線後面加入版本號 在 webpack.prod.conf.js 檔案裡 自己獲取乙個時間加在後面就可以了 官方 impor...

vue專案打包檔案過大優化

總結一下前端打包優化,我用的是vue cli3 配置檔案vue.config.js 一 路由懶載入 每次進入乙個新頁面才載入該頁面所需要的資源 component import view setting setting.vue 二 把不常改變的庫放到index.html中,通過cdn引入 最好引入指...

qt打包程式

qt的應用程式編譯出來之後,將單獨的exe程式拿到其他pc上執行是執行不起來的,會提示缺少對應的動態鏈結庫。我們需要去qt的安裝目錄下找到所有的qt程式執行時所依賴的,將他們和exe程式放到同一目錄下,程式才可以執行。根據上邊的描述我們可以想象的到,如果手動去尋找應用程式依賴的動態庫,這是一件非常麻...