Table of Contents
问题:在ubuntu16.04上用Clion写好的C++程序,用到了第三方库opencv,现在需要在一个没有装opencv甚至没有装Clion的linux电脑下执行,应该怎么打包发布呢?
问题:在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,程序运行过程中想要保存的资源就保存不了。
在打包的过程中注意以上问题。