統(tǒng)信UOS系統(tǒng)開發(fā)筆記(七):在統(tǒng)信UOS系統(tǒng)上使用linuxdeployqt發(fā)布qt程序
前言
??在ubuntu上發(fā)布qt程序相對還好,使用腳本,但是在統(tǒng)信UOS麒麟上發(fā)布的時候,因為銀河麒麟等不同版本,使用腳本就不太兼容,同時為了實現(xiàn)直接點擊應用可以啟動應用的效果,使用linuxdeployqt發(fā)布qt程序。
注意
??本篇文章,最終手動結(jié)合幾個方式成功,花費不少時間研究,推斷是終端直接ldd之后強制進入了一個另外的環(huán)境變量,導致無法連接成功,也就是,第一層是成功的,第一層的庫又調(diào)用ldd依賴的這一步的環(huán)境變量被強了。
??但是最后通過手動來實現(xiàn)linuxdeplopyqt和編譯配置來實現(xiàn)打包部署了。
統(tǒng)信UOS系統(tǒng)版本
??系統(tǒng)版本:
??

linuxdeployqt
??Linux部署工具linuxdeployqt將應用程序作為輸入,并通過將應用程序使用的資源(如庫、圖形和插件)復制到一個包中使其自包含。結(jié)果包可以作為AppDir或AppImage分發(fā)給用戶,也可以放入交叉分發(fā)包中。它可以作為構(gòu)建過程的一部分,在CMake、qmake和make等系統(tǒng)中部署用C、C++和其他編譯語言編寫的應用程序。當用于基于Qt的應用程序時,它可以綁定運行應用程序所需的Qt的特定最小子集。
源碼下載地址
??gitcode地址:https://gitcode.net/mirrors/probonopd/linuxdeployqt
linuxdeployqt編譯(統(tǒng)信UOS系統(tǒng))
步驟一:下載解壓
??

步驟二:修改源碼,去掉gcc版本檢查
??找到main.cpp源碼,將這一段(在192行左右)注釋掉(這里通過看源碼,實際上是可以通過配置去控制的(研究源碼發(fā)現(xiàn)的,但是我們不再動作了,只是貼出來):
??

??還是老方法繼續(xù)修改:
vi linuxdeployqt-master/tools/linuxdeployqt/main.cpp
??

步驟三:使用cmake配置
cd linuxdeployqt-master
cmake CMakeLists.txt
??

??因為安裝了git與這個工程可能不對,我們直接使用源碼修改大法,直接定位到代碼給刪掉:
vi CMakeList.txt
??直接刪掉目錄下的緩存文件:CMakeCache.txt,然后繼續(xù):
??

??繼續(xù)cmake CMakeList.txt
步驟四:配置Qt的依賴環(huán)境
??麒麟系統(tǒng)本身自帶了qt5庫(未帶開發(fā)相關的庫),而我們使用了另外安裝的qt5,所以依賴需要引入我們自己安裝的qt5上。
??為了方便配置,也不影響系統(tǒng)我們裝上cmake的gui版本:
sudo yum install cmake-gui
??

??

cmake-gui
??選擇對應的路徑,然后使用默認unix makefile方式配置:
??

??

??

步驟五:生成generate
??

步驟六:編譯make
??切入build目錄,并且使用make命令即可:
make
??

??測試程序:
??

步驟七:安裝到系統(tǒng)目錄
??沒有make install這個,手動移動到/usr/local/bin
sudo cp tools/linuxdeployqt/linuxdeployqt /usr/local/bin/
??

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

linuxdeployqt打包流程(arm看可以,本次pc版本失?。?/h1>
??(PS:虛擬機打包好之后,退回到裸機版本,再測試)
??新建一個工程
??

??然后,找個空目錄:
??

??未打包在開發(fā)機上也可以運行(裸機不行):
??

??這里要將Qt引入環(huán)境,為了不影響系統(tǒng),使用source腳本引入,每次使用之前使用source env.sh引入即可。
touch env.sh
??然后輸入如下(QT_DIR為安裝Qt的路徑):
#!/bin/shQT_DIR=/home/yang/Qt5.12.8/5.12.8/gcc_64export PATH=${QT_DIR}/bin:$PATHexport LIB_PATH=${QT_DIR}/lib:$LIB_PATHexport PLUGIN_PATH=${QT_DIR}/plugins:$PLUGIN_PATHexport QML2_PATH=${QT_DIR}/qml:$QML2_PATHexport LD_LIBRARY_PATH=${QT_DIR}/lib:$LD_LIBRARY_PATHecho $PATHecho $LIB_PATHecho $PLUGIN_PATHecho $QML2_PATHecho $LD_LIBRARY_PATH
??

??引入環(huán)境:
??

??下次打包遵循此流程即可,繼續(xù)打包:
??

??(PS:這里是沒有使用sudo進行的打包的,可能對權(quán)限管控比較嚴格,查看“入坑二”)
??下面使用sudo打包:
sudo linuxdeployqt testDemo -verbose2
??

??上面是Qt5Widget的庫連接到系統(tǒng)庫上去了,版本不一樣找不到api
??下面是未打包的testDemo在開發(fā)機上:
??

??下面是未打包的testDemo在裸機上:
??

手動來實現(xiàn)linuxdeployqt打包
步驟一:應用放過去
??

??(這是開發(fā)機,直接運行也是可以的)
??

步驟二:創(chuàng)建qt.conf
??這個文件最重要,他就是調(diào)用testDemo應用時候,先加載然后去搜索庫路徑的配置,沒有他則走向系統(tǒng)環(huán)境變量了。
touch qt.confvi qt.conf
??內(nèi)容,是我們從另外國產(chǎn)麒麟打包的該文件復制的,如下:
??

# Generated by linuxdeployqt# https://github.com/probonopd/linuxdeployqt/[Paths]Prefix = ./Plugins = plugins
Imports = qml
Qml2Imports = qml
??這個時候,我們再運行一次:
??

??路徑從本地開始找了。
步驟三:實現(xiàn)其他三個文件夾依賴的拷貝
??

ls -lcp /home/yang/Qt5.12.8/5.12.8/gcc_64/translations/ . -rfcp /home/yang/Qt5.12.8/5.12.8/gcc_64/plugins/ . -rfcp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/ . -rfls -lh
??

??測試本機可運行了:
??

??(PS:這里是全部copy了庫,沒有進行依賴裁剪的,暫時不管了,花費時間遠超預期了)
步驟四:打包放到裸機上
??因為沒有裁剪,所以包比較大:
cd ..tar cvf outManual.tar outManualls -l outManual.tar
??

??拷貝到裸機上去。
??

??

步驟五:裸機上測試運行(失?。?/h1>
??還是失敗,如下:
??

??這還是之前一樣,libQt5Widget.so.5依賴libQt5Core.so.5,前面是用當前配置的,然后庫的依賴庫就強制引入到了/usr/lib64,跟之前l(fā)inuxdeployqt打包一樣的問題。
??

??然后有個念頭,于是嘗試加上LD_LIBRARY_PATH測試,可以運行成功,具體查看“入坑四”。
步驟六:編譯時引入運行時路徑pro配置QMAKE_RPATHDIR
??為了不在運行時額外添加環(huán)境變量,為了打包不出現(xiàn)xcb問題,還得修改一下.pro文件如下圖:
# 這里是添加運行應用的時候的運行包,此處避免額外設置LD_LIBRARY_PATH
QMAKE_RPATHDIR = ./lib
??

??編譯出來,單獨將testDemo2放置到原來的部署裸機上:
??

?最終,直接點擊可以運行成功。
入坑
入坑一:編譯linuxdeployqt的依賴Qt路徑問題
問題
??開始編譯的時候,讓其依賴了系統(tǒng),直接導致就算引入了其他qt的環(huán)境變量,打包也是依賴系統(tǒng),直接不打包
??

原因
??懷疑是跟編譯linuxdeployqt的依賴有關,所以重做一遍自己安裝Qt的cmake。
解決
??重做一遍自己安裝Qt的cmake后編譯,也還是一樣的。
??

入坑二:linuxdeployqt不復制的問題
問題
??如前面的入坑,就是不復制,與編譯依賴沒關系。
嘗試
??沒有辦法,直接干linuxdeployqt的main.cpp的源碼:
??1.先調(diào)試哪里沒有打印,每次修改源碼重新編譯之后,部署再打包看輸出結(jié)果。??(PS:發(fā)現(xiàn)qDebug()不輸出,輸出的是qInfo())
??

??

??

??將所有LogError換為qInfo(),如下圖:
??

??

??還是不行:
??

??繼續(xù):
??

??棘手的問題:
??

??至此可以確認是兼容性問題,這個問題比較棘手,短期內(nèi)調(diào)不好了。
解決
??Linuxdeployqt方式暫未解決,可以換個linuxdeployqt的版本,也許不同的uos版本也不會又這個問題了,很奇怪連LogError和qDebug都不出來。
??后續(xù),第二天突然想到是否需要sodu權(quán)限,嘗試了下,確實是的:
??

??所以又重做,使用sudo來打包了。
入坑三:依賴鏈接庫存在錯誤
問題
??

??這是和系統(tǒng)的沖突了。
??編譯的時候也是使用的安裝包的:
??

原因
??

??

??無解,qmake路徑和環(huán)境變相也都沒有問題
??

??檢查linuxdeployqt
??

嘗試1
??拍快照,然后目錄下的所有/usr/lib64/Qt5*刪除,首先檢查系統(tǒng)是否正常啟用,再打包嘗試。
sudo rm /usr/lib64/libQt5*
??重啟,確實,系統(tǒng)起不來了,系統(tǒng)依賴Qt5.11下的庫。
??

??所以不能刪除,此路不通。
嘗試2
??拍快照,然后將安裝的Qt5庫copy過去,首先檢查系統(tǒng)是否正常啟用,再打包嘗試。
??執(zhí)行copy指令,直接立即黑屏,此路不同。
??所以,/usr/lib64下的庫是不能動的。
??

??這里懷疑,從進入終端開始就進入了固定的優(yōu)先環(huán)境變量,只是推測,目前l(fā)inuxdeployqt又花費半天,暫時仍然無解。
解決方法(有點偏門,失敗)
??找不到一個庫就刪掉一個庫,此時系統(tǒng)是已經(jīng)將庫加載進內(nèi)存運行,是不影響正在運行的系統(tǒng),但是無法重啟,如下:
sudo linuxdeployqt testDemo -verbose2sudo rm /usr/lib64/libQt5Gui.so*
??

??
sudo linuxdeployqt testDemo -verbose2sudo rm /usr/lib64/libQt5Core.so*
??
sudo linuxdeployqt testDemo -verbose2sudo cp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/libicuuc.so* /usr/lib64/
??
sudo linuxdeployqt testDemo -verbose2sudo cp /home/yang/Qt5.12.8/5.12.8/gcc_64/lib/libicudata.so* /usr/lib64/
??
sudo linuxdeployqt testDemo -verbose2sudo yum install patchelfsudo linuxdeployqt testDemo -verbose2
??
??
??可以,uos你贏了,我放棄了!?。?/p>
入坑四:手動qt.conf模仿部署還是強制路徑切換
問題
??
原因
??分析該系統(tǒng)第二次搜索庫,總是會引入到/usr/lib64,這個問題很操蛋,從一開始linuxdeployqt打包不行就是這個根本原因。
解決
??直接在編譯的時候,最優(yōu)先的方式,讓應用去運行時先依賴相對路徑,而不是去依靠運行時的環(huán)境變量和配置文件了。
??pro加入配置文件:
# 這里是添加運行應用的時候的運行包,此處避免額外設置LD_LIBRARY_PATH
QMAKE_RPATHDIR = ./lib
??點擊應用運氣的時候,應用自身會先依賴./lib下的庫查找。
解決方法(有點偏門,失?。?/h1>
??找不到一個庫就刪掉一個庫,此時系統(tǒng)是已經(jīng)將庫加載進內(nèi)存運行,是不影響正在運行的系統(tǒng),但是無法重啟,如下:
sudo linuxdeployqt testDemo -verbose2sudo rm /usr/lib64/libQt5Gui.so*
??

??

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

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

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

sudo linuxdeployqt testDemo -verbose2sudo yum install patchelfsudo linuxdeployqt testDemo -verbose2
??

??

??可以,uos你贏了,我放棄了?。?!
入坑四:手動qt.conf模仿部署還是強制路徑切換
問題
??

原因
??分析該系統(tǒng)第二次搜索庫,總是會引入到/usr/lib64,這個問題很操蛋,從一開始linuxdeployqt打包不行就是這個根本原因。
解決
??直接在編譯的時候,最優(yōu)先的方式,讓應用去運行時先依賴相對路徑,而不是去依靠運行時的環(huán)境變量和配置文件了。
??pro加入配置文件:
# 這里是添加運行應用的時候的運行包,此處避免額外設置LD_LIBRARY_PATH
QMAKE_RPATHDIR = ./lib
??點擊應用運氣的時候,應用自身會先依賴./lib下的庫查找。