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

posted @ 2021-11-26 06:02  吴建明wujianming  阅读(3149)  评论(0编辑  收藏  举报