CMakeLists.txt中调用自己编写的so库

文章目录

      • 1 问题
      • 2 解决
        • 2.1 .cmake文件方法
        • 2.2 暴力链接库方法
      • 3 例子
        • 3.1 生成libposelib.so
        • 3.2 调用so库

参考:https://blog.csdn.net/qq_41253960/article/details/121256498

1 问题

在使用ceres库时,CMakeLists.txt中出现:

...

# 添加cmake模块以使用ceres库
list( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules )

# 寻找Ceres库并添加它的头文件
find_package( Ceres REQUIRED )
include_directories( ${CERES_INCLUDE_DIRS} )

...

不太理解 list在这里的作用

2 解决

2.1 .cmake文件方法

之前接触的例子都是源文件和头文件都写在一个同一个文件下,或者是调用安装到/usr/local/include和/usr/local/lib中的库和头文件(如果ceres安装时没有执行sudo make install也不会安装到该目录下,也需要用现在讨论的list方法调用),之前没有调用过自己生成的so动态库文件。可以发现,我们使用过很多库发现他们都有一个文件夹叫cmake或者cmake_modules之类的。这类文件夹一般包含很多.cmake文件,这类文件把本来该写在CMakeLists.txt里的内容分散开来,用来找特定的库之类的。就好像我们写一个大型程序需要把很多功能分成特定的函数一样。

对于安装到本地的库(头文件所在目录/usr/local/include,库的位置位于/usr/local/lib.),一些大型的开源库,例如OpenCV,在输入:

find_package(OpenCV REQUIRED)

他就可以自己就能找到库,因为它们已经自带.cmake文件了,可以获取到头文件目录和库目录,并且把可执行文件链接到库

include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(test test.cpp)
target_link_libraries(test ${OpenCV_LIBS})

可是一些不知名的库,或者自己编译的库,你直接使用find_package( REQUIRED)是找不到库的。因为其实根本就不知道libNAME.so在哪里。例如,我自己生成的中的libPOSE.so

find_pakcage(POSE REQUIRED)

此时CMakeLists.txt这样解决:
1、在CMakeLists.txt相同目录下创建一个叫cmake_modules的文件夹,在里面创建一个名为FindPOSE.cmake的文件。命名格式Find.cmake,这也增加了规范性。

2、在FindPOSE.cmake中写入下面内容。

find_path(POSE_INCLUDE_DIRS NAMES pose.h PATHS /usr/local/include
											  /usr/include
											  /home/wuhd/wuhd/sl/mine/ch6_ceres/demo_cmake_module/pose
												...)
#会在几个候选的PATHS中找到头文件并把正确的目录赋给BAYES_INCLUDE_DIR

find_library(POSE_LIBRARIES NAMES poselib PATHS /usr/local/include
												/usr/include
 											    /home/wuhd/wuhd/sl/mine/ch6_ceres/demo_cmake_module/pose/build
												...)
#会在几个候选的PATHS中找到库文件并把完整的文件路径赋给BAYES_LIBRARIES

第一行命令要求寻找一个叫(NAMES) pose.h的头文件。并在CMakeLists.txt中命名为POSE_INCLUDE_DIRS.(后续cmakelists.txt中include_directories(${POSE_INCLUDE_DIRS})调用),POSE_INCLUDE_DIRS中的POSE名称尽量与FindPOSE.cmake中的POSE一致。

第二行命令要求寻找一个叫(NAMES) libposelib.so的库文件。并在CMakeLists.txt中命名为POSE_LIBRARIES . 可以看到我们只是指定了poselib,并不是指定找libposelib.so(指定也行)。这是程序默认的。任何库的名字都是lib开头。你只需要指定lib后的那串字符就可以了

3、在你的CMakeLists.txt中,加入下面的这句话(list)决定我们在哪儿去找.cmake文件。

set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)

或者

list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules/")

然后再find_package(POSE REQUIRED) 这个POSE与FindPOSE.cmake中的POSE一致。

cmake_minimum_required(VERSION 2.8)
project(demo)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules/")
find_package(POSE REQUIRED)  # POSE --> FindPOSE.cmake
include_directories(${POSE_INCLUDE_DIRS})
add_executable(demo main.cpp)
target_link_libraries(demo ${POSE_LIBRARIES})

2.2 暴力链接库方法

如果你实在不想写.cmake文件,但是又要链接到一个你不知道find_package(XXX REQUIRED)中name是何物的库,你可以用一种很暴力的方法。

比如你知道你要链接的库的位置就是在/usr/local/lib/libABC.so,你可以在target_link_libraries中直接添加这个路径

target_link_libraries(${PROJECT_NAME} /usr/local/lib/libABC.so)

这种方法也是可以的!不仅不用写cmake,而且连find_package这个语句都省略了,不过这样做的话以后别人使用你的程序来扩展会比较麻烦

3 例子

主要从调用so库举例,在例子中说明list的用法。

–pose
– --pose.cpp
– --pose.h
– --CMakeLists.txt
– --build
–main
– --main.cpp
– --cmake_modules
– -- --FindPOSE.cmake
– --CMakeLists.txt
– --build

3.1 生成libposelib.so

pose/pose.cpp:

#include"pose.h"  //千万不要漏了
int pose(int a, int b)
{
   return (a+b);
}

pose/pose.h:

int pose(int a, int b);

pose/CMakeLists.txt:

cmake_minimum_required( VERSION 2.8)
add_library(poselib SHARED pose.cpp)

在build下面生成libposelib.so,前面的lib会自动加上

3.2 调用so库

main/cmake_modules/FindPOSE.cmake:

#Try to find BAYES library
find_path(POSE_INCLUDE_DIRS NAMES pose.h PATHS /usr/local/include
											  /usr/include
											  /home/wuhd/wuhd/sl/mine/ch6_ceres/demo_cmake_module/pose
												...)
#会在几个候选的PATHS中找到头文件并把正确的目录赋给BAYES_INCLUDE_DIR

find_library(POSE_LIBRARIES NAMES poselib PATHS /usr/local/include
												/usr/include
 											    /home/wuhd/wuhd/sl/mine/ch6_ceres/demo_cmake_module/pose/build
												...)
#会在几个候选的PATHS中找到库文件并把完整的文件路径赋给BAYES_LIBRARIES

注意:一个是find_path,另一个是find_library
main/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(demo)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules/")
find_package(POSE REQUIRED)  # POSE --> FindPOSE.cmake
include_directories(${POSE_INCLUDE_DIRS})
add_executable(demo main.cpp)
target_link_libraries(demo ${POSE_LIBRARIES})

main/main.cpp:

#include
#include"pose.h"

using namespace std;

int main()
{
	int a=8, b=9;
	int c = pose(a, b);
	cout<<"c: "<

你可能感兴趣的:(CMakeLists.txt,几何学,c++,自动驾驶)