type
status
date
slug
summary
tags
category
icon
password
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_DIRCMAKE_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_testenable_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(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_dirsPkgName_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_DIRSXXX_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:

 
基本概念和符号ROS中的约定