Qt - 跨平台程序打包发布
文章目錄
- Qt跨平臺
- Java跨平臺實現
- Qt跨平臺實現
- Qt - Windows打包發布
- 最小依賴庫
- Windeployqt
- Enigma Virtual Box 打包為可獨立運行exe
- Inno Setup 封裝為安裝包
- 如何修改版本信息
- 修改.pro
- rc資源文件
- Qt - Linux打包發布
- 拷貝依賴庫
- linuxdelpoyqt
- 參考鳴謝
Qt跨平臺
Qt 的跨平臺為 一次編碼,處處編譯,這與 Java 依賴虛擬機實現的 一次編譯,處處運行 是不同的。
Java跨平臺實現
Java 是把針對不同平臺與操作系統的跨系統核心代碼抽象出來,形成單獨的 JVM層(java virtual machine),Java 代碼運行在 JVM 上,把跨平臺 java語言框架問題 分解為在不同平臺上設計 JVM的問題,結構簡單、邏輯清晰、易于實現 1。
為此,Java 付出了犧牲效率的代價。Java 語言需要先通過 JVM 再映射到操作系統里,最后由CPU 執行,執行過程多了一步。早期由于 Java語言 主要使用 解釋性編譯器,從而導致運行效率進一步降低。但是隨著 即時編譯技術(JIT) 的推出,尤其是硬件計算速度的大幅提升,Java運行效率 問題基本得到解決 1。
Qt跨平臺實現
Qt平臺 封裝了針對不同平臺的類庫,API 。這些都被上層做了封裝,對我們開發者來說操作各種平臺的接口都是一樣的 1。以我最近使用的 QSerialPort 為例子,在 Qserialport.h 中可發現以下蛛絲馬跡:
Qserialport.h(源碼可戳)
//line 74 #if defined(Q_OS_WIN32)typedef void* Handle; #elsetypedef int Handle; #endif//line 307 #if defined(Q_OS_WIN32)Q_PRIVATE_SLOT(d_func(), bool _q_startAsyncWrite()) #endifQSerialPort.cpp(源碼可戳)
//line 90 #if defined(Q_OS_WIN32): readChunkBuffer(QSERIALPORT_BUFFERSIZE, 0) #endif {writeBufferChunkSize = QSERIALPORT_BUFFERSIZE;readBufferChunkSize = QSERIALPORT_BUFFERSIZE; } //line 1253 qint64 QSerialPort::bytesToWrite() const {qint64 pendingBytes = QIODevice::bytesToWrite(); #if defined(Q_OS_WIN32)pendingBytes += d_func()->writeChunkBuffer.size(); #endifreturn pendingBytes; }可見 QSerialPort 提供的接口是使用 宏 做了跨平臺處理的。
那么 Qt 為我們提供的跨平臺接口有那些呢?
Qt的界面,Qt封裝的一些庫包,數據結構以及算法…
對于 Qt項目 中不提供跨平臺的部分,則需要我們自己實現,常用的就是 宏。
例如換行操作:
#ifdef Q_OS_WIN32qDebug() << "Windows換行!\r\n"; #else//假設是LinuxqDebug()<<"unWindows換行!\n "; #endif好了下面進入正題,Qt - Windows程序及Linux程序打包發布。
Qt - Windows打包發布
最小依賴庫
在 QtCore 中,當我們把構建方式選為Release,將生成 *.exe 文件
直接打開該文件會提示 缺少xxx.dll 等錯誤。
我們可在 Qt 的編譯器路徑下搜索缺失的 dll文件;
我的路徑是 xxx\QT5.9.3\5.9.3\mingw53_32\bin,找到后將其放到可執行文件· 同一路徑 下。
下圖是我復制的 dll庫,應該是 最小依賴庫 了。
Windeployqt
作為懶鬼,我堅信懶是人類發展的原動力。
于是我發現了一個便捷的工具 Windeployqt,它將幫助我們將依賴庫復制到指定目錄中。
例如我這在 D盤 創建了一個 UHelper文件夾 ,然后將前面生成的 UHelper.exe 移動進去。
打開Qt for Desktop;
執行 windeployqt *.exe。
可以發現,依賴的庫都復制進去了
Enigma Virtual Box 打包為可獨立運行exe
我們可以將上面的 exe文件 及 dll文件 打包給別人,但是這樣一點也不酷。
有沒有辦法直接將 exe 和 所需的dll庫 都打包為一個exe文件呢?
還真有,Enigma Virtual Box 就是一個不錯的選擇。
下載地址見:Enigma Virtual Box官網
ps:如果是使用 Windeployqt 添加的庫,把所有添加的 dll及文件夾都拖選添加至 Enigma Virtual Box 即可。
切記:文件夾也要,并且不要試圖去改變它。
執行完成后,就生成了一個獨立可執行程序。
Inno Setup 封裝為安裝包
下載地址見:Inno Setup官網
使用流程可參考 2 Inno setup 打包教程
生成安裝程序如下:
安裝完成后的文件目錄如下:
有別于直接移植的是,在控制面板中是可以查找得到該程序的(即修改了注冊表)。并且它給我們提供了一個卸載程序。
如何修改版本信息
到此為止我們生成的可執行文件都是沒有詳細信息的。
修改.pro
最簡單的方法莫過于直接在 pro文件 中添加以下代碼。
下面列舉了一些常用信息 3 4:
//版本信息 VERSION = xx.xx.xx.xx //圖標 RC_ICONS = xxxx.ico //公司名稱 QMAKE_TARGET_COMPANY = "" //產品名稱 QMAKE_TARGET_PRODUCT = "" //文件說明 QMAKE_TARGET_DESCRIPTION = "" //版權信息 QMAKE_TARGET_COPYRIGHT = "" //中文(簡體) RC_LANG = 0x0004rc資源文件
由于 rc文件 是 Windows平臺相關的東西,Qt助手 中對于 rc文件 幾乎沒有任何介紹 5。
使用可查看本文參考 - 傳送門 。
Qt - Linux打包發布
將項目拷貝到 Ubuntu18.04;
Qt環境 與 Windows下的相同,均為 Qt5.9.3;
移過去后,UI 顯示有點問題,于是修改了一下 UI;
然后用 Release編譯,即生成可執行文件 UHelper。
由于 Ubuntu自帶了Qt庫 6,我們可以直接運行:
程序運行效果:
若非 Ubuntu 系統則需要拷貝so庫。
拷貝依賴庫
可以使用 ldd命令 查看其依賴庫及路徑:
ldd UHelper //or ldd ./UHelper
一個個復制很麻煩,為此可以借助 shell腳本 完成 so庫 的復制:
執行:
chmod 777 pack.sh ./pack.sh復制完以后的結果如下圖所示:
再編寫一個可執行文件;
UHelper.sh
#!/bin/sh appname=`basename $0 | sed s,\.sh$,,` dirname=`dirname $0` tmp="${dirname#?}" if [ "${dirname%$tmp}" != "/" ]; then dirname=$PWD/$dirname fi LD_LIBRARY_PATH=$dirname export LD_LIBRARY_PATH $dirname/$appname "$@"注意:這里的腳本名必須和可執行文件名一致。
通過運行此腳本而不是可執行文件,可以確保動態鏈接程序將找到Qt庫 7。
linuxdelpoyqt
linuxdeployqt 可以理解為 Windeployqt 的 Linux 版本,讓你的打包如絲般順滑。
同時,linuxdelpoyqt 是一個開源項目,下載地址見 Github-linuxdelpoyqt
下載完成后我們給它重命名為 delpoyqt。
執行一下:
但是,我們在其他路徑下調用則顯得很不方便。
為此可將其移動到 /usr/local/bin,這樣在任何地方都可以使用 deployqt。
sudo mv ./deployqt /usr/local/bin驗證:
打包:
AppImage 的文檔提到,其理念是:應用程序應建立在最舊的系統上,以使它們可以在較新的系統上運行 8。
至于原因,其解釋為:這樣就可以排除某些 基礎庫,而這些 基礎庫 可以在所有主要的 桌面Linux發行版 中找到,從而減少了 One app = one file 的開銷 8。
顯然 Linuxdeployqt 的作者是非常認同這種做法的。
probonopd :我認為應用程序開發人員只是為最新和最大的發行版進行開發而“懶惰”,并告訴用戶“僅升級您的OS即可使用此應用程序” 9。
目前所支持的最新Ubuntu LTS版本為16.04。
安裝Ubuntu16.04鏡像,記得選 arm版 并安裝 Qt、Linuxdeployqt…
重復之前的步驟,再重新執行:
sudo deployqt Uhelper -appimage
這里提示圖標的問題,可以暫時忽略。
如何設置圖標,如何讓軟件開機自啟,如何打包為 deb文件,可參考 在Linux下使用linuxdeployqt發布Qt程序 10。
參考鳴謝
《Qt平臺體系與應用——Qt5.5+核心方法、技巧與案例》 ?? ?? ??
Inno setup 打包教程 ??
How to Get Current App Version in Qt ??
Qt 之生成 Window 資源文件(.rc 文件) ??
Qt 之添加 Windows 資源文件(.rc文件) ??
01-為什么要用Qt開發(Qt跨平臺應用開發) ??
Qt for Linux/X11 - Deployment ??
AppImage-Docs-Introduction-Concepts ?? ??
Latest continuous linuxdeployqt build does not work on Ubuntu 16.04 LTS and openSUSE Leap 15.0 #340 ??
在Linux下使用linuxdeployqt發布Qt程序 ??
總結
以上是生活随笔為你收集整理的Qt - 跨平台程序打包发布的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pl中xmp文件的修改与保存
- 下一篇: VSCode+Marp:用Markdow