type
status
date
slug
summary
tags
category
icon
password
常用变量PROJECT_NAMEPROJECT_SOURCE_DIRCMAKE_CURRENT_SOURCE_DIRPROJECT_BIN_DIRCMAKE_C_FLAGSCMAEK_CXX_FLAGSCMAKE_INSTALL_PREFIXEXECUTABLE_OUTPUT_PATHLIBRARY_OUT_PATH常用指令指定CMake的最小版本定义工程名字,指定工程语言定义变量添加头文件设置编译类型指定编译包含的源文件查找指定的库文件查找指定的包设置 target 需要链接的库指定链接动态库或静态库指定全路径指定链接多个库打印信息包含其它cmake文件换个地方保存目标二进制向C/C++添加-D定义add_test和enable_testing指令AUX_SOURCE_DIRECTORY其他内容find_package详解1.前言2. find_package解析过程3. find_package使用方式References:
CMakeLists.txt文件中的指令不区分大小写
常用变量
PROJECT_NAME
- 项目名称,用函数project(demo)指定的项目名称,这里变量的值为demo
PROJECT_SOURCE_DIR
- 工程根目录,他与
CMAKE_SOURCE_DIR
、<projectname>_SOURCE_DIR
指代的内容是一样的
CMAKE_CURRENT_SOURCE_DIR
- 指的是当前CMakeLists.txt所在的路径
PROJECT_BIN_DIR
- 执行cmake命令的目录,如果mkdir build, cd build, cmake..的话,该变量的值为build目录。
PROJECT_BIN_DIR
、CMAKE_BINARY_DIR
、<projectname>_BINARY_DIR
这三个变量指代的内容是一样的
CMAKE_C_FLAGS
- 设置C编译选项
CMAEK_CXX_FLAGS
- 设置C++编译选项
CMAKE_INSTALL_PREFIX
- 制定install指令安装文件的根目录
EXECUTABLE_OUTPUT_PATH
- 生成目标可执行文件的根目录,在哪生成可执行文件就在哪用
LIBRARY_OUT_PATH
- 库文件输出位置,在哪生成库文件就在哪用
常用指令
指定CMake的最小版本
定义工程名字,指定工程语言
- 支持语言的列表可以省略,默认情况下支持所有语言。
- 隐式定义了两个变量
PROJECT_BINARY_DIR
(执行cmake的目录)和PROJECT_SOURCE_DIR
(工程的根目录)
定义变量
set(<variable> <value> [PARENT_SCOPE])
<variable>
变量名称,只能有一个
<value>
变量值,可以有多个
PARENT_SCOPE
(父作用域):作用域
添加头文件
include_directories(xxx)
- 用于在调用的函数里面写“include <xxx>
设置编译类型
add_library
默认生成是静态库,最终会编入到可执行文件中
- 通过以上命令生成文件名字,在linux下是demo、libcommon.a、libcommon.so
指定编译包含的源文件
查找指定的库文件
- 查找到指定的预编译库,并将它的路径存储在变量中。
- 默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可。
查找指定的包
- version:指定查找库的版本号。
- EXACT:要求该版本号必须精确匹配。
- QUIET:禁掉没有找到时的警告信息。如果没找到则忽略这一问题,继续执行。
- REQUIRED选项表示如果包没有找到的话,CMake的过程会终止,并输出警告信息。
如果CMake自动找不到路径,我们需要手动设置路径,如 先 set(OpenCV_INCLUDE_DIRS “home/hwh/Opencv3.1/build”) 设置路径,然后find_package(OpenCV 3.1 REQUIRED)
设置 target 需要链接的库
指定链接动态库或静态库
指定全路径
指定链接多个库
打印信息
包含其它cmake文件
换个地方保存目标二进制
- 可以通过
SET
指令重新定义EXECUTABLE_OUTPUT_PATH
和LIBRARY_OUTPUT_PATH
变量来指定最终的目标二进制的位置
在哪里
ADD_EXECUTABLE
或 ADD_LIBRARY
,如果需要改变目标存放路径,就在哪里加入上述的定义向C/C++添加-D定义
如果你的代码中定义了
#ifdef ENABLE_DEBUG #endif
,这个代码块就会生效add_test
和enable_testing
指令
add_test
和enable_testing
指令- ENABLE_TESTING 指令用来控制 Makefile 是否构建 test 目标,涉及工程所有目录。语法很简单,没有任何参数,ENABLE_TESTING(),一般情况这个指令放在工程的主CMakeLists.txt 中.
- ADD_TEST(testname Exename arg1 arg2 ...)
- testname 是自定义的 test 名称
- Exename 可以是构建的目标文件也可以是外部脚本等
- 如果没有在同一个 CMakeLists.txt 中打开ENABLE_TESTING()指令,任何 ADD_TEST 都是无效的
AUX_SOURCE_DIRECTORY
AUX_SOURCE_DIRECTORY
- AUX_SOURCE_DIRECTORY(dir VARIABLE)
- 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
其他内容
- 需要看到 make 构建的详细过程,可以使用
make VERBOSE=1
或者VERBOSE=1 make
命令来进行构建。
- 通过message指令输出文本的时候,
FETAL_ERROR
会立即停止所有cmake过程。
- 变量通过
${}
方式提取值,但是在IF控制语句中是直接使用变量名。
- 指令是大写小无关的,参数是大小写相关的
SET(SRC_LIST main.c)
也可以写成SET(SRC_LIST “main.c”)
- 执行
make clean
即可对构建结果进行清理,不会清除makefile
- cmake 强烈推荐的是外部构建(out-of-source build)
- 通过
ldd ExeFileName
查看可执行文件的链接情况
- 在 Windows 下,系统会根据链接库目录,搜索xxx.lib 文件,Linux 下会搜索 xxx.so 或者 xxx.a 文件,如果都存在会优先链接动态库(so 后缀)
find_package详解
- 用途:在安装完某个功能包以后,需要对其调用,通过
include_directory()
或者target_include_directories()
来手动指定头文件和源文件是非常繁琐的,一种比较方便的方式是通过find_package(PkgName …)
来加载某个包,会自动将头文件、源文件赋值给PkgName_include_dirs
和PkgName_LIBS
,省时省力。
1.前言
先看以下寻找并包含 Eigen3 的
CMakeLists.txt
示例,通过find_package
命令寻找到了Eigen3库,并获得了其中的导入目标列表。2. find_package解析过程
Module 模式
这种模式下,
find_package
需要解析 Findxxx.cmake
文件,这也是 find_package
默认工作的模式Config 模式
这种模式下,
find_package
需要解析 xxxConfig.cmake
文件或者 xxx-config.cmake
文件。实际上只有 Findxxx.cmake
文件无法找到,即 Module 模式执行不成功,才会进入 Config 模式。2.1 Module 模式
Module 模式下
find_package
的参数为:参数名称 | 可选性 | 名称 | 备注 |
package | 必填 | 需要查找的包名 | 注意大小写 |
VERSION | 可选 | 指定版本,如果指定就必须检查找到的包的版本是否和 VERSION 兼容 | ㅤ |
EXACT | 可选 | 如果指定该参数,则表示需要寻找必须完全匹配的版本而不是兼容版本 | 配合 VERSION 使用 |
REQUIRED | 可选 | 表示一定要找到包,找不到的话就立即停掉整个 CMake 解析过程 | ㅤ |
QUIET | 可选 | 表示如果查找失败,不会在屏幕进行输出 | 不得与 REQUIRED 搭配 |
MODULE | 可选 | 前面提到说 “ Module 模式执行失败,才会进入 Config 模式”,但是假如加入了 MODULE 选项,那么就只在 Module 模式查找,如果 Module 模式下查找失败并不切换到 Config 模式查找。 | ㅤ |
COMPONENTS | 可选 | 表示查找的包中必须要找到的组件(components),如果有任何一个找不到就算失败,类似于 REQUIRED ,导致CMake 停止执行。 | ㅤ |
- Module 模式下需要查找到名为
Find<PackageName>.cmake
的配置文件。该文件的查找过程只涉及到两个路径:CMAKE_MODULE_PATH
和 CMake 安装路径下的 Modules 目录。即,搜索路径依次为:
- 先在
CMAKE_MODULE_PATH
变量对应的路径中查找。如果路径为空,或者路径中查找失败,则在 CMake 安装目录(即CMAKE_ROOT
变量)下的 Modules 目录中查找。这个目录通常为/usr/share/cmake-x.xx/Modules
。这两个变量可以在CMakeLists.txt
文件中打印查看具体内容。
- 其中
CMAKE_MODULE_PATH
默认为空,可以利用set
命令对该变量进行设置。
- 在安装 CMake 时,CMake 为我们提供了很多开发库的
FindXXX.cmake
模块文件,这些文件都定义在CMAKE_ROOT
指代路径的文件夹里面。可以在终端通过键入以下命令进行查询
2.2 Config 模式
Config 模式下
find_package
的完整命令参数不必全部了解,相比于 Module 模式,Config 模式的参数更多,也更复杂,但实际在使用过程中我们并不会用到所有参数,大部分参数都是可选的,我们只需要掌握基本的参数用法即可。其中具体查找库并给XXX_INCLUDE_DIRS
和XXX_LIBS
两个变量赋值的操作由XXXConfig.cmake
模块完成。CMake 默认采取 Module 模式,如果 Module 模式未找到库,才会采取 Config 模式。总之,Config 模式是一个备选策略。通常,库安装时会拷贝一份
XXXConfig.cmake
到系统目录中,因此在没有显式指定搜索路径时也可以顺利找到。3. find_package使用方式
在填写功能包名字的时候,要准确,区分大小写,否则不能找到功能包名,CMake将会以写入的功能包名称在系统路径下查找相应的包配置文件。
这一约定是为了避免不同的功能包之间出现命名冲突。
对于如何确定功能包的具体名称时,可以通过查看官方文档或查看PkgNameConfig.cmake文件来确定,PkgName就是find_package需要写入的包名。
PkgNameConfig.cmake文件在Ubuntu 20.04系统上的存放位置通常在以下几个路径中:
- 全局安装路径
- /usr/local/lib/cmake/Xxx/
- /usr/local/share/cmake-x.x/Modules/
- 安装在系统目录
- /usr/lib/cmake/Xxx/
- /usr/share/cmake-x.x/Modules/
References:
- Author:Lianzhao
- URL:https://lianzhao.vercel.app//article/CMakeListsIntroduction
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!