Cmake实践记录

前言

最近刚开始学习slam,在用高翔的《视觉slam十四讲》,该书第二讲的第8个习题要求将helloSLAM小程序库安装进计算机,并用find_packege调用。我没有任何计算机视觉基础,也没有用过Linux系统,因此写下这个博客当成我的学习记录。本文采用c++语言

Cmake

Cmake是一个用于管理源代码的工具,能高效地编译源代码。主要使用流程如下:
1、新建一个CMakeLists.txt文件并编辑
2、依次使用cmake命令和make命令

编译helloSLAM库

编写源文件

先在当前用户目录~下新建一个slam文件夹,cd到slam文件夹并新建一个文件夹ch1,在ch1文件夹中新建一个文件夹src用于存放源文件

cd ~
mkdir slam
cd slam
mkdir ch1
cd ch1
mkdir src

helloSLAM库的头文件

#ifndef HELLOSLAM_H_
#define HELLOSLAM_H_
int helloSLAMFunc();
#endif

helloSLAM库的库文件

#include<iostream>
#include "helloSLAM.h"
using namespace std;
int main()
{
	cout<<"Damn, I love Slam!"
	return 0;
}

编写CMakeLists.txt文件

在主工程目录ch1下,新建CMakeLists.txt文件,并写入以下内容

# 声明所需的cmake的最低版本为2.8
cmake_minimum_required(VERSION,2.8)

# CMAKE工程名helloSLAM
project(helloSLAM)

# 添加子工程目录
add_subdirectories(src lib)

接着在src目录下新建CMakeLists.txt文件,并写入一下内容

# 源文件名赋给LIB_SRC 变量
set(LIB_SRC helloSLAM.cpp)
# 将库设为共享库
add_librariy(helloSLAM SHARED ${LIB_SRC})

到此CMakeLists.txt编写完成,可以看出,除了主工程目录外,每一个需要管理的字母里也需要编写CMakeLists.txt文件,并利用add_subdirectories函数添加到主工程列表中。
add_ subdirectories()`函数的调用格式为

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

source_dir 可以指定需要管理的子目录,而binary_dir指定生成编译中间文件和结果的子目录。这两个目录均为相对路径,分别相对于PROJECT_SOURCE_DIRPROJECT_BINARY_DIR,这两个目录分别表示主工程路径和编译发生的路径。此例中PROJECT_SOURCE_DIR~/slam/ch1,而PROJECT_BINARY_DIR~/slam/ch1/build(build文件夹在下文新建)

使用cmake-make命令编译库

一般采用外部编译,将编译中间文件与源码分离。在主目录下新建build文件夹,cd到此文件夹

cd ~/slam/ch1
mkdir build
cd build

依次运行如下指令

cmake ..
make

便可在build/lib文件夹中看到libhelloSLAM.so库,其中库名称首尾的lib和.so为系统自动添加,表明该库为共享库,而helloSLAM为src/CMakeLists.txt中指定的库名称。
一般而言,动态库还需要一个版本号,可在src/CMakeLists.txt中添加

SET_TARGET_PROPERTIES(helloSLAM PROPERTIES VERSION 1.2 SOVERSION 1)

参数VERSION 指的是动态库版本,而SOVERSION 指的是API版本,此处待检验
重新运行cmake-make即可,使用tree命令检查build文件夹,可看到
动态库版本号

安装helloSLAM库

需要使用install命令来安装库文件和头文件,头文件使用普通格式安装,通用语法如下

INSTALL(FILES files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])

可在一条语句中同时安装多个文件
而库文件使用工程目标格式安装

INSTALL(TARGETS targets...
[[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS
[Debug|Release|...]]
[COMPONENT <component>]
[OPTIONAL]
] [...])

其中,RUNTIME 代指可执行文件,LIBRARY 特指共享库,ARCHIVE 特指静态库
本例中安装如下,在lib/CMakeLists.txt添加如下语句,将头文件安装在<prefix>/include/helloSLAM目录中,将库文件安装在<prefix>/lib目录中
头文件

set(LIB_HEAD helloSLAM.h)
INSTALL(FILES ${LIB_HEAD}
		DESTINATION include/hello/SLAM)

库文件

INSTALL(TARGETS helloSLAM
		DESTINATION lib)

为了指定<prefix>,需要在终端中使用如下指令

cd ~/slam/ch1/build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..

接着运行cmake-make即可完成编译和安装。

调用helloSLAM库

新建一个文件夹ch0,同时在ch0下新建src、build文件夹(意义同上)

编写cpp文件

在src文件夹中新建useHello.cpp,分别如下

//useHello.cpp
#include<iostream>
#include<helloSLAM.h>
int main()
{
	helloSLAMFunc();//调用库函数
	return 0;
}

改写CMakeLists.txt文件

主工程下新建CMakeLists.txt文件并编辑

# 声明所需的cmake的最低版本为2.8
cmake_minimum_required(VERSION,2.8)

# CMAKE工程名USEHELLO
project(USEHELLO)

# 添加子工程目录
add_subdirectories(src bin)

在src目录下新建并编辑CMakeLists.txt

#添加可执行程序
set(EXE_SRC useHello.c)
add_executable(useHello ${EXE_SRC})

#目录前缀
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr")

#添加库的头文件目录
include_directories(include/helloSLAM)

#添加库文件目录
link_directories(lib)

#将可执行文件与库连接起来
target_link_libraries(useHello helloSLAM)

其中target_link_libraries()函数中库参数可以赋为库的目标名称helloSLAM,也可赋为库名称libhelloSLAM.so
cd 到build目录下,执行cmake-make即可

利用find_package()查找并调用helloSLAM库

自编库

我们安装好库之后,调用是每次都需要去检查库的位置,这是非常麻烦的,于是我们便可以编写FindhelloSLAM.cmake文件(称为module),来记录库的位置,下次直接读取该文件即可实现对库的路径和名称查找。FindhelloSLAM.cmake的一般放在二级目录cmake文件夹下,本例中为~/slam/ch1/cmake
FindhelloSLAM.cmake文件内容如下

# 辅助输出信息
message("now using FindhelloSLAM.cmake find demo9 lib")
 
# 将helloSLAM.h文件路径赋值给HELLOSLAM_INCLUDE_DIR,FIND_PATH可以指定若干个查找路径,查到的第一个赋给HELLOSLAM_INCLUDE_DIR 
FIND_PATH(HELLOSLAM_INCLUDE_DIR helloSLAM.h /usr/include/demo9/
        /usr/local/demo9/include/)
 
# 将libhelloSLAM.so文件路径赋值给HELLOSLAM_LIBRARY,FIND_LIBRARY可以指定若干个查找路径,查到的第一个赋给HELLOSLAM_LIBRARY 
FIND_LIBRARY(HELLOSLAM_LIBRARY libhelloSLAM.so /usr/local/demo9/lib/)
 
if(HELLOSLAM_INCLUDE_DIR AND HELLOSLAM_LIBRARY )
    # 设置变量结果
    set(HELLOSLAM_FOUND TRUE)
endif(HELLOSLAM_INCLUDE_DIR AND HELLOSLAM_LIBRARY )

该文件指定了三个变量的值,以供CMakeLists.txt文件使用,分别是HELLOSLAM_INCLUDE_DIR 、HELLOSLAM_LIBRARY 、HELLOSLAM_FOUND
对应的src/CMakeLists.txt中内容如下

#添加可执行程序
set(EXE_SRC useHello.c)


set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
find_packages(helloSLAM)
if(HELLOSLAM_FOUND)
	add_executable(useHello ${EXE_SRC})
	
	#添加库的头文件目录
	include_directories(HELLOSLAM_INCLUDE_DIR )

	#添加库文件目录
	link_directories(HELLOSLAM_LIBRARY)
	
	#将可执行文件与库连接起来
	target_link_libraries(useHello helloSLAM)
else()
	message("Library : helloSLAM Not Found")
endif(HELLOSLAM_FOUND)

非自编库

对比非自编库,一般库的作者会提供Find<lib_name>.txt文件和CMakeLists.txt文件,库安装完成后自动在Find<lib_name>.txt文件中指定库的路径,调用时只需直接使用find_packages即可。
此外cmake软件还提供了许多多常用库的module来帮助查找该库使用命令

cmake --help-module-list 

可以查看提供了哪些module

本文参考Cmake实践与踩坑记录

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值