應用程式開發完成後,下一步當然是把它發布出去,讓其他人使用囉。
如果你把這個系列隨便一個範例,編譯成 EXE 檔案丟給你朋友,請他在自己的電腦上執行,那麼八成程式跑不起來,錯誤訊息是「找不到 Qt6Core.dll」之類的字樣。因為 Qt 應用程式除了EXE本身,還需要一些外部函式庫 DLL 才能正常運作。
這一篇的教學裡,我們講解如何使用 Qt 的佈署工具來發布你的 Qt 應用程式。
發布程式時最重要,最重要的事情就是要用 Release 組態來編譯應用程式。
請在 Qt Creator 的左下角選擇組態。
預設值是 Debug,這個組態會盡可能的提供程式設計師詳細的除錯資訊,幫助我們寫出正確的程式。但是 Debug 組態的程式既沒有最佳化,檔案尺寸也比較大,而且通常限定在有安裝開發環境的電腦才能執行。所以 Debug 組態編譯出來的執行檔,是完全沒辦法發布的喔。
相對的,使用 Release 組態來編譯程式,第一是開啟了編譯器最佳化功能,程式碼的效能會好很多,檔案尺寸也會變小,而且使用者不需要安裝開發環境。所以請記得用 Release 組態來發布應用程式。
Qt 應用程式除了EXE本身,還需要一些外部函式庫 DLL 才能正常運作。
當然你可以手動複製去補齊這些檔案。但是 Qt 內建了一個非常有用的工具叫做 windeployqt,它會協助你蒐集所有必須的依賴檔案。
該程式在 Qt 安裝目錄下,使用方式如下:
windeployqt your/qt_app.exe
該指令會將這個 EXE 檔所需要的所有 Qt 資料都複製到 EXE 所在的路徑下。
我用本系列的看圖軟體範例作為例子,一開始目錄內只有一個 EXE: ImageViewer.exe
下指令 windeployqt ImageViewer.exe
PS C:\ironman> windeployqt.exe .\ImageViewer.exe
C:\ironman\ImageViewer.exe 64 bit, release executable
Adding Qt6Network for qtuiotouchplugin.dll
Adding Qt6Svg for qsvgicon.dll
Direct dependencies: Qt6Core Qt6Gui Qt6Widgets
All dependencies : Qt6Core Qt6Gui Qt6Widgets
To be deployed : Qt6Core Qt6Gui Qt6Network Qt6Svg Qt6Widgets
Warning: Cannot find Visual Studio installation directory, VCINSTALLDIR is not set.
Updating Qt6Core.dll.
Updating Qt6Gui.dll.
Updating Qt6Network.dll.
Updating Qt6Svg.dll.
Updating Qt6Widgets.dll.
Updating opengl32sw.dll.
Updating D3Dcompiler_47.dll.
Creating directory C:/ironman/generic.
Updating qtuiotouchplugin.dll.
Creating directory C:/ironman/iconengines.
Updating qsvgicon.dll.
Creating directory C:/ironman/imageformats.
Updating qgif.dll.
Updating qico.dll.
Updating qjpeg.dll.
Updating qsvg.dll.
Creating directory C:/ironman/networkinformation.
Updating qnetworklistmanager.dll.
Creating directory C:/ironman/platforms.
Updating qwindows.dll.
Creating directory C:/ironman/styles.
Updating qwindowsvistastyle.dll.
Creating directory C:/ironman/tls.
Updating qcertonlybackend.dll.
Updating qopensslbackend.dll.
Updating qschannelbackend.dll.
Creating C:\ironman\translations...
Creating qt_ar.qm...
Creating qt_bg.qm...
Creating qt_ca.qm...
Creating qt_cs.qm...
Creating qt_da.qm...
Creating qt_de.qm...
Creating qt_en.qm...
Creating qt_es.qm...
Creating qt_fa.qm...
Creating qt_fi.qm...
Creating qt_fr.qm...
Creating qt_gd.qm...
Creating qt_he.qm...
Creating qt_hr.qm...
Creating qt_hu.qm...
Creating qt_it.qm...
Creating qt_ja.qm...
Creating qt_ko.qm...
Creating qt_lv.qm...
Creating qt_nl.qm...
Creating qt_nn.qm...
Creating qt_pl.qm...
Creating qt_pt_BR.qm...
Creating qt_ru.qm...
Creating qt_sk.qm...
Creating qt_tr.qm...
Creating qt_uk.qm...
Creating qt_zh_CN.qm...
Creating qt_zh_TW.qm...
PS C:\ironman>
你可以看到 windeployqt 偵測到了應用程式用了哪些 Qt 模組,還複製了一大堆檔案進來EXE目錄。
最終目錄看起來會長這樣
這樣第一步 Qt 相關的依賴檔案就都包括進來囉,但是還沒結束喔,請繼續往下看。
要正確執行EXE應用程式,除了Qt自己的依賴檔案以外,還有編譯器本身的依賴檔案。
如果你是用 MinGW 來編譯你的應用程式,還需要多複製兩個檔案:
這些檔案位於 MinGW 的安裝目錄下,我的電腦上路徑是 C:\Qt\Tools\mingw1120_64\x86_64-w64-mingw32\lib\
。加上這些檔案,你應該就可以順利執行應用程式囉。
如果用 MSVC 的話,需要使用者的電腦上有安裝 Visual C++ Runtime。這個安裝是一次性的,使用者只要安裝過一次,那麼他的電腦之後任何使用 MSVC 編譯的程式都可以執行。
你可能需要引導使用者安裝它。
對於 macOS 平台,Qt 同樣提供了 macdeployqt 工具來幫助自動複製需要的框架和函式庫到你的應用程式包(Mac App Bundle)中。
使用方式如下:
macdeployqt path/to/your_app.app
這個命令將會處理所有的事情,包含修正框架和插件的路徑以及添加必要的資源到你的 app bundle 中。
這樣一來,你發布出去的應用程式,應該就可以被大多數人使用囉。