當軟件開發完成之後,還有一項很關鍵的任務要做 - 打包發佈。換句話說,我們的軟件最終要交付給用戶,並且能夠讓他們很容易地安裝在自己的系統上。
那麼,該如何製作這樣的安裝程序(軟件包)呢?我們一步一步道來。
靜態庫與動態庫
在介紹打包之前,有必要分享一下靜態庫與動態庫的區別,因為最終安裝包中的文件組成與之息息相關。
Tips:對於使用 Qt 的應用程序,如果要靜態編譯,則需要構建一個靜態版的 Qt。這意味著,無法關閉源代碼並在 LGPL 上回復(要麼開放源代碼,要麼獲得商業版 Qt 許可證)。
在 Windows 中,要解決可執行文件過大的問題,可以使用像 UPX 這樣的加殼工具。在對可執行文件壓縮之後,會在啟動時將其解壓縮到 RAM 中。
而在 Linux 中,可以通過 strip 命令來去除目標文件中的調試信息、符號信息,以減小程序的大小。但要注意一點,strip 只能用於可執行文件和動態庫(.so),不能用於靜態庫(.a)。
應用程序的組成
對於 Qt 應用程序來說,它們一般由下述文件組成,這些文件可分為三部分:
- 可執行文件(例如:.exe):最終由用戶運行的程序。
- 動態庫(.dll 或 .so):通常是一些 Qt 模塊(QtCore、QtGui 等)和插件,以及第三方庫。
- 支持文件:如圖片、翻譯文件、幫助文檔等。
支持文件可以被集成到可執行文件中,最簡單的方法是使用 Qt 資源系統,它允許將任何文件嵌入到可執行文件中。這是大多數僅由可執行文件(而非用戶)使用的文件的邏輯位置,像上面說的圖片、翻譯文件、幫助文檔等,千萬不要將示例文檔、或者用戶希望能夠在文件系統中找到的其他文件放在這裡面。
在創建安裝程序時,則需要用到這些資源並從中構建軟件包。該包不僅包含了所需的文件,還可能會包含一些說明(例如:ReadMe),以及用戶需要遵循的許可協議(License),等等。
構建安裝程序
從某種程度上來講,構建安裝程序是平臺特定的任務,而且將來可能會一直都是。這不僅因為平臺不同,而且因為分發機制不同。
Windows
在 Windows 平臺上,當構建完 Qt 程序之後,需要找到其所依賴的動態庫(dll)。為此,可以使用工具 Dependency Walker,它展示了一個圖形樹,包含了程序所依賴的 dll,以及每個 dll 依賴的其他 dll。
使用 Dependency Walker 有個訣竅 - 分類查找:判斷哪些 dll 是 Windows 自帶的(即:預裝在用戶計算機上的)、哪些是屬於 Qt 的(即:需要打包的)。另外,還要考慮用到的一些第三方庫,這可能會增加更多的依賴關係。最後,還有一個需要注意的問題:Qt dll 可以依賴於其他 Qt dll(例如,Qt3Support 模塊依賴於大多數其他 Qt 模塊)。
在使用 Dependency Walker 將所需文件列表放在一起後,下一步是從這些文件中構建一個安裝程序,有許多工具都可以完成此任務:
- NSIS:如果你喜歡開源軟件,則一定知道 NSIS(全稱:Nullsoft Scriptable Install System)。它是一個專業的工具,可用於創建從非常簡單到非常複雜的安裝程序。雖然它很小,但功能卻很豐富,非常適合 Internet 分發。正如其名,NSIS 是基於腳本的,它能夠讓我們創建處理任何情況所需的複雜邏輯。幸運的是,它包含了許多插件和預定義腳本,以幫助初學者入門。
- Inno Setup:是一個免費的安裝製作軟件,小巧、簡便、精美是其最大特點,支持 pascal 腳本,能快速製作出標準 Windows 2000 風格的安裝界面,足以完成一般安裝任務。該軟件用 Delphi 寫成,其官網同時也提供源程序免費下載。它雖不能與 Installshield 這類“恐龍級”的安裝製作軟件相比,但也算是當之無愧的後起之秀。
- Advanced Installer:有一個免費版本,但也有其他幾個版本,這些版本的價格取決於安裝程序的複雜程度。如果你正在尋找更專業的東西,其中還包括一些支持選項,那麼 Advanced Installer 是一個不錯的選擇。用它創建 MSI 文件包非常方便,只需添加文件、修改名稱、添加按鈕即可,無需任何腳本方面的知識,並且生成的安裝文件保證符合 Windows 最佳操作建議。
- InstallShield:是一款“恐龍級”的安裝包製作工具,是 Flexera Software 的當家產品。這不僅是因為它擁有 20 多年的研發歷史,而且它也是全球著名軟件公司的“皇家御用”打包軟件,比如 Adobe、Corel、Autodesk 等公司。然而這款軟件過於專業,並不像 NSIS、Inno Setup 等那樣容易入門,所以想學習必須下很大功夫。這也是全球領先的 Windows 安裝開發解決方案,現在已經成為 Windows Installer 和 InstallScript 安裝方面的行業標準。
- WIX Toolset:是一個免費的打包工具,通常要與 Visual Studio(2012 或更高版本)一起使用。之所以最後提到它,是因為它需要經過大量的學習。雖然可用它創建一些非常複雜的安裝程序,但要編寫大量的代碼並經常使用命令行。
Tips:在測試安裝程序時,建議使用一臺沒有安裝任何 Qt 版本的機器(最好是全新安裝的 Windows)。如果安裝程序缺少 dll,將無法運行並顯示相應的錯誤信息,指出缺少哪個 dll。但是,在啟動時不會檢查插件,因此需要確保測試插件提供的所有功能都存在。
Linux
對於 Linux 系統來說,要查看可執行文件依賴的庫以及缺少的函數符號,可以使用 ldd -r 指令。
如果要部署 Qt 應用程序,可以選擇以下方式:
- 構建源碼包:對於開源項目來說,這是最簡單的方法。但一定要記得,在使用 tar 命令對目錄樹進行壓縮之前,需要先運行 make distclean 來清理構建環境。
- 創建本地分發包:這要考慮系統的發行版,而主流的包管理系統有兩個:rpm 和 deb。rpm 格式起源於 RedHat,但也被其他發行版使用,例如:CentOS、SuSE 和 Fedora。deb 格式是由 Debian 項目開發的,適用於 Debian/Ubuntu 及其衍生版。rpm 可參考 RPM HOWTO,尤其是關於構建的部分 - Building RPMs。deb 可參考Debian 新維護者手冊。
- 創建獨立的應用程序包:若要將 Qt 程序作為一個獨立的包部署到 Linux 中,需要將其以及所需的組件捆綁在一起,像 Qt 庫、Qt 插件(尤其是 platforms 插件)。推薦一個 Linux 部署工具 - linuxdeployqt,它能夠自動執行上述的流程,並提供 AppImage。
Tips:和 Windows 不同的是,Linux 下可執行文件及其依賴庫放在同一目錄一般是無法正常運行的。常用方式是寫一個 Shell 腳本,並用 LD_LIBRARY_PATH 指定依賴庫所在目錄,然後通過運行這個腳本來間接地啟動程序。
OS X
買不起... 買不起... 買不起... 貧窮限制了我,So 暫不涵蓋!
多平臺 GUI 安裝程序
除了上述特定平臺的打包方式之外,還有一些支持跨平臺的工具:
- Qt Installer Framework:簡稱 Qt IFW,由 Qt 官方提供,以前僅用於 Qt 本身,但現在已經發布了,用於創建通用的安裝程序。
- InstallBuilder:是一個功能強大、易於使用的跨平臺安裝程序創建工具。它一直都在積極維護,但僅供商業使用。
- InstallJammer:是一個跨平臺 GUI 安裝程序和生成器,雖然是開源的,但 2011 年之後就不再維護了,比較遺憾!
- ......
以上介紹的都是一些比較知名、並且相對穩定的工具,可以很好地幫助我們構建 Qt 安裝程序,我相信類似的工具還有很多,不知道你用的是哪一款呢?Enjoy
作者:一去、二三里,愛編程、愛分享、愛生活!
歡迎大家關注,更多優質原創內容敬請期待!
閱讀更多 高效程序員 的文章