本次記錄僅作參考。
程序說明:
程序是一個編解碼器控制管理的工具,使用到的庫有:Qt的WebEngine
、OpenGL
模塊、poco
庫、libmicrohttpd
、libcurl
、libvlc
。同時程序間接的依賴libssl/libxml2等庫。
其中poco
/libcurl
/libmicrohttpd
等都編譯為了靜態庫,libvlc
/Qt
庫都是動態庫。這里主要解決動態庫的問題。
Qt官方文檔中關於Qt在X11下的依賴情況 http://doc.qt.io/qt-5/linux-requirements.html
打包過程:
首先在QtCreator中編譯運行程序,沒有問題。
重新手動使用`qmake`生成`Makefile`編譯后,運行程序出錯。
錯誤及解決:
錯誤1:
/home/x/program/qt-5.6.0/5.6/gcc_64/libexec/QtWebEngineProcess: error while loading shared libraries: libQt5WebEngineCore.so.5: cannot open shared object file: No such file or directory
這個錯誤是因為Qt庫的原因,這里可以現看一下生成程序的最后一步鏈接
的相關信息
g++ -Wl,-O1 -Wl,-z,origin -Wl,-rpath,\$ORIGIN -Wl,-rpath,/home/x/program/qt-5.6.0/5.6/gcc_64/lib -Wl,-rpath-link,/home/x/program/qt-5.6.0/5.6/gcc_64/lib -o WebCS main.o widget.o ActiveTasks.o Business.o CommonUtil.o JsonConfig.o NMUDPServer.o SocketUtil.o TCPLongConnection.o TCPServer.o UDPLongConnection.o UDPServer.o CharsetConvert.o CharsetConvertMFC.o CharsetConvertSTD.o FileAnywhereManager.o FileAnywhereObserver.o FileAnywhereTaskParameter.o InterfaceProcessTask.o InterfaceProtocolSpecific.o InterfaceServer.o UUID.o CBusinessEvent.o MircoHttpdInit.o VlcPlayer.o moc_widget.o moc_VlcPlayer.o -L/home/x/work/work/WebCS/Depends/libs -lmicrohttpd -lcurl -lNCX -lTaskModel -lPocoNet -lPocoJSON -lPocoXML -lPocoUtil -lPocoFoundation -lz -luuid -L/home/x/work/vlc-build/lib/ -lvlc -lvlccore -lssl -lcrypto -L/home/x/program/qt-5.6.0/5.6/gcc_64/lib -lQt5WebEngineWidgets -lQt5WebEngineCore -lQt5Quick -lQt5Widgets -lQt5Gui -lQt5Qml -lQt5Network -lQt5WebChannel -lQt5Core -lGL -lpthread
鏈接中有-Wl,-rpath,\$ORIGIN -Wl,-rpath,/home/x/program/qt-5.6.0/5.6/gcc_64/lib -Wl,-rpath-link,/home/x/program/qt-5.6.0/5.6/gcc_64/lib
指定了Qt庫文件的路徑,已經運行時候的查找路徑。
-rpath-link:這個也是用於“鏈接”的時候的,例如你顯示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你並沒有指定,而是 FOO.so 引用到它,這個時候,會先從 -rpath-link 給的路徑里找。 -rpath: “運行”的時候,去找的目錄。運行的時候,要找 .so 文件,會從這個選項里指定的地方去找。對於交叉編譯,交叉編譯鏈接器需已經配置 --with-sysroot 選項才能起作用。也就是說,-rpath指定的路徑會被記錄在生成的可執行程序中,用於運行時查找需要加載的動態庫。-rpath-link 則只用於鏈接時查找。
因為這里我們要打包,所以這里也不能直接使用絕對路徑。而QtWebEngineProcess
這個程序是程序運行時候加載運行的,所以這個程序也要帶上。
其實Qt的很多文件都需要帶上,這里就不啰嗦了。直接拷貝過來,要拷貝的內容如下。(使用cp命令的時候帶上-d
選項,避免跟蹤符號鏈接)
[x@localhost build]$ cd /home/x/program/qt-5.6.0/5.6/gcc_64/ [x@localhost gcc_64]$ ls -p bin/ include/ libexec/ phrasebooks/ qml/ .tag doc/ lib/ mkspecs/ plugins/ resources/ translations/ [x@localhost gcc_64]$ cp -d -R lib libexec phrasebooks plugins resources translations ~/work/work/WebCS/build/ # ~/work/work/WebCS/build/ 是我程序的編譯生成目錄 # plugins resources translations 這幾個都需要,不然WebEngine運行不起來
拷貝之后,使用下面的命令來重新鏈接生成程序
[x@localhost build]$ g++ -Wl,-O1 -Wl,-z,origin -Wl,-rpath,\$ORIGIN -Wl,-rpath,./lib -Wl,-rpath-link,./lib -o WebCS main.o widget.o ActiveTasks.o Business.o CommonUtil.o JsonConfig.o NMUDPServer.o SocketUtil.o TCPLongConnection.o TCPServer.o UDPLongConnection.o UDPServer.o CharsetConvert.o CharsetConvertMFC.o CharsetConvertSTD.o FileAnywhereManager.o FileAnywhereObserver.o FileAnywhereTaskParameter.o InterfaceProcessTask.o InterfaceProtocolSpecific.o InterfaceServer.o UUID.o CBusinessEvent.o MircoHttpdInit.o VlcPlayer.o moc_widget.o moc_VlcPlayer.o -L/home/x/work/work/WebCS/Depends/libs -lmicrohttpd -lcurl -lNCX -lTaskModel -lPocoNet -lPocoJSON -lPocoXML -lPocoUtil -lPocoFoundation -lz -luuid -L/home/x/work/vlc-build/lib/ -lvlc -lvlccore -lssl -lcrypto -L./lib -lQt5WebEngineWidgets -lQt5WebEngineCore -lQt5Quick -lQt5Widgets -lQt5Gui -lQt5Qml -lQt5Network -lQt5WebChannel -lQt5Core -lGL -lpthread
注意,這里將原本的絕對路徑改為了相對路徑。
然后進入將lib
目錄下的文件都創建軟鏈接到libexec
目錄。
# 進入lib目錄 [x@localhost build]$ cd lib # 刪除多余的文件(這些是不需要的,還有一些沒有用上的Qt模塊也可以刪掉) [x@localhost lib]$ rm *.la *.prl # 創建軟連接 [x@localhost lib]$ ls *.so|xargs -I{} ln -s ../lib/{} ../libexec/{} [x@localhost lib]$ ls *.so|xargs -I{} ln -s ../lib/{} ../libexec/{}.5 [x@localhost lib]$ ls *.so|xargs -I{} ln -s ../lib/{} ../libexec/{}.5.6 [x@localhost lib]$ ls *.so|xargs -I{} ln -s ../lib/{} ../libexec/{}.5.6.0 # libcui的庫,也要創建軟鏈接 [x@localhost lib]$ ls *.so.56*|xargs -I{} ln -s ../lib/{} ../libexec/{} # 上面五條命令其實可以直接使用 ls *.so*|xargs -I{} ln -s ../lib/{} ../libexec/{} 來實現
然后在當前build/libexec
目錄下新建qt.conf
文件,內容如下
[Paths] Prefix=..
然后在當前build
目錄下新建qt.conf
文件,內容如下
[Paths] Prefix=.
再運行就沒有Qt庫相關的問題了。
錯誤2:
core libvlc error: No plugins found! Check your VLC installation.
這是因為不能正確讀取VLC插件的原因。通過strace
命令跟蹤運行程序,可以找到其去讀取的位置(搜索輸出語句,往上一點找),會發現它會在當前build
目錄中查找,而實際上是這些插件是在vlc編譯安裝目錄/lib/vlc
目錄下。
在最后鏈接的時候 -L/home/x/work/vlc-build/lib/
這一句只是指定了鏈接libvlc``libvlccore
的目錄,所以這里做一點小的修改。
現把libvlc
中需要的相關文件都拷貝到build
目錄下。
[x@localhost build]$ cp /home/x/work/vlc-build/lib/* lib/ -R
重新鏈接一下
[x@localhost build]$ g++ -Wl,-O1 -Wl,-z,origin -Wl,-rpath,\$ORIGIN -Wl,-rpath,./lib -Wl,-rpath-link,./lib -o WebCS main.o widget.o ActiveTasks.o Business.o CommonUtil.o JsonConfig.o NMUDPServer.o SocketUtil.o TCPLongConnection.o TCPServer.o UDPLongConnection.o UDPServer.o CharsetConvert.o CharsetConvertMFC.o CharsetConvertSTD.o FileAnywhereManager.o FileAnywhereObserver.o FileAnywhereTaskParameter.o InterfaceProcessTask.o InterfaceProtocolSpecific.o InterfaceServer.o UUID.o CBusinessEvent.o MircoHttpdInit.o VlcPlayer.o moc_widget.o moc_VlcPlayer.o -L/home/x/work/work/WebCS/Depends/libs -lmicrohttpd -lcurl -lNCX -lTaskModel -lPocoNet -lPocoJSON -lPocoXML -lPocoUtil -lPocoFoundation -lz -luuid -L./lib -lvlc -lvlccore -lssl -lcrypto -L./lib -lQt5WebEngineWidgets -lQt5WebEngineCore -lQt5Quick -lQt5Widgets -lQt5Gui -lQt5Qml -lQt5Network -lQt5WebChannel -lQt5Core -lGL -lpthread
再次編譯運行,沒有問題了。但是考慮到別的機器可能沒有安裝openssl
、libuuid
、zlib
等,所以這里需要使用ldd
看一下程序還有那些依賴的動態庫是沒有打包進來的,除了libc.so.*
等這種基礎的庫,都可以拷貝到build/lib
目錄下。
錯誤3:
報了一個OpenGL函數沒有實現的錯誤。
OpenGL Warning: glXCreatePbuffer not implemented by Chromium OpenGL Warning: glXCreatePbuffer not implemented by Chromium OpenGL Warning: glXCreatePbuffer not implemented by Chromium OpenGL Warning: glXCreatePbuffer not implemented by Chromium js: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/. OpenGL Warning: glXCreatePbuffer not implemented by Chromium QOpenGLFramebufferObject: Unsupported framebuffer format. QOpenGLFramebufferObject: Unsupported framebuffer format.
這個問題是在給Virtual Box虛擬機中系統安裝了增強功能之后出現的,原本程序會鏈接到libGL.so*
,現在會鏈接到VBoxOGLcrutil.so
。
對於這個問題,直接關閉虛擬機的啟用3D加速
就可以了。
http://www.cnblogs.com/oloroso/p/6149000.html