首页 >> 大全

CMake初级简明教程

2023-10-12 大全 30 作者:考证青年

我藏在人群中 然后失去晴空

像我的名字 从你的记忆清空。 —《你头顶的风》

本文仅仅介绍了一些常用函数的参数的简单写法以及个人理解,如果你想了解更多,可以去查找专门介绍该函数的博客。本文只能保证你读完之后对各个函数有基本的认识,以及最基本的应用。

个人认为,想要提高自己写能力的最好方法有两个。其一者,自己编写更加复杂的工程文件。其二者,阅读、修改现有库的。有的库的有上百行(比如PCL库),但是其实看明白之后就是很简单的几个模块判断、引入。尤其是后者,小学写过的字帖都有三部分:描红,仿影,临帖。先看人家怎么写,学会笔法之后再写自己的,编程学习之法可谓相同。

笔者才疏学浅,知识均由自学得来,故可能多有错漏。本文仅作抛砖引玉之用,欢迎读者斧正。

1.ed

含义:要求cmake的最小版本

示例

cmake_minimum_required(VERSION 2.8)

说明:

ed()命令隐式调用()命令,以指定为给定范围的cmake版本编写当前项目代码。

个人理解:

cmake各个版本在查找文件的策略等等上会有一些差异。通过这个函数指定最小版本。以保证当前的策略是你想要的策略。

对于初学者,无需管这个,随便指定一个就可以,例如 2.8.

2.

含义:指定本工程名称

示例:

project(test)

个人理解:

指定工程名称,随便起一个名字就可以。需要注意的是,这个指定的不是编译出来的exe或者是可执行文件的名字,那个是通过另一个函数指定的。这个就是工程的名字。

3.set

含义:设定变量的值

示例:

set(PCL_ROOT "D:/program-tools/PCL/PCL 1.12.1") //设定PCL_ROOT值为后面的路径
set(_waiting_for_debug 0)	//设定值为0
set(DEFAULT_CXX_STANDARD 11)  //设定值为11

个人理解:

这个函数基本可以看作赋值用的,需要注意的是,编译器往往有一些预定义的值,例如示例里面的 ,这个是编译器预定义的值,通过将其置为11,可以设定编译规范为C++11.

这个函数另一个重要作用就是指定库的路径,例如示例中的第一行,指定了PCL库的ROOT根目录。这一点我们下面也会谈到。

4.

这个函数非常非常非常重要,你编译的时候找不到包大部分都是因为这个函数使用不当引起的。而且有些问题非常隐秘。这一部分可能有点多,但是请务必看下去,不然到时候你debug一天也找不到问题的时候可不要后悔哦。

cmake本身不提供任何搜索库的便捷方法,所有搜索库并给变量赋值的操作必须由cmake代码完成,比如.cmake和.cmake。只不过,库的作者通常会提供这两个文件,以方便使用者调用。

例如,以著名的点云库PCL为例,其部分文件夹结构如下:

---PCL|---PCL 1.12.1|---include|--- ...(略,一些头文件)|---lib|--- ...(略,一些库文件)|---cmake|---PCLConfig.cmake|---PCLConfigVersion.cmake|---Modles|---FindEigen.cmake|---FindFLANN.cmake|---FindQhull.cmake|---FindOpenMP.cmake|--- ...(略,其余的依赖cmake文件)|--- ...(其他文件夹)

观察上面的文件夹结构,作者特意把cmake文件独立一个文件夹,而其库引导文件.cmake就在cmake目录下,我们不妨称之为根引导文件。在这个根引导文件的同级目录下,有一个文件夹,里面的文件都是诸如.cmake之类,顾名思义,显然是找到PCL库的其他依赖库的引导文件。我们不用打开根引导文件也能猜到,想必是这个.cmake调用了文件夹里面的这些小的查找文件,去查找所需的依赖库。所以怎么办,你只要让cmake找到这个.cmake根引导文件就可以了。这个根文件会自动调用其他查找文件。

find_package(OpenCV REQUIRED)

set(PCL_DIR  "D:/program-tools/PCL/PCL 1.12.1/cmake")
find_package(PCL REQUIRED)

这样就不会再报错了。

再比如,我要引入,怎么办:

set(OpenCV_DIR  D:/opencv/opencv3.4.6/opencv/build/x64/vc15/lib/)
find_package(OpenCV REQUIRED)

你可能注意到,这两个DIR一个是字符串,一个不是,这个不重要,两个写法都是可以的。

set(ABC_DIR "your path")
find_package(ABC REQUIRED)

模式:搜索指定路径下的.cmake文件,执行该文件从而找到XXX库。其中,具体查找库并给和两个变量赋值的操作由.cmake模块完成(先搜索当前项目里面的文件夹里面提供的.cmake,然后再搜索系统路径/usr/local/share/cmake-x.y//.cmake)模式:搜索指定路径下的.cmake文件,执行该文件从而找到XXX库。其中具体查找库并给和两个变量赋值的操作由.cmake模块完成。 5.

include_directories(${OpenCV_INCLUDE_DIRS})
include_directories("D:/program-tools/PCL/PCL 1.12.1/include/pcl-1.12/")
include_directories("D:/program-tools/PCL/PCL 1.12.1/3rdParty/FLANN/include/")

示例讲解:

第一行:${}是一个变量,里面的值显而易见是个路径。通过引入搜索路径。

第二、三行:引入指定头文件搜索路径。

个人讲解:

关于${}这类函数怎么来,一般是.cmake这种自带的引导文件自带的,你自己读就可以看到,一般都在注释里面注明了。

这种库提供的变量,其实一般已经被库自带的引导文件自动包含了,但是为了vs code的自动补全,你不妨再手动添加一下,反正也没什么坏处。

6.

含义:添加可执行文件

示例:

add_executable(main 
${PROJECT_SOURCE_DIR}/DNN/dnn.cpp
${PROJECT_SOURCE_DIR}/main.cpp
)

关于什么是${},自己去查,到这都四千字了懒得写了。

cmake高级教程__cmake入门教程

个人讲解:

第一个参数就是可执行文件的名字,下面就是main.exe,后面若干个参数都是说明了,这个可执行文件是由哪几个源代码编译过来的。当你的工程很简单的时候,可能一个cpp就可以编译出来一个exe可执行文件,但是一些稍微复杂一点的就不是这样的了。

需要注意的是,这个函数其实老版cmake是不支持一下添加好几个源文件的,因为其实源文件里面也有依赖关系,例如你在A.cpp里面定义了类A,在main.cpp里面使用了类A,那么如果你先编译main.cpp就会报错。但是我看现在的cmake好像都支持自动排序编译,很实用。不过仍然建议,按照你源文件的依赖顺序去写,对你自己也不无好处。

一个项目可以不止生成一个目标文件。

7.s

含义:对该目标链接库

示例:

target_link_libraries(main  ${OpenCV_LIBS})
target_link_libraries(test ${Boost_LIBRARIES} ${Qhull_LIBRARIES} ${PCL_LIBRARIES} ${PTHREAD_LIB})

个人理解:

需要注意的是,先生成目标再链接库。链接库是在编译成可执行文件后面的,不要把顺序搞反了。后面的其实是库的列表,这个${}大家有兴趣可以打印出来看看是什么。 8.

含义:输出,打印

示例:

message(root: "111 ${PCL_ROOT} 1111")

效果:

可以看到,${}括起来的自动替换为变量的值,而root:即使没有被套在双引号内,仍然是作为字符打印的。这个常用做调试,查看变量的值。这个是终端,没有颜色。如果是的,通过改变参数,可以输出红色、黄色等颜色的错误、警告。

9.简易示例1

这个是我写的一个DNN库的,这里没有把它编译成lib。可以作为参考。

cmake_minimum_required(VERSION 2.8)project(main)# SET(CMAKE_BUILD_TYPE "Release")	#可以设定优化为Release# set(CMAKE_CXX_FLAGS_RELEASE "-O3")    #可以设定优化级别为O3set(DEFAULT_CXX_STANDARD 11)	#C++11规范set(OpenCV_DIR  D:/opencv/opencv3.4.6/opencv/build/x64/vc15/lib/)find_package(OpenCV REQUIRED)include_directories(${OpenCV_INCLUDE_DIRS})include_directories(${PROJECT_SOURCE_DIR}/DNN/)add_executable(main 
${PROJECT_SOURCE_DIR}/main.cpp
${PROJECT_SOURCE_DIR}/DNN/dnn.cpp
)target_link_libraries(main  ${OpenCV_LIBS})

10.简易示例2(含)

这个是一个叫做的库,做出来的效果是这样的:

可以以系统通知的形式,横幅通知在屏幕右下方,文字、图标都可以换,有点好玩。这里我又自己二次封装了一下,注意看函数。这个文件写的很丑,不过既然是自己写着玩,我也就没管了。

cmake_minimum_required(VERSION 3.17)
project(wintoasttest)
add_definitions(-DCOMPILEDWITHC11)
include_directories(${PROJECT_SOURCE_DIR}/lib-wintoast/)add_library(wintoastlib STATIC 
${PROJECT_SOURCE_DIR}/lib-wintoast/wintoastlib.cpp  
${PROJECT_SOURCE_DIR}/lib-wintoast/wintoastlib.h)add_library(my_wintoastlib STATIC 
${PROJECT_SOURCE_DIR}/sjh/my-wintoast/mywintoast.cpp  
${PROJECT_SOURCE_DIR}/sjh/my-wintoast/mywintoast.h)add_executable(main main.cpp)
add_executable(test test.cpp)
add_executable(test2 test2.cpp)target_link_libraries(main ${PROJECT_SOURCE_DIR}/lib-wintoast/wintoastlib.lib)
target_link_libraries(test ${PROJECT_SOURCE_DIR}/lib-wintoast/wintoastlib.lib)
target_link_libraries(test2 ${PROJECT_SOURCE_DIR}/lib-wintoast/wintoastlib.lib${PROJECT_SOURCE_DIR}/sjh/my-wintoast/my_wintoastlib.lib)

后续将会填充其他函数。写了六千七百字今晚不想写了。

我终于平庸 终于化成了

路过你头顶的风

–《你头顶的风》

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了