CMake
语法特性
- 变量使用
${}
方式取值,但是在IF
控制语句中是直接使用变量名。 - 指令(参数 1 参数 2...) ,参数使用括弧括起,参数之间使用空格或分号分开。
- 指令是大小写无关的,参数和变量是大小写相关的。
- 无行结束符,注释使用
#
。
编译工程
设置编译规则
- 包含源文件的子文件夹包含 CMakeLists.txt 文件,主目录的 CMakeLists.txt 通过
add_subdirectory
添加子目录即可。 - 包含源文件的子文件夹未包含 CMakeLists.txt 文件,子目录编译规则体现在主目录的 CMakeLists.txt 中。
构建方式
- 内部构建(in-source build)会在同级目录下产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件放在一起会显得杂乱无章,不推荐使用。
- 外部构建(out-of-source build)会将编译输出文件与源文件放到不同目录中,推荐使用。
常用变量
路径
PROJECT_NAME
: 返回通过 PROJECT 指令定义的项目名称CMAKE_BINARY_DIR
,PROJECT_BINARY_DIR
,<projectname>_BINARY_DIR
: 如果是 in-source build,指的就是工程顶层目录,如果是 out-of-source build编译,指的是工程编译发生的目录CMAKE_SOURCE_DIR
,PROJECT_SOURCE_DIR
,<projectname>_SOURCE_DIR
: 不论采用何种编译方式,都是工程顶层目录CMAKE_CURRENT_SOURCE_DIR
: 指的是当前处理的 CMakeLists.txt 所在的路径CMAKE_CURRRENT_BINARY_DIR
: 如果是 in-source build,与CMAKE_CURRENT_SOURCE_DIR
一致,如果是 out-of-source build,指的是 target 编译目录,add_subdirectory
可以修改这个变量的值,设置EXECUTABLE_OUTPUT_PATH
并不会对这个变量造成影响CMAKE_CURRENT_LIST_FILE
:输出调用这个变量的 CMakeLists.txt 的完整路径CMAKE_CURRENT_LIST_LINE
: 输出这个变量所在的行EXECUTABLE_OUTPUT_PATH
: 可执行文件输出的存放路径LIBRARY_OUTPUT_PATH
: 库文件输出的存放路径CMAKE_INSTALL_PREFIX
: 目标文件的安装目录,默认值为/usr/local/bin
CMAKE_MODULE_PATH
:自定义的 CMake 模块的路径CMAKE_INCLUDE_CURRENT_DIR
: 自动添加CMAKE_CURRENT_SOURCE_DIR
和CMAKE_CURRRENT_BINARY_DIR
到当前的 CMakeLists.txt 中处理CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
: 将工程提供的头文件目录始终置于系统文件目录之前
系統信息
CMAKE_MAJOR_VERSION
: CMake 的主版本号,例如 2.3.6 中的 2CMAKE_MINOR_VERSION
:CMake 的次版本号,例如 2.3.6 中的 3CMAKE_PATCH_VERSION
:CMake 的补丁等级,例如 2.3.6 中的 6CMAKE_SYSTEM_NAME
: 系统名称,包含版本号,例如 Linux-2.6.28CMAKE_SYSTEM_NAME
: 系统名称,不包含版本号,例如 LinuxCMAKE_SYSTEM_VERSION
: 系统版本号,例如 2.6.28CMAKE_SYSTEM_PROCESSOR
: 处理器名称,例如 I386UNIX
: 在所有的类 UNIX 平台为 TRUE,包括 MacOS 和 CygwinWIN32
: 在所有的 win32 平台为 TRUE,包括 Cygwin
开关选项
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
: 开关选项,用来控制 if else 的书写方式BUILD_SHARED_LIBS
: 开关选项,默认为静态库
编译选项
CMAKE_BUILD_TYPE
: 编译类型,Debug, ReleaseCMAKE_C_COMPILER
: 指定 C 编译器CMAKE_CXX_COMPILER
: 指定 C++ 编译器CMAKE_C_FLAGS
: 设置 C 编译选项,也可以通过add_definitions()
添加CMAKE_CXX_FLAGS
: 设置 C++ 编译选项,也可以通过add_definitions()
添加
环境变量
$ENV{NAME}
:调用系统的环境变量。SET(ENV{VAR} VALUE)
:设置环境变量。
重要指令
cmake_minimum_required
指定 CMake 的最小版本要求。
语法:
示例:
project
定义工程名称,并可指定工程支持的语言。支持的语言列表是可以忽略的,默认情况表示支持所有语言。
语法:
隐含定义了两个变量 <projectname>_BINARY_DIR
和 <projectname>_SOURCE_DIR
示例:
set
显式的定义变量。
语法:
示例:
message
向终端输出用户定义的信息。
语法:
SEND_ERROR
:产生错误,生成过程被跳过SATUS
:输出前缀为-
的信息FATAL_ERROR
:立即终止所有 cmake 过程
示例:
add_compile_options
添加编译参数。
语法:
示例:
include_directories
向工程添加多个特定的头文件搜索路径。
语法:
示例:
add_library
生成库文件。
语法:
SHARED
:动态库STATIC
:静态库MODULE
:在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待EXCLUDE_FROM_ALL
:这个库不会被默认构建,除非有其他的组件依赖或者手工构建
示例:
set_target_properties
设置输出的名称,对于动态库,可以用于指定动态库的版本和 API 版本。
语法:
获取属性可以使用:
示例:
link_directories
向工程添加多个特定的库文件搜索路径。
语法:
示例:
target_link_libraries
为 target 添加需要链接的共享库。
语法:
示例:
install
安装文件
语法:
安装目标文件
ARCHIVE
: 静态库文件LIBRARY
: 动态库文件RUNTIME
: 可执行文件DESTINATION
: 定义安装路径,如果是绝对路径则覆盖CMAKE_INSTALL_PERFIX
,否则是指相对CMAKE_INSTALL_PERFIX
的相对路径
示例:
上面的例子将:
- 二进制文件 myrun 安装到
${CMAKE_INSTALL_PERFIX}/bin
目录 - 二进制文件 libmylib 安装到
${CMAKE_INSTALL_PERFIX}/lib
目录 - 二进制文件 liblibstatic 安装到
${CMAKE_INSTALL_PERFIX}/libstatic
目录
安装普通文件
可以指定权限,如果不指定,则默认是 644 权限。
目录安装
add_executable
增加可执行文件。
语法:
示例:
add_subdirectory
向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置。
语法:
示例:
aux_source_directory
发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表。
语法:
示例:
add_definitions
向 C/C++ 编译器添加 -D
定义。
语法:
示例:
使用 cmake
指定时也可以定义宏:
add_dependencies
定义 target 依赖的其他 target,确保在编译本 target 之前,其他的 target 已经被构建。
语法:
示例:
add_test 与 enable_testing
enable_testing()
用来控制 Makefile 是否构建 test 目标,一般放在工程的主 CMakeLists.txt 中。
语法:
testname
是自定义的 test 名称,Exename
可以是构建的目标文件也可以是外部脚本等。如果没有在同一个 CMakeLists.txt 中打开 enable_testing()
,任何 add_test
都是无效的。
示例:
生成 Makefile 后,就可以运行 make test 来执行测试。
file
文件操作指令。
语法:
include
载入 CMakeLists.txt 文件或者预定义的 cmake 模块。载入的内容在处理到 include
时直接执行。如果指定的是一个模块,将会在 CMAKE_MODULE_PATH
中搜索。
语法:
OPTIONAL
:文件不存在时也不会产生错误。
find
- find_package 的
REQUIRED
指定这个共享库是不是工程必须的。
控制指令
if
语法:
- 凡是出现
if
的地方一定要有对应的endif
- 出现
elseif
的地方,endif
是可选的 - 如果
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
则else()
和endif()
的expression
可以省略
示例:
while
语法:
其真假判断条件可以参考 if
指令。
for_each
for_each
有三种使用形式:
列表
语法:
示例:
范围
语法:
示例:
范围和步进
语法:
以 start
开始到 stop
结束,以 step
为步进。
示例:
模块的使用和自定义模块
使用 FindCURL 模块
方法一:
方法二:
自定义模块
定义 cmake/FindHELLO.cmake
模块
使用:
主工程中应该加入:
__EOF__

本文链接:https://www.cnblogs.com/xiaojianliu/p/14898640.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App