linux C++打包程序总结
linux C++打包程序总结
linux c++ 动态库打包 应用程序打包 动态库搜索路径
1. 问题
linux环境下打包C++应用程序,包括依赖的动态库,以便解决程序发布后程序运行动态库缺失问题
2. 解决
l 动态库编译时添加-fPIC编译选项(一般动态库都会有此选项,自己写的库记得添加)
l -fPIC: 生成与位置无关代码
l 编译自己的应用程序,得到test
l 打包动态库:使用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 "$(dirname "$0")";pwd)
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${SHELL_FOLDER}/lib
${SHELL_FOLDER}/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="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$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="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$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="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$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