在开发c++项目时,采用cmake来组建项目十分方便,特别是需要支持跨平台时更是如此,cmake项目可以直接转换为visual studio项目,qt项目,client项目等。
1.cmake项目的核心组成部分
project(Test) //定义名字为“Test”的cmake工程
add_executable(demo //定义一个名字为“demo”的执行程序项目
file.hpp //包含所需的头文件和源文件
file.cpp)
add_library(demo //定义一个名字为“demo”的库程序项目
file.hpp //包含所需的源文件和头文件
file.cpp)同通过上述几行代码,就能创建出一个能编译出执行程序或者库程序的cmake项目
2.在cmake项目中使用第三方库
第三方库会包括include文件和lib文件,采用include_directories和link_directories,target_link_librariesproject(Test) include_directories(path/include) //把path/include添加到头文件搜索路径,注意只是添加了搜索路径,编译器会选择需要的进行编译而非全部编译link_directories(path/lib) //把path/lib添加到库的搜索路径,注意只是添加了搜索路径,编译器会选择需要的进行编译而非全部编译
add_executable(demo
file.hpp //和上述include_directories不同,这是添加的所有文件都会参与编译
file.cpp)
target_link_libraries(demo //把需要用到的库引入,这里只需要写库的名字即可,会自动在库搜索路径这寻找,也可以写库的全路径
myliblibmylib.so
libmylib.a)
使用第三方库需要注意,必须把改库所依赖的库及其头文件也引用进来。举例:假设我们基于opencv编译出来库libtestlib.so。那么在使用libtestlib.so时,必须include_directories去添加opencv的头文件,也需要target_link_libraries添加opencv的库
3.cmake中的变量
①定义变量使用变量可以简化cmake代码。cmake设置变量用set命令:set(MY_VAR str1)。一个变量可以存放多个字符串,用“;”分隔:set(MY_VAR str1; str2; str3)。这里的字符串不需要带双引号。例如,如果要把一个路径设为变量:set(MY_PATH /usr/local)或者set(MY_PATH /usr/local; /mnt/src)。②使用变量使用变量时,一定要用${MY_VAR}的格式,否则MY_VAR会被当作字符串
4.使用find_package有些大型的第三方库
包含很多so文件和头文件,让用户自行添加会比较麻烦,因此他们会做把添加的过程写成一个独立的cmake文件,用户只需要调用find_package即可
① 用户调用find_package函数,cmake编译程序会自动从搜索目录中寻找相应的 .cmake文件:eg: find_package(OpenCV REQUIRED), 会去搜索FindOpenCV.cmake文件,并执行该文件的代码
② .cmake文件里一般就包含了一些普通的cmake代码,把特定的库和头文件添加到特定的cmake变量。例如,如果系统安装了opencv,用find_package(OpenCV REQUIRED),就会生成两个变量:OpenCV_INCLUDE_DIRS 和OpenCV_LIBS,它们分别包含了所需要的头文件和库文件,使用时只需要include_directories(${OpenCV_INCLUDE_DIRS}), target_link_directories(demo ${OpenCV_LIBS})
③ 当然,使用findpackage的前提时相应的.cmake文件存在搜索目录里面。可以用set(CMAKE_MODULE_PATH mypath)来把mypath添加到搜索目录中④"REQUIRED"关键字的作用,可以注意到find_package函数用到了这个关键字,它的作用是,如果没找到,就报错
5.使用file函数批量添加文件
有时候,我们会给一个程序写了很多的头文件和源文件,逐个在add_executable里面添加会十分繁琐,此时可使用file函数:
file(GLOB MY_FILES
path1/.cpp
path2/.h)
会把path1中所有的cpp文件和path2中的所有h文件都添加到MY_FILES变量中,add_executable(demo ${MY_FILES})即可
6.install命令
编译好执行程序或者库文件后,一般需要打包一下,特别是编译库文件,需要把所以包含的头文件以及所依赖的库文件,打包到特定的路径下。采用make install 指令,完成打包功能。相应地,需要在cmake文件里面定义install功能,即使用install函数
①设置打包的目标路径:set(CMAKE_INSTALL_PREFIX mypath) //CMAKE_INSTALL_PREFIX的默认值是usr/local
②打包编译出来的执行程序或者库文件:install(TARGETS demo DESTINATION bin)//将demo程序放入
C
M
A
K
E
I
N
S
T
A
L
L
P
R
E
F
I
X
/
b
i
n
目
录
下
③
打
包
整
个
文
件
夹
:
i
n
s
t
a
l
l
(
D
I
R
E
C
T
O
R
Y
p
a
t
h
/
i
n
c
l
u
d
e
/
D
E
S
T
I
N
A
T
I
O
N
i
n
c
l
u
d
e
/
)
/
/
将
p
a
t
h
/
i
n
c
l
u
d
e
文
件
夹
里
面
的
所
有
文
件
,
放
入
{CMAKE_INSTALL_PREFIX}/bin目录下 ③打包整个文件夹:install(DIRECTORY path/include/ DESTINATION include/) //将path/include文件夹里面的所有文件,放入
CMAKEINSTALLPREFIX/bin目录下③打包整个文件夹:install(DIRECTORYpath/include/DESTINATIONinclude/)//将path/include文件夹里面的所有文件,放入{CMAKE_INSTALL_PREFIX}/include里面。这里有个细节要注意:path/include 和 path/include/是不一样的。install(DIRECTORY path/include/ …),表示复制include里面的所有文件,install(DIRECTORY path/include …)表示复制include文件夹本身。
7.给编译器添加标志
在源代码中,需要一些标志来实现跨平台支持,或者选择性编译。例如,根据DEBUG判断是debug模式还是release模式,根据WIN32判断系统的情况等。这些标志都是需要在编译之前定义的,在cmake文件里面可以添加。另外需要注意,cmake文件里面的变量不是标志,它们不会进入编译阶段。添加标志的方式:add_definitions(-D MY_DEFINITON)
备注:
点击下面链接,进入奥比中光开发者社区,了解更多3D视觉技术信息:
https://developer.orbbec.com.cn/
或扫描下方二维码,进入奥比中光开发者社区: