linux C++打包程序总结
linux C++打包程序總結
linux c++ 動態庫打包 應用程序打包 動態庫搜索路徑
- 問題
linux環境下打包C++應用程序,包括依賴的動態庫,以便解決程序發布后程序運行動態庫缺失問題 - 解決
? 動態庫編譯時添加-fPIC編譯選項(一般動態庫都會有此選項,自己寫的庫記得添加)
? -fPIC: 生成與位置無關代碼
? 編譯自己的應用程序,得到test
? 打包動態庫:使用pack_lib.sh腳本將test依賴的動態庫至某文件夾(如可在發布的程序根目錄下新建lib文件夾,如下所示)
bin/test
lib/
#! /bin/sh
pack_lib.sh
deplist=$( ldd $1 | awk ‘{if (match($3,"/")){ print $3}}’ )
cp -L -n $deplist $2
使用方式:
sudo chmod a+x pack_lib.sh # 增加執行權限
./pack_lib.sh test ./lib/ # 第一個參數: 應用程序 第二個參數: lib/路徑
4.創建發布后應用程序執行腳本:作用是將工程目錄下的lib/路徑添加到動態庫搜索路徑中。當程序發布后,應當通過該腳本啟動應用程序。
#! /bin/bash
AppRun.sh
SHELL_FOLDER=(cd"(cd "(cd"(dirname “0")";pwd)exportLDLIBRARYPATH=0")";pwd) export LD_LIBRARY_PATH=0")";pwd)exportLDL?IBRARYP?ATH={LD_LIBRARY_PATH}😒{SHELL_FOLDER}/lib
SHELLFOLDER/test"{SHELL_FOLDER}/test "SHELLF?OLDER/test"@”
使用方式:
./AppRun.sh
如果test需要添加參數 如下
./AppRun.sh param1 param2
3. 擴展
運行時動態庫的搜索路徑的先后順序:
1.編譯目標代碼時指定的動態庫搜索路徑;
2.環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑;
3.配置文件/etc/ld.so.conf中指定的動態庫搜索路徑;
4.默認的動態庫搜索路徑/lib和/usr/lib;
C/C++編程:Linux下打包發布Qt應用程序
Linux下使用Qt進行開發的程序,如果想要在其它搭載Linux系統的主機上運行,需要將要發布的Qt程序依賴的一些動態鏈接庫一起打包。具體做法如下:
1、編譯文件
在Qt中使用release的方式編譯出可執行文件,然后新建一個文件夾,將可執行文件拷貝進去備用。
2.巧用腳本文件
這里以Server可執行文件為例。
在新建的文件夾下,新建兩個腳本文件:
? pack.sh
? Server.sh: 這個腳本文件名必須和要發布的程序名字相同,所以為Server
新建文件后,文件夾包含內容如下:
添加腳本
向pack.sh文件里添加以下內容:
#!/bin/sh
exe=“Server” #你需要發布的程序名稱
des="/home/mrzhong/server" #創建文件夾的位置
deplist=$(ldd $exe | awk ‘{if (match($3,"/")){ printf("%s "),$3 } }’)
cp $deplist $des
然后向Server.sh文件里,添加以下內容(內容不需要更改):
#!/bin/sh
appname=basename $0 | sed s,\.sh$,,
dirname=dirname $0
tmp="KaTeX parse error: Expected '}', got '#' at position 9: {dirname#??}" if [ "{dirname%KaTeX parse error: Expected 'EOF', got '}' at position 4: tmp}?" != "/" ]; the…PWD/dirnamefiLDLIBRARYPATH=dirname fi LD_LIBRARY_PATH=dirnamefiLDL?IBRARYP?ATH=dirname
export LD_LIBRARY_PATH
dirname/dirname/dirname/appname “$@”
執行腳本
終端進入文件夾目錄,運行:
./pack.sh
可執行文件依賴的鏈接庫將會拷貝到所在的目錄,如圖:
在其它主機里面使用和可執行文件同名的腳本文件(這里為Server.sh)運行程序即可。
打包發布
最后將這個文件打包后拷貝到其它主機上即可運行
linux (centos)c++項目打包并部署到其它服務器運行
總結發版步驟:
1、使用cmake 打包成可執行文件(這個過程也很復雜,這里不做討論)
2、使用ldd 查看可執行文件依賴庫,可以記錄一下個數,和導出的文件做對比
ldd可執行文件。
3、編寫shell腳本,把可執行文件導出到指定的文件夾
3.1、新建文件夾 lddlib.sh
vim lddlib.sh輸入下面的腳本
deplist=$( ldd $1 | awk ‘{if (match($3,"/")){ print $3}}’ )
cp -L -n $deplist $2
3.2、執行lddlib.sh
lddlib.sh 可執行程序,存放依賴庫的目錄
4、把可執行文件和依賴庫到拷貝到服務器,使用rz 和 sz 進行文件轉移
5、設置環境變量
臨時有效方式:可以做測試或者沒有權限時這樣做
export LD_LIBRARY_PATH=/dev/nm/project/Spider/lib
永久有效方式:
可以把依賴的庫都拷貝到/usr/lib 下
然后執行 /sbin/ldconfig
到這里就可以運行了!
在Linux下用sh打包發布基于opencv的C++可執行文件
問題:在ubuntu16.04上用Clion寫好的C++程序,用到了第三方庫opencv,現在需要在一個沒有裝opencv,甚至沒有裝Clion的linux電腦下執行,應該怎么打包發布呢?
解決過程:
1.準備已運行好的可執行程序
2.新建腳本文件
2.1 pack.sh
2.2 untitled5.sh
3.執行腳本
4.需要注意的問題
問題:在ubuntu16.04上用Clion寫好的C++程序,用到了第三方庫opencv,現在需要在一個沒有裝opencv甚至沒有裝Clion的linux電腦下執行,應該怎么打包發布呢?
ubuntu打包opencv和C++可執行程序。
一開始用寫的腳本復制依賴庫,但腳本運行出錯,不曉得是啥的問題。然后一個一個依賴庫的復制。最后打包發到別的電腦上顯示找不到依賴庫,之后添加環境變量,依然出錯。
在Linux下用sh打包發布可執行文件:這個方法直接就成功了,感謝這位博主。
可以同時參考這兩個文章,能大概了解打包過程并解決問題。)
解決過程:
用的C++編譯軟件是CLion,實際上與Qt的打包過程相同,可參照上面的第二個博客。
1.準備已運行好的可執行程序
以寫的程序為例,先新建文件夾(名字隨意)test 。
將之前已運行好生成的可執行文件放入test。我運行的程序包名為untitled5,這里生成的可執行文件也叫做untitled5。可執行文件在如下位置:
將這些文件復制到新建的test文件夾中:
2.新建腳本文件
需要新建兩個腳本文件:pack.sh 和 untitled5.sh。
pack.sh:主要是為了復制可執行文件untitled5所需要的依賴庫。
untitled5.sh:是為了在別的電腦上運行可執行文件untitled5。
2.1 pack.sh
pack.sh腳本的內容為:
#!/bin/sh
exe=“untitled5” #發布的程序名稱
des="/home/bei/Desktop/test" #創建文件夾的位置
deplist=$(ldd $exe | awk ‘{if (match($3,"/")){ printf("%s "),$3 } }’)
cp $deplist $des
此腳本的作用在于,會將untitled5所需要的依賴庫復制到創建的文件夾的位置,放到test中。
當程序名稱和新建文件夾名稱位置和我的不同時,只需修改第二行和第三行的內容。
2.2 untitled5.sh
untitled5.sh的腳本內容為:
#!/bin/sh
appname=basename $0 | sed s,\.sh$,,
dirname=dirname $0
tmp="KaTeX parse error: Expected '}', got '#' at position 9: {dirname#??}" if [ "{dirname%KaTeX parse error: Expected 'EOF', got '}' at position 4: tmp}?" != "/" ]; the…PWD/dirnamefiLDLIBRARYPATH=dirname fi LD_LIBRARY_PATH=dirnamefiLDL?IBRARYP?ATH=dirname
export LD_LIBRARY_PATH
dirname/dirname/dirname/appname “$@”
此腳本的作用是執行可執行程序untitled5。
腳本內容不需要修改,直接復制即可。
3.執行腳本
在pack.sh所在位置打開終端,運行:
sh ./pack.sh
會發現test中出現了許多依賴庫文件,如圖:
此時,已經可以將test文件夾打包發到別的linux電腦上,在untitled5所在位置打開終端,運行untitled5.sh腳本:
sh ./untitled5.sh
即可成功運行。
4.需要注意的問題
但需要注意的一點是,如果可執行程序中不需要圖片、視頻等需要在項目中提前準備好的之類的資源,按照以上方法打包不存在問題。但如果程序執行過程中需要這類的資源,在打包test時,一定要將需要的資源打包進去,否則程序會出錯。比如我的程序需要用到一些圖片和視頻,在沒有將這些資源打包進去前,執行腳本程序會出現錯誤:
有新建了一個文件夾Test,將test放入Test中,再將需要用到資源所在文件夾放入Test中。如圖:
需要注意的是,不能將video和video_one直接放入test中,這樣依然會出錯。也不能單獨將需要的資源直接放入Test中。這應該是與整個項目的結構有關,拿這個項目為例,整體結構如下:
實際上,在主程序中只用到了map.jpg以及NoObjects.png這兩張圖片,但不能將這兩張圖片直接放入Test中,也就是說,test相當于cmake-build-release(cmake-build-release中存放是可執行程序及相關文件),video存放的是程序需要的資源,video_one存放的是程序運行過程中需要保存的資源,如果Test中沒有將video和video_one放在與test文件夾同一目錄下,程序就會出現問題。沒有video,程序會運行出錯;沒有video_one,程序運行過程中想要保存的資源就保存不了。
在打包的過程中注意以上問題。
Linux打包opencv和C++可執行程序
在Linux上寫好的C++程序,用到了第三方庫opencv,現在需要在一個沒有裝opencv的linux電腦下執行,做個筆記,希望對需要的人有幫助
參考:
http://www.ngui.cc/51cto/show-6859.html
https://blog.csdn.net/qq_28901541/article/details/97310437
1.準備編譯好的c++程序以及可執行文件
圖一
上面目錄是經過如下編譯后的結果,
cmake .
make -j4
./yolov4是編譯好的可執行文件
yolov4是c++代碼
.bin和.param是轉后的ncnn模型
2.將編譯后ncnn靜態庫和代碼復制到上圖目錄下
git clone https://github.com/Tencent/ncnn.git #可使用鏡像加速github.com.cnpmjs.org和git.sdut.me/
cd ncnn
mkdir -p build
cd build
cmake …
make -j4
make install
編譯后ncnn靜態庫:./ncnn/build/install
2.1.在圖一新建ncnn文件夾,如下,
mkdir ncnn
cd ncnn
mkdir include
mkdir lib
2.2.將編譯后ncnn靜態庫和文件移動到2.1新建的相應位置
./ncnn/build/install/include/ncnn -> 2.1中ncnn/include下
./ncnn/build/install/lib -> 2.1中ncnn/lib/下
3.移動依賴需要的腳本
需要新建兩個腳本文件:pack.sh 和 yolov4.sh。(yolov4.sh文件名需要和可執行文件名一致)
pack.sh:主要是為了復制可執行文件untitled5所需要的依賴庫。
yolov4.sh:是為了在別的電腦上運行可執行文件yolov4。
pack.sh #此將c++執行需要的opencv依賴庫單獨copy出來,用于在其它機器上用
#!/bin/sh
exe=“yolov4” #發布的程序名稱
des="./opencv3.4" #創建文件夾的位置
deplist=$(ldd $exe | awk ‘{if (match($3,"/")){ printf("%s "),$3 } }’)
cp $deplist $des
執行的出現了問題,把腳本在命令行下分開執行了
yolov4.sh
#!/bin/sh
appname=basename $0 | sed s,\.sh$,, # $0是腳本文件名,所以腳本文件一定要和可執行文件名保持一致
dirname=dirname $0
tmp="KaTeX parse error: Expected '}', got '#' at position 9: {dirname#??}" if [ "{dirname%KaTeX parse error: Expected 'EOF', got '}' at position 4: tmp}?" != "/" ]; the…PWD/dirnamefiLDLIBRARYPATH=dirname fi LD_LIBRARY_PATH=dirnamefiLDL?IBRARYP?ATH=dirname
export LD_LIBRARY_PATH
dirname/dirname/dirname/appname “$@”
4.執行腳本
./pack.sh
即可成功運行。
最終目錄
5.復制到其它機器,編譯c++文件
sh yolov4.sh
cmake .
make -j4
./yolov4 #執行正常
CMakeLists.txt少了個 project(yolov4) ,添加上就ok了
在win10 Ubuntu子系統下編寫pack.sh時候
執行sh pack.sh報錯
調查后參考:https://www.cnblogs.com/willingtolove/p/13387424.html
window下的換行是回車符+換行符,也就是\r\n,而unix下是換行符\n。
使用vim打開xxx.sh
vim xxx.sh
直接輸入“:set ff”,不用進編輯模式;
如果輸出“fileformat=dos”,說明文本格式是windows下的;
直接輸入“:set ff = unix” 即可。
參考鏈接:
https://www.cnblogs.com/nmhome/p/14776440.html
https://blog.csdn.net/mjj1024/article/details/107110640
https://blog.csdn.net/yiersab/article/details/112391845
https://blog.csdn.net/zhizhengguan/article/details/105482209
https://www.cnblogs.com/wangxujoy/p/12499839.html
總結
以上是生活随笔為你收集整理的linux C++打包程序总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习编译器Data Flow和Con
- 下一篇: JIT Code Generation代