linux下同時運行不同版本的qt程序

     因項目需要,可能有不同版本的qt程序要運行到同一臺機器上,本次實驗是qt4.8.5和qt5.3.1開發的程序同時運行在同一臺機器上,此機器可以不按照qt的任何版本,當然,兩個版本開發的qt與機器的位數必須一樣,例如都是32位或者64位。

    兩個版本的qt的程序我都採用動態編譯(靜態編譯方法請度娘),所以需要把運行程序所需的動態庫放到程序可以鏈接的地方,程序可以鏈接的動態庫路徑參見:linux動態庫搜索路徑。此處直接貼出結論:動態庫的搜索路徑搜索的先後順序是:

  1.編譯目標代碼時指定的動態庫搜索路徑;

  2.環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑;

  3.配置文件/etc/ld.so.conf中指定的動態庫搜索路徑;

  4.默認的動態庫搜索路徑/lib;

  5.默認的動態庫搜索路徑/usr/lib。

    考慮到一臺機器要運行多個不同版本的qt,而且不能要求機器一定會安裝了某個版本的qt,所以不同qt版本的程序所需的動態庫最好是放在編譯目標代碼指定的動態庫路徑,做到路徑獨立,因爲如果把動態庫放在/lib和/usr/lib的話,那麼其他版本的qt程序也會到這個地方搜索動態庫,可能出現衝突。故此,我這裏qt4.8.5和qt5.3.1的程序都在編譯時指定動態庫路徑爲工程所在目錄下面的lib。


一、對於qt4.8.5具體操作如下:

       1)修改工程文件(.pro文件),加上一行LIBS += -L./lib,注意,-L後面不能有空格,要緊跟你指定的動態庫路徑(可以自由指定),然後保存文件。

       2)在終端去到你工程所在目錄,執行命令qmake xxx.pro,其中xxx.pro是你的工程文件,命令執行完畢後生成Makefile,用vi或者其他工具打開Makefile,然後搜索LIBS,可以看到,我們這裏的LIBS已經加上了你剛纔在.pro文件裏面配置的./lib,具體如圖(圖中的-L./lib)所示:

        3)執行make得到可執行文件xxx。

     測試方法:通過ldd命令查看xxx依賴的動態庫指向哪裏,命令如下:

ldd untitled | grep -i qt, #這裏的untitled爲剛纔make出來的可執行文件

命令執行結果爲:

libQtGui.so.4 => /usr/local/Trolltech/Qt-4.8.5/lib/libQtGui.so.4 (0x00007f289a88e000)
libQtCore.so.4 => /usr/local/Trolltech/Qt-4.8.5/lib/libQtCore.so.4 (0x00007f289a3a0000),

可見此時編譯出來的可執行文件的動態庫是指向/usr/local/Trolltech/Qt-4.8.5/lib/,這個路徑爲qt的安裝路徑,個人猜測是你用qtCreator編寫qt程序時就已經默認加上這個動態庫搜索路徑的,這是qtCreator已經配置了這個路徑,具體見qtCreator的Tools-->Options-->Build & Run-->Kits-->Qt Version.

首先我們把這些依賴的庫拷貝到我們的可執行文件的同級目錄的lib下,首先用終端去到我們的qt工程所在目錄,執行命令如下:

mkdir lib    #創建lib目錄,目錄名必須要與我們在pro文件新增的LIBS += -L後面指定的目錄名稱一致

cp /usr/local/Trolltech/Qt-4.8.5/lib/libQtGui.so.4 ./lib  #把依賴的庫拷貝到lib裏面

cp /usr/local/Trolltech/Qt-4.8.5/lib/libQtCore.so.4 ./lib

我們通過屏蔽當前可執行文件指向的動態庫路徑模擬一個沒有安裝qt的機器,執行命令如下:

cd /usr/local/Trolltech/Qt-4.8.5;mv lib lib-bak,

這樣把lib改名後,我們重新執行了ldd untitled | grep -i qt,命令的結果如下:

libQtGui.so.4 => ./lib/libQtGui.so.4 (0x00007f89a6631000)
libQtCore.so.4 => ./lib/libQtCore.so.4 (0x00007f89a6142000),

可見此時的可執行文件可以自動把動態庫路徑指向我們編譯時執行的./lib,運行可執行文件正常。

     最終,我們發佈文件時,要把lib拷貝到可執行文件的當前目錄,同時把所需的庫拷貝到lib裏面,把可執行文件和lib一起發佈即可。


二、對於qt5.3.1:

       這裏我採用與qt4.8.5一樣的方法,在工程文件所在目錄創建lib目錄,然後在.pro文件加上LIBS += ./lib,然後重新qmake xxx.pro,然後make,然後ldd xxx | grep -i qt,然後,命令執行結果的所有so文件拷貝到工程文件所在目錄的lib裏面,然後屏蔽掉ldd xxx | grep -i qt命令執行結果的qt安裝路徑裏面對應的lib,即把這個對應的lib改個名字,然後運行我們的make出來的可執行程序,然後提示錯誤,error while loading shared libraries: libQt5Widgets.so.5: cannot open shared object file: No such file or directory,然後我用ldd查看動態庫鏈接情況,ldd version531 | grep -i qt,(version531爲make出來的可執行程序),結果如下:

    libQt5Widgets.so.5 => not found
    libQt5Gui.so.5 => not found
    libQt5Core.so.5 => not found
但是我查看工程目錄所在目錄的lib,裏面是有這幾個文件的,不過是一個軟連接,但是這個軟連接所鏈接的文件我也已經拷貝在lib裏面的,不知道爲什麼還是提示找不到,沒辦法,我只有通過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑到lib了,執行如下命令:

    export LD_LIBRARY_PATH=./lib

此時,再次運行可執行文件,然後又出錯,提示如下:
    This application failed to start because it could not find or load the Qt platform plugin "xcb".
Reinstalling the application may fix this problem.
Aborted

這個錯誤,我在網上搜索了下,這個錯誤的原因是qt5的新特性導致的,最終的解決辦法在工程目錄創建platforms目錄,然後把安裝qt5的目錄的lib所在目錄的同一級目錄的plugins/platforms裏面的libqxcb.so拷貝到剛纔新建的platforms目錄,重新運行可執行文件,可以正常運行,此時我把LD_LIBRARY_PATH環境變量置爲空也正常了。



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