运行系统:Ubuntu20.04
运行环境:
python
2.7.17系统不一样,遇到的问题可能不一样,该方法不一定见效
问题描述
:工作中时常需要调用同事写的.so文件作为一些功能的接口,那么如何将cmake文件进行动态库生成和调用呢?实现方法或许有多种,此处记录自己成功使用的一种。
问题分析:
动态库的生成比较简单,动态库的调用有时会遇麻烦(比如找不到库,找不到cpp中包含的头文件等)
1、.so文件的生成
首先创建一个完整的项目包,cpp文件中包含自身的.h文件
mkdir test_
cd /test_
mkdir include
cd /include
touch test.h
cd ../
touch test.cpp
touch CMakeLists.txt
在CMakeLists.txt中写入必要的信息
,
并加上生成动态库的指令:
add_library(test SHARED test.cpp)
target_link_libraries(test lib(该文件的依赖库))
该过程中注意将自己的头文件包含进来,不然编译报错找不到test.h
include_directories(${PROJECT_SOURCE_DIR}/include) #头文件的路径
接下来在build目标下进行编译即可得到一个libtest.so文件
mkdir build
cd build
cmake ../
make
动态库的生成就完成了。。。
若要提高代码的运行速度,编译前可将文件设置成发行版,即在CMakeLists.txt文件中加入如下指令!!!
set(CMAKE_BUILD_TYPE "Release")
2、.so文件的链接
以调用上述libtest.so动态库为例,首先将libtest.so及test.h文件拷贝至你当前的项目(或某一位置)
在你的cpp文件中调用该头文件
#include "test.h"
在CMakeLists.txt中添加必要的信息后,
添加调用该库的指令:
include_directories(tesh.h所在的目录路径) //路径不需要带/test.h
add_executable(A, A.cpp)
target_link_libraries(A, libtesh.so文件的路径)
一开始遇到的一些问题:
1、认为只要调用了libtest.so,不再需要拷贝test.h和在CMakeLists.txt中include_directories(),cpp中include “test.h”就能用了,因为生成libtest.so文件时已经包含了这个头文件,实际上编译会报错找不到该头文件。
想一想:
我们调用第三方库的时候,比如opencv,是不是需要在CMakeLists.txt中include_directories(¥{OpenCV_INCLUDE_DIRS}),安装opencv时本地是不是也下载了opencv库中的那些.h文件。所以调用别人的动态库也是一样,需要拷贝libtest.so文件和test.h头文件,在CMakeLists.txt中需要查找该.h文件。
2、自己的项目文件和调用的libtest.so库文件依赖的第三方库相同的情况下,认为libtest.so文件中包含的第三方库能作用于自己的项目,target_link_libraries()不再需要包含相同的第三方库,实际上是不能的,或许libtest.so文件中包含第三方库的作用域局限于test文件本身(猜的),target_link_libraries()在包含libtest.so文件的同时,需要再包含自身项目所需的第三方库。
3、调用libtest.so与调用其他第三方库的区别在于,第三方库是下载至本地,需要通过find_package()去查找,再通过include_directories()去包含头文件,再通过target_link_libraries()链接动态库。调用libtest.so只需要include_directories()和target_link_libraries(),记得拷贝.h文件和.so文件,如果是自己电脑生成的.so文件,只需写对文件路径即可。
###################理解不是很深,后面再做补充######################