CMake 教程
CMake 教程
晨茗一、CMake 常用变量
1. CMAKE_BINARY_DIR
和PROJECT_BINARY_DIR <projectname>_BINARY_DIR一样,这三个变量指代的内容是一致的,如果是 in-source 编译,指的就是工程顶层目录,如果是 out-of-source 编译,则指的是工程编译发生的目录。PROJECT_BINARY_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
2. CMAKE_SOURCE_DIR
和 PROJECT_SOURCE_DIR <projectname>_SOURCE_DIR 三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。也就是在 in source 编译时,他跟 CMAKE_BINARY_DIR 等变量一致。PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
3. CMAKE_CURRENT_SOURCE_DIR
指的是当前处理的 CMakeLists.txt 所在的路径,比如上面我们提到的 src 子目录。
4. CMAKE_CURRRENT_BINARY_DIR
如果是 in-source 编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是 out-of-source 编译,他指的是 target 编译目录。使用我们上面提到的 ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对这个变量造成影响,它仅仅修改了最终目标文件存放的路径。
5.CMAKE_CURRENT_LIST_FILE
输出调用这个变量的 CMakeLists.txt 的完整路径
6. CMAKE_CURRENT_LIST_LINE
输出这个变量所在的行
7. CMAKE_MODULE_PATH
这个变量用来定义自己的 cmake 模块所在的路径。如果你的工程比较复杂,有可能会自己编写一些 cmake 模块,这些 cmake 模块是随你的工程发布的,为了让 cmake 在处理 CMakeLists.txt 时找到这些模块,你需要通过 SET 指令,将自己的 cmake 模块路径设置一下。
比如 SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) 这时候你就可以通过 INCLUDE 指令来调用自己的模块了,类似 add_subdirectory。
8. EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
分别用来重新定义最终结果的存放目录,前面我们已经提到了这两个变量。
9. PROJECT_NAME
返回通过 PROJECT 指令定义的项目名称。
二、CMake 环境变量
使用 $ENV{NAME} 指令就可以调用系统的环境变量了。
比如:MESSAGE(STATUS “HOME dir: $ENV{HOME}”)
设置环境变量的方式是: SET(ENV{变量名}值)
三、基本指令
1. ADD_DEFINITIONS
向 C/C++编译器添加 -D 定义,比如:ADD_DEFINITIONS(-DENABLE_DEBUG -DABC),参数之间用空格分割。如果你的代码中定义了#ifdef ENABLE_DEBUG #endif,这个代码块就会生效。
如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS 变量和 CMAKE_CXX_FLAGS 变量设置。
2. ADD_DEPENDENCIES
定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...)
让一个顶层目标依赖于其他的顶层目标。一个顶层目标是由命令 ADD_EXECUTABLE,ADD_LIBRARY,或者 ADD_CUSTOM_TARGET 产生的目标。为这些命令的输出引入依赖性可以保证某个目标在其他的目标之前被构建。
3. ADD_EXECUTABLE、ADD_LIBRARY、ADD_SUBDIRECTORY
ADD_EXECUTABLE(可执行文件名 生成该可执行文件的源文件)
源文件需要编译出的可执行文件名。
例:ADD_EXECUTABLE(hello ${SRC_LIST})
ADD_LIBRARY(name [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
name 属性必须全局唯一,生成的 library 名会根据 STATIC 或 SHARED 成为 name.a 或 name.lib。
这里的 STATIC 和 SHARED 可不设置,通过全局的 BUILD_SHARED_LIBS 的 FALSE 或 TRUE 来指定。
例:ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
ADD_SUBDIRECTORY(src_dir [binary_dir] [EXCLUDE_FROM_ALL])
向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制的存放位置EXCLUDE_FROM_ALL含义:将这个目录从编译过程中排除
4. INCLUDE
include(${CMAKE_SOURCE_DIR}/vendor/CMakeLists.txt)
引入一个新的CMake项目,与**ADD_SUBDIRECTORY**的区别在于其不会创建一个新的变量域。
四、第三方依赖
1. 使用 ExternalProject
[!note]+ 参考链接
https://www.cxybb.com/article/wzj_110/116722467
基础配置
1 | # Dependencies' .cmake |


下载
- URL

- Git

将依赖的静态库打包进产出的静态库中
1 | add_custom_target(combined ALL |
2. 使用 PKG
其实质上是通过检测系统中的 pkg-config 是否存在指定的 .pc 文件,来寻找软件的。
1 | include(FindPkgConfig) |
五、CPack
1 | set(CMAKE_INSTALL_PREFIX "/opt/nat_experiment") |


%20%E6%9C%8D%E5%8A%A1.jpeg)

