ubuntu下對Qt工程進行deb打包釋出
前言
最近研究ubuntu上的Qt打包遇到了很多問題,雖然有個LinuxDeployQt,但是這貨有個很大的缺點,那就是它打包的程式在執行的時候會把自己釋放到一個臨時目錄執行,這樣就導致了我們的程式設定當前執行目錄有誤,導致相對路徑之類的東西全部撲街。所以我們需要一個新的辦法。在調查了一段時間後,最終找到解決方案,並學會了deb安裝包的製作
環境
系統:ubuntu 16.04
Qt程式:TestQt
Qt版本:5.12.4
分析
要實現我們最終的目的,需要解決下面幾個問題:
- 讓Qt程式執行時載入自己指定目錄下的動態庫,而不是系統預設的,避免和系統已有的Qt庫發生衝突
- 自動提取所需要的依賴包到我們指定的目錄,這個可以藉助ldd
- Qt程式指定
plugins
載入路徑,這個需要用到qt.conf
配置檔案 - 如果製作deb包,這個設計到deb工程的目錄結構和dpkg打包指令,還涉及到 linux的 desktop 檔案格式(類似windows快捷方式)
方案
問題 1
我們需要指定一個LFLAGS的引數,這裡是指定程式所在目錄下的lib目錄
-Wl,-rpath,'$$ORIGIN/lib'
這個引數就可以指定程式執行時候的優先載入路徑,如果用的是QtCreator,那麼我們修改pro工程檔案
QMAKE_LFLAGS += -Wl,-rpath,\'\$$ORIGIN/lib\'
注意:這裡一定要用 \
轉義,不然 QMAKE_LFLAGS
問題 2
這個只需要使用ldd來查詢依賴,並自動拷貝到我們app下的lib目錄即可,在程式目錄建了一個指令碼 copylib.sh
內容如下:
#!/bin/bash LibDir=$PWD"/lib" Target=$1 lib_array=($(ldd $Target | grep -o "/.*" | grep -o "/.*/[^[:space:]]*")) $(mkdir $LibDir) for Variable in ${lib_array[@]} do cp "$Variable" $LibDir done
假設我們的Qt程式為 TestQt
,這樣我們使用 copylib.sh ./TestQt
就直接拷貝依賴到 lib目錄下了
注意:如果是打包Qt,那麼要注意xcb的問題,我們需要額外拷貝兩個Qt庫進來,libQt5XcbQpa
和 libQt5DBus
這兩個都屬於 plugins/platforms
裡面 libqxcb.so
所依賴的庫。另外我們需要拷貝plugins目錄下的 bearer
,platforms
,imageformats
。還要注意一點,那就是Qt庫要帶著符號連結一起拷貝過去,不然依舊會報錯
問題 3
這個就是使用qt.conf檔案了,內容如下:
[Paths]
Prefix=./
Libraries=lib
Plugins=plugins
問題 4
目錄說明
首先我們需要建立一個目錄結構,這裡拿TestQt的舉例,不含檔案
TestQt-Package/
└── project
├── DEBIAN
└── usr
├── local
│ └── TestQt
| ├── lib
│ ├── plugins
│ │ ├── bearer
│ │ ├── imageformats
│ │ ├── platforms
└── share
├── applications
└── icons
└── hicolor
└── 64x64
└── apps
這裡的project就是我們要打包成 deb 包的工程資料夾,內容主要是 usr
和 DEBIAN
兩個資料夾,usr目錄結構和系統保持一致。然後我們簡單說明一下
DEBIAN:這個資料夾是 deb 配置資訊資料夾
applications:這裡是放置程式的快捷方式的,用來在 ubuntu 程式選單中顯示你的程式
icon:這裡放置你的程式圖示,png格式,這裡是64x64的解析度,請根據自身圖示大小挑選對應解析度資料夾放置
我們的程式位於 /usr/local/TestQt 下面,當然,你也可以放到其他地方,參考上面的目錄結構即可
檔案說明
首先我們瞭解一下 linux的快捷方式檔案,linux的快捷方式 是 desktop 格式,類似windows的 lnk,示例檔案(TestQt.desktop)如下
[Desktop Entry]
Categories=Utility;
Comment=a test
Exec=/usr/local/TestQt/TestQt
GenericName=TestQT project
Icon=TestQt.png
Name=TestQt
Name[zh_CN]=TestQt測試程式
Type=Application
StartupNotify=false
Version=1.0.0
這裡做個簡單的說明
Exec:這個欄位是執行路徑,如果你的程式直接放到/usr/bin之類的地方,那麼你可以直接寫 TestQt,而不需要完整路徑
Icon:這個是圖示路徑,預設會從 /usr/share/icons下面去找,如果你按照上面目錄結構放入了 TestQt.png ,那麼就可以直接寫圖示名字。如果沒有,比如你放到了程式目錄,那麼就需要寫上完整路徑
Name:這個可以加上locate來支援多語言
接著我們熟悉一下 DEBIAN
目錄下的配置檔案 ,配置檔案固定名字為 control , 內容如下
package: TestQt
version: 1.0.0
architecture: amd64
maintainer: magicdmer
description: a test project
都放好後,我們就在 TestQt-Package 目錄下執行下面的命令打包
dpkg -b project/ TestQt_ubuntu_amd64.deb
終於完畢