日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt - 跨平台程序打包发布

發布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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()) #endif

QSerialPort.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 = 0x0004

rc資源文件

由于 rc文件 是 Windows平臺相關的東西,Qt助手 中對于 rc文件 幾乎沒有任何介紹 5

使用可查看本文參考 - 傳送門

Qt - Linux打包發布

將項目拷貝到 Ubuntu18.04;

Qt環境 與 Windows下的相同,均為 Qt5.9.3;

移過去后,UI 顯示有點問題,于是修改了一下 UI;

然后用 Release編譯,即生成可執行文件 UHelper。


由于 Ubuntu自帶了Qt庫 6,我們可以直接運行:

./UHelper

程序運行效果:


若非 Ubuntu 系統則需要拷貝so庫。

拷貝依賴庫

可以使用 ldd命令 查看其依賴庫及路徑:

ldd UHelper //or ldd ./UHelper


一個個復制很麻煩,為此可以借助 shell腳本 完成 so庫 的復制:

#!/bin/sh # ldd $exe (所以這里寫你的可執行文件名) exe="UHelper" # copy 目錄 des="/home/hsy/SW/Qt5.9.3/Project/UHelper_test" # awk 匹配第三個參數“/”,排除掉沒有路徑的 deplist=$(ldd $exe | awk '{if (match($3,"/")){printf("%s\n"),$3}}') # 將so庫拷貝至des目錄 # -L:--dereference 始終遵循源中的符號鏈接 # -n: --no-clobber 不要覆蓋已存在的文件 cp -L -n $deplist $des

執行:

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 - 跨平台程序打包发布的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。