前言
最近研究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
Version=1.0.0
這里做個簡單的說明
Exec:這個字段是執行路徑,如果你的程序直接放到/usr/bin之類的地方,那么你可以直接寫 TestQt,而不需要完整路徑
Icon:這個是圖標路徑,默認會從 /usr/share/icons下面去找,如果你按照上面目錄結構放入了 TestQt.png ,那么就可以直接寫圖標名字。如果沒有,比如你放到了程序目錄,那么就需要寫上完整路徑
Name:這個可以加上locale來支持多語言
接着我們熟悉一下 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
終於完畢