統信UOS系統開發筆記(七):在統信UOS系統上使用linuxdeployqt發佈qt程序

前言

  在ubuntu上發佈qt程序相對還好,使用腳本,但是在統信UOS麒麟上發佈的時候,因爲銀河麒麟等不同版本,使用腳本就不太兼容,同時爲了實現直接點擊應用可以啓動應用的效果,使用linuxdeployqt發佈qt程序。

 

注意

  本篇文章,最終手動結合幾個方式成功,花費不少時間研究,推斷是終端直接ldd之後強制進入了一個另外的環境變量,導致無法連接成功,也就是,第一層是成功的,第一層的庫又調用ldd依賴的這一步的環境變量被強了。
  但是最後通過手動來實現linuxdeplopyqt和編譯配置來實現打包部署了。

 

統信UOS系統版本

  系統版本:
  在這裏插入圖片描述

 

linuxdeployqt

  Linux部署工具linuxdeployqt將應用程序作爲輸入,並通過將應用程序使用的資源(如庫、圖形和插件)複製到一個包中使其自包含。結果包可以作爲AppDir或AppImage分發給用戶,也可以放入交叉分發包中。它可以作爲構建過程的一部分,在CMake、qmake和make等系統中部署用C、C++和其他編譯語言編寫的應用程序。當用於基於Qt的應用程序時,它可以綁定運行應用程序所需的Qt的特定最小子集。

源碼下載地址

 

linuxdeployqt編譯(統信UOS系統)

步驟一:下載解壓

  在這裏插入圖片描述

步驟二:修改源碼,去掉gcc版本檢查

  找到main.cpp源碼,將這一段(在192行左右)註釋掉(這裏通過看源碼,實際上是可以通過配置去控制的(研究源碼發現的,但是我們不再動作了,只是貼出來):
  在這裏插入圖片描述

  還是老方法繼續修改:

vi linuxdeployqt-master/tools/linuxdeployqt/main.cpp

  在這裏插入圖片描述

步驟三:使用cmake配置

cd linuxdeployqt-master
cmake CMakeLists.txt

  在這裏插入圖片描述

  因爲安裝了git與這個工程可能不對,我們直接使用源碼修改大法,直接定位到代碼給刪掉:

vi CMakeList.txt

  直接刪掉目錄下的緩存文件:CMakeCache.txt,然後繼續:
  在這裏插入圖片描述

  繼續cmake CMakeList.txt

步驟四:配置Qt的依賴環境

  麒麟系統本身自帶了qt5庫(未帶開發相關的庫),而我們使用了另外安裝的qt5,所以依賴需要引入我們自己安裝的qt5上。
  爲了方便配置,也不影響系統我們裝上cmake的gui版本:

sudo yum install cmake-gui

  在這裏插入圖片描述

  在這裏插入圖片描述

cmake-gui 

  選擇對應的路徑,然後使用默認unix makefile方式配置:
  在這裏插入圖片描述

  在這裏插入圖片描述

  在這裏插入圖片描述

步驟五:生成generate

  在這裏插入圖片描述

步驟六:編譯make

  切入build目錄,並且使用make命令即可:

make

  在這裏插入圖片描述

  測試程序:
  在這裏插入圖片描述

步驟七:安裝到系統目錄

  沒有make install這個,手動移動到/usr/local/bin

sudo cp tools/linuxdeployqt/linuxdeployqt /usr/local/bin/

  在這裏插入圖片描述

步驟八:測試是否編譯成功

  在這裏插入圖片描述

 

linuxdeployqt打包流程(arm看可以,本次pc版本失敗)

  (PS:虛擬機打包好之後,退回到裸機版本,再測試)
  新建一個工程
  在這裏插入圖片描述

  然後,找個空目錄:
  在這裏插入圖片描述

  未打包在開發機上也可以運行(裸機不行):
  在這裏插入圖片描述

  這裏要將Qt引入環境,爲了不影響系統,使用source腳本引入,每次使用之前使用source env.sh引入即可。

touch env.sh

  然後輸入如下(QT_DIR爲安裝Qt的路徑):

#!/bin/sh
QT_DIR=/home/yang/Qt5.12.8/5.12.8/gcc_64

export PATH=${QT_DIR}/bin:$PATH
export LIB_PATH=${QT_DIR}/lib:$LIB_PATH
export PLUGIN_PATH=${QT_DIR}/plugins:$PLUGIN_PATH
export QML2_PATH=${QT_DIR}/qml:$QML2_PATH
export LD_LIBRARY_PATH=${QT_DIR}/lib:$LD_LIBRARY_PATH

echo $PATH
echo $LIB_PATH
echo $PLUGIN_PATH
echo $QML2_PATH
echo $LD_LIBRARY_PATH

  在這裏插入圖片描述

  引入環境:
  在這裏插入圖片描述

  下次打包遵循此流程即可,繼續打包:
  在這裏插入圖片描述

  (PS:這裏是沒有使用sudo進行的打包的,可能對權限管控比較嚴格,查看“入坑二”)
  下面使用sudo打包:

sudo linuxdeployqt testDemo -verbose2

  在這裏插入圖片描述

  上面是Qt5Widget的庫連接到系統庫上去了,版本不一樣找不到api
  下面是未打包的testDemo在開發機上:
  在這裏插入圖片描述

  下面是未打包的testDemo在裸機上:
  在這裏插入圖片描述

 

手動來實現linuxdeployqt打包

步驟一:應用放過去

  在這裏插入圖片描述

  (這是開發機,直接運行也是可以的)
  在這裏插入圖片描述

步驟二:創建qt.conf

  這個文件最重要,他就是調用testDemo應用時候,先加載然後去搜索庫路徑的配置,沒有他則走向系統環境變量了。

touch qt.conf
vi qt.conf

  內容,是我們從另外國產麒麟打包的該文件複製的,如下:
  在這裏插入圖片描述

# Generated by linuxdeployqt
# https://github.com/probonopd/linuxdeployqt/
[Paths]
Prefix = ./
Plugins = plugins
Imports = qml
Qml2Imports = qml

  這個時候,我們再運行一次:
  在這裏插入圖片描述

  路徑從本地開始找了。

步驟三:實現其他三個文件夾依賴的拷貝

  在這裏插入圖片描述

ls -l
cp /home/yang/Qt5.12.8/5.12.8/gcc_64/translations/ . -rf
cp /home/yang/Qt5.12.8/5.12.8/gcc_64/plugins/ . -rf
cp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/ . -rf
ls -lh

  在這裏插入圖片描述

  測試本機可運行了:
  在這裏插入圖片描述

  (PS:這裏是全部copy了庫,沒有進行依賴裁剪的,暫時不管了,花費時間遠超預期了)

步驟四:打包放到裸機上

  因爲沒有裁剪,所以包比較大:

cd ..
tar cvf outManual.tar outManual
ls -l outManual.tar

  在這裏插入圖片描述

  拷貝到裸機上去。
  在這裏插入圖片描述

  在這裏插入圖片描述

步驟五:裸機上測試運行(失敗)

  還是失敗,如下:
  在這裏插入圖片描述

  這還是之前一樣,libQt5Widget.so.5依賴libQt5Core.so.5,前面是用當前配置的,然後庫的依賴庫就強制引入到了/usr/lib64,跟之前linuxdeployqt打包一樣的問題。
  在這裏插入圖片描述

  然後有個念頭,於是嘗試加上LD_LIBRARY_PATH測試,可以運行成功,具體查看“入坑四”。

步驟六:編譯時引入運行時路徑pro配置QMAKE_RPATHDIR

  爲了不在運行時額外添加環境變量,爲了打包不出現xcb問題,還得修改一下.pro文件如下圖:

# 這裏是添加運行應用的時候的運行包,此處避免額外設置LD_LIBRARY_PATH
QMAKE_RPATHDIR = ./lib

  在這裏插入圖片描述

  編譯出來,單獨將testDemo2放置到原來的部署裸機上:
  在這裏插入圖片描述
  最終,直接點擊可以運行成功。

 

入坑

入坑一:編譯linuxdeployqt的依賴Qt路徑問題

問題

  開始編譯的時候,讓其依賴了系統,直接導致就算引入了其他qt的環境變量,打包也是依賴系統,直接不打包
  在這裏插入圖片描述

原因

  懷疑是跟編譯linuxdeployqt的依賴有關,所以重做一遍自己安裝Qt的cmake。

解決

  重做一遍自己安裝Qt的cmake後編譯,也還是一樣的。
  在這裏插入圖片描述

入坑二:linuxdeployqt不復制的問題

問題

  如前面的入坑,就是不復制,與編譯依賴沒關係。

嘗試

  沒有辦法,直接幹linuxdeployqt的main.cpp的源碼:
  1.先調試哪裏沒有打印,每次修改源碼重新編譯之後,部署再打包看輸出結果。  (PS:發現qDebug()不輸出,輸出的是qInfo())
  在這裏插入圖片描述

  在這裏插入圖片描述

  在這裏插入圖片描述

  將所有LogError換爲qInfo(),如下圖:
  在這裏插入圖片描述

  在這裏插入圖片描述

  還是不行:
  在這裏插入圖片描述

  繼續:
  在這裏插入圖片描述

  棘手的問題:
  在這裏插入圖片描述

  至此可以確認是兼容性問題,這個問題比較棘手,短期內調不好了。

解決

  Linuxdeployqt方式暫未解決,可以換個linuxdeployqt的版本,也許不同的uos版本也不會又這個問題了,很奇怪連LogError和qDebug都不出來。
  後續,第二天突然想到是否需要sodu權限,嘗試了下,確實是的:
  在這裏插入圖片描述

  所以又重做,使用sudo來打包了。

入坑三:依賴鏈接庫存在錯誤

問題

  在這裏插入圖片描述

  這是和系統的衝突了。
  編譯的時候也是使用的安裝包的:
  在這裏插入圖片描述

原因

  在這裏插入圖片描述

  在這裏插入圖片描述

  無解,qmake路徑和環境變相也都沒有問題
  在這裏插入圖片描述

  檢查linuxdeployqt
  在這裏插入圖片描述

嘗試1

  拍快照,然後目錄下的所有/usr/lib64/Qt5*刪除,首先檢查系統是否正常啓用,再打包嘗試。

sudo rm /usr/lib64/libQt5*

  重啓,確實,系統起不來了,系統依賴Qt5.11下的庫。
  在這裏插入圖片描述

  所以不能刪除,此路不通。

嘗試2

  拍快照,然後將安裝的Qt5庫copy過去,首先檢查系統是否正常啓用,再打包嘗試。
  執行copy指令,直接立即黑屏,此路不同。
  所以,/usr/lib64下的庫是不能動的。
  在這裏插入圖片描述

  這裏懷疑,從進入終端開始就進入了固定的優先環境變量,只是推測,目前linuxdeployqt又花費半天,暫時仍然無解。

解決方法(有點偏門,失敗)

  找不到一個庫就刪掉一個庫,此時系統是已經將庫加載進內存運行,是不影響正在運行的系統,但是無法重啓,如下:

sudo linuxdeployqt testDemo -verbose2
sudo rm /usr/lib64/libQt5Gui.so*

  在這裏插入圖片描述

  在這裏插入圖片描述

sudo linuxdeployqt testDemo -verbose2
sudo rm /usr/lib64/libQt5Core.so*

  在這裏插入圖片描述

sudo linuxdeployqt testDemo -verbose2
sudo cp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/libicuuc.so* /usr/lib64/

  在這裏插入圖片描述

sudo linuxdeployqt testDemo -verbose2
sudo cp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/libicudata.so* /usr/lib64/

  在這裏插入圖片描述

sudo linuxdeployqt testDemo -verbose2
sudo yum install patchelf
sudo linuxdeployqt testDemo -verbose2

  在這裏插入圖片描述

  在這裏插入圖片描述

  可以,uos你贏了,我放棄了!!!

入坑四:手動qt.conf模仿部署還是強制路徑切換

問題

  在這裏插入圖片描述

原因

  分析該系統第二次搜索庫,總是會引入到/usr/lib64,這個問題很操蛋,從一開始linuxdeployqt打包不行就是這個根本原因。

解決

  直接在編譯的時候,最優先的方式,讓應用去運行時先依賴相對路徑,而不是去依靠運行時的環境變量和配置文件了。
  pro加入配置文件:

# 這裏是添加運行應用的時候的運行包,此處避免額外設置LD_LIBRARY_PATH
QMAKE_RPATHDIR = ./lib

  點擊應用運氣的時候,應用自身會先依賴./lib下的庫查找。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章