用Cmake编译程序时,链接到FFmpeg库
一、前言
可喜可贺,折腾了一晚上终于把这个勾八链接成功了,已经要吐了。看到下面控制台的输出,吾心甚慰呀😭
[100%] Linking CXX executable rknn_yolov5_demo
[100%] Built target rknn_yolov5_demo
[100%] Built target rknn_yolov5_demo
Install the project...
下面总结一下,我之前链接失败的几点原因:
-
忽略了系统架构之间的差别
Cmake工具运行的环境是Ubuntu18.04操作系统,系统架构为X86_64;而我的目标环境是嵌入式操作系统,该系统安装在RKNN 1808(瑞芯微)开发板上,系统架构为aarch(ARM 64);
这导致链接时出现了千奇百怪的错误,几度差点心态崩溃
-
盲目拷贝文件,没考虑各种依赖问题
上面第一点屡试不爽后,我转移了目标,让甲方开发人员在RKNN开发板上先安装了FFmpeg工具,然后我直接将板子上的共享库so文件和头文件拷贝了过来。
继续尝试链接,依然失败,而且此次的问题比上次更多了,疯狂查阅资料发现是我只拷贝了文件却忽略了这些文件的依赖,因此惨败。
直到第3次,我尝试自己对FFmpeg进行交叉编译【见另外一篇文章:ubuntu下交叉编译ffmpeg到目标架构为aarch架构的系统-CSDN博客】,最终才得以链接成功,不过嘛我好像跑题了嘿嘿,我是要介绍怎么链接FFmpeg而不是怎么正确地搞到FFmpeg相关东西。
二、包含头文件和链接共享库
-
找到共享库的路径和头文件所在路径(小声说:其实如果你是自己编译的ffmpeg,你应该知道在哪)
find / -name "libav*
运行命令后,操作系统会在整个文件系统中查找这个东西,然后返回位置,比如我的返回:
/home/fy/LIBS/ffmpeg5.0.1_linux_arm64/lib/libavfilter.so /home/fy/LIBS/ffmpeg5.0.1_linux_arm64/lib/libavcodec.so /home/fy/LIBS/ffmpeg5.0.1_linux_arm64/lib/libavdevice.so /home/fy/LIBS/ffmpeg5.0.1_linux_arm64/lib/libavutil.so /home/fy/LIBS/ffmpeg5.0.1_linux_arm64/lib/libavformat.so
注意,返回的可能有多个不同路径的结果,此时你就需要甄别,哪些是当前系统的,哪些是用在目标系统的
然后,就可以打开【/home/fy/LIBS/ffmpeg5.0.1_linux_arm64】这个文件夹,头文件和共享库都在这个文件夹的子文件夹下,瞅瞅我的:
(base) root@110kmg49ac7fk-0:/home/fy/LIBS/ffmpeg5.0.1_linux_arm64# ls bin include lib share
上面列出了4个文件夹,其中【include】是头文件的目录,【lib】是共享库文件的目录
-
包含头文件
打开你用于编译C++程序的CMakeLists文件,在任何位置,当然,一般写在中下部,写下面的语句,设置头文件的目录:
set(FFMPEG_INCLUDE_DIRS /home/fy/LIBS/ffmpeg5.0.1_linux_arm64/include ) include_directories(${FFMPEG_INCLUDE_DIRS})
- 【set】该关键字在Cmake工具里用于设置一个变量
- 【FFMPEG_INCLUDE_DIRS】该字符串为变量的名字
- 【/home/fy/LIBS/ffmpeg5.0.1_linux_arm64/include】该串为头文件的目录,现在这个是我的,你应该修改为你的
- 【include_directories】该关键字用于包含一个目录
- 【${FFMPEG_INCLUDE_DIRS}】这个表示我们的头文件目录了,里面的变量介绍过了,【${}】用来引用一个变量
因为【include_directories】的参数就是一个路径,而我们的变量【FFMPEG_INCLUDE_DIRS】就是给我们的路径起了个别名而已,因此上面的语句还可以简化为
include_di