1. 程式人生 > >在Linux 下如何打包免安裝的QT程式?

在Linux 下如何打包免安裝的QT程式?

如題,近期因為專案需求,得打包QT程式,並將程式放到沒有安裝QT庫的電腦上執行。網上索羅了下,打包QT程式的方式很多,主要分為以下幾種:
1. 打包成安裝包形式;
2. 打包成二進位制檔案,附帶執行庫的形式:
- windows下,有很多工具,教程也比較多,執行庫基本是dll檔案
- linux下,需要靠指令碼協助,很多教程都不完整,執行庫基本是so檔案

筆者這裡只演示如何在linux下打包免安裝程式,程式名稱為giptables,QT版本是5.7.1,以下如出現這個名稱,則一律替換成讀者自己的應用程式名稱。
0、找個地方,比如桌面,建立空資料夾Giptables,這個將用來存放giptables程式的執行檔案
1、先將工程使用Release模式編譯
2、開啟編譯輸出檔案的資料夾(帶二進位制檔案giptables的那個)

筆者的資料夾名稱是build-giptables-Desktop_Qt_5_7_1_GCC_64bit-Release

3、在上一步的資料夾中新建檔案copylib.sh,通過指令設定許可權chmod 777 copylib.sh
4、在 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

5、開啟終端並進入到當前資料夾,輸入./copylib.sh giptables

其中, giptables 是執行copylib.sh 指令碼的引數,指令碼實際上是呼叫了 ldd giptables指令獲得giptables執行時需要哪些庫,並將庫都複製放到當前目錄的lib資料夾中。

執行完上述指令後,同目錄下會生成lib資料夾,這裡我們將其稱作giptables的庫資料夾,避免與下文內容混淆

6、將giptables的二進位制檔案giptables的庫資料夾裡所有的檔案複製到Giptables資料夾中,注意:這裡是把lib裡的所有檔案複製出來,不用複製lib資料夾

7、進入QT的安裝目錄,找到platforms資料夾,筆者的路徑是

~/Qt5.7.1/5.7/gcc_64/plugins/platforms
將整個platforms資料夾複製到Giptables資料夾中,注意:這時複製的是整個資料夾,這使得Giptables資料夾中會多出一個platforms資料夾

8、將上文的copylib.sh放到Giptables/platforms/中,並執行./copylib.sh libqxcb.so,這時會得到lib資料夾——libqxcb.so的庫資料夾
ps:為什麼是libqxcb.so呢?具體看文末的參考資料,這個跟你要執行的程式有關,需要用到哪些QT的庫,就再打包對應的東西。

9、將libqxcb.so的庫資料夾中的所有檔案複製Giptables資料夾中,然後刪除掉Giptables/platforms/lib資料夾

10、在Giptables資料夾中新建指令碼giptables.sh,執行chmod 777 giptables.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 "[email protected]"

到這裡就基本完成了,將Giptables資料夾複製到需要執行程式的目標主機即可,在目標主機中,執行程式,都採用 ./giptables.sh而不是./giptables,即執行程式的sh指令碼,而不是二進位制檔案

過程中遇到的問題:
1、執行copylib.sh時報找不到庫的錯誤:必須保證在原始檔夾中執行copylib.sh,而不能先將檔案複製出來,然後再執行copylib.sh生成lib
2、在目標主機中提示

This application failed to start because it could not find or load the Qt platform plugin “xcb”

這是因為沒有生成libqxcb.so的庫資料夾,或者沒有將生成的資料夾中所有的檔案放到giptables.sh同一級目錄下,筆者最後生成的目錄結構如下

Giptables(資料夾) -- platforms(資料夾) -- libqxcb.so
                 |                    \__ *.so
                 |
                 \__ giptables.sh
                 \__ *.so