CMake详细使用

2023-10-29

1、CMake简介

CMake是一个用于管理源代码的跨平台构建工具

可以方便地根据目标平台和编译工具产生对应的编译文件

主要用于C/C++语言的构建,但是也可以用于其它编程语言的源代码。

如同使用make命令工具解析Makefile文件一样

cmake命令工具依赖于一个CMakeLists.txt的文件

该文件定义了代码的编译规则和目标等信息。

官方文档说明:https://cmake.org/cmake/help/v3.17/index.html

2、CMake 注释

  1. 单行注释 #

# 单行注释
  1. 多行注释 #[[ ]]

#[[ 多行注释
    多行注释
    多行注释 ]]

3、CMake 变量

CMake 中所有变量都是 String 类型

  1. set() 声明变量

# set(变量名 变量值)
set(name 小明)

  1. unset() 移除一个变量

# unset(变量名)
unset(name)

  1. ${} 引用变量

# ${变量名}
${name}

  1. message() 打印变量

# message("name = ${变量名}")
message("name = ${name}")

4、CMake列表

列表也是字符串,可以把列表看做是一个特殊的变量,这个变量有多个值。

  1. 列表格式 (设置列表有两种方式)

# set(列表名 值1 值2 ... 值n)
set(list_age 1 2 ... n)

# set(列表名 "值1; 值2; 值3")
set(list_age "1;2;3")

5、CMake流程控制

  1. 操作符

优先级:() > 一元 > 二元 > 逻辑

类型

名称

一元

EXIST、COMMAND、DEFINED

二元

EQUAL、LESS、LESS_EQUAL、GREATER、GREATER_EQUAL、

STREQUAL、STRLESS、STRLESS_EQUAL、STRGREATER、

STRGREATER_EQUAL、VERSION_EQUAL、VERSION_LESS、

VERSION_LESS_EQUAL、VERSION_GREATER、

VERSION_GREATER_EQUAL、MATCHES

  1. 布尔常量值

类型

true

1、ON、YES、TRUE、Y、非0的值

false

0、OFF、NO、FALSE、N、IGNORE、NOTFOUND

空字符串、一-NOTFOUND结尾的字符串

  1. 条件判断 if()

语法:

if(表达式)
    ....
elseif(表达式)
    ...
else(表达式)
    ...
endif()            
  • elseif和else部分是可选的

  • elseif部分可以有多个

  • 缩进和空格对语句的解析没有影响

  1. 循环命令 while()

语法:

while(表达式)
    ...
endwhile()
  • break() 可以跳出整个循环

  • continue() 可以跳出当前循环

  1. 循环遍历 foreach()

循环遍历分为两种:

  • 遍历RANGE:

#循环范围从start到stop,循环增量为step
foreach(循环变量 RANGE start stop step)
    ...
endforeach(循环变量)
  • 遍历LISTS:

foreach(循环遍历 IN LISTS 列表)
    ...
endforeach(循环变量)
  • break() 可以跳出整个循环

  • continue() 可以跳出当前循环

6、CMake自定义函数

语法:

function(<name> arg1 arg2 arg3)
    ...
endfunction(<name>)

调用:

name(arg1 arg2 arg3)

7、CMake自定义宏命令

语法:

macro(<name> arg1 arg2 arg3)
    ...
endmacro(<name>)

调用:

name(arg1 arg2 arg3)

8、CMake常用变量

CMake预设了一些常用变量

这些变量通常会在编写CMakeLists.txt文件时使用到:

变量值

作用

CMAKE_MAJOR_VERSION

cmake 主版本号

CMAKE_MINOR_VERSION

cmake 次版本号

CMAKE_C_FLAGS

设置 C 编译选项

CMAKE_CXX_FLAGS

设置 C++ 编译选项

PROJECT_SOURCE_DIR

工程的根目录

PROJECT_BINARY_DIR

运行 cmake 命令的目录

CMAKE_CURRENT_SOURCE_DIR

当前CMakeLists.txt 所在路径

CMAKE_CURRENT_BINARY_DIR

目标文件编译目录

EXECUTABLE_OUTPUT_PATH

重新定义目标二进制可执行文件的存放位置

LIBRARY_OUTPUT_PATH

重新定义目标链接库文件的存放位置

UNIX

如果为真,表示为UNIX-like的系统,包括AppleOSX和CygWin

WIN32

如果为真,表示为 Windows 系统,包括 CygWin

APPLE

如果为真,表示为 Apple 系统

CMAKE_SIZEOF_VOID_P

表示void*的大小(例如为4或者8),可以使用其来判断当前构建为32位还是64位

CMAKE_CURRENT_LIST_DIR

表示正在处理的CMakeLists.txt文件所在目录的绝对路径

CMAKE_ARCHIVE_OUTPUT_DIRECTORY

用于设置ARCHIVE目标的输出路径

CMAKE_LIBRARY_OUTPUT_DIRECTORY

用于设置LIBRARY目标的输出路径

CMAKE_RUNTIME_OUTPUT_DIRECTORY

用于设置RUNTIME目标的输出路径

9、CMakeLists.txt 常用语法

  1. project 命令:

# 命令语法:project(<projectname> [languageName1 languageName2 ...])
# 设置项目名称 (工程名称为 projectName)
project(projectName)
  1. cmake_minimum_required 命令:

# cmake_minimum_requried(VERSION major[.minor[.patch)
# 设置 CMake 最低版本 (最低版本 3.14)
cmake_minimum_required(VERSION 3.14.0)
  1. aux_source_directory命令:

# aux_source_directory(<dir> <variable>)
# 用于包含源文件目录,dir目录下的所有源文件的名字保存在变量variable中
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src DIR_SRCS)
  1. add_executable命令:

# add_executable(<name> [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL] source1 source2 … sourceN)
# 用于指定从一组源文件source1 source2 ... sourceN 编译出一个可执行文件且命名为name
add_executable(Main $(DIR_SRCS))
  1. add_library命令:

# add_library([STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1source2 … sourceN)
# 用于指定从一组源文件 source1 source2 ... sourceN编译出一个库文件且命名为name
add_library(Lib $(DIR_SRCS))
  1. add_dependencies命令:

# add_dependencies(target-name depend-target1 depend-target2 …)
# 用于指定某个目标(可执行文件或者库文件)依赖于其他的目标。
# 这里的目标必须是add_executable、add_library、add_custom_target命令创建的目标
  1. add_subdirectory命令:

# add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
# 用于添加一个需要进行构建的子目录
add_subdirectory(Lib)
  1. target_link_libraries命令:

# target_link_libraries(<target> [item1 [item2 […]]][[debug|optimized|general] ] …)
# 用于指定target需要链接item1 item2 ...。这里target必须已经被创建,链接的item可以是已经存在的target(依赖关系会自动添加)
target_link_libraries(Main Lib)
  1. set命令:

# 用于设定变量 variable 的值为 value。如果指定了 CACHE 变量将被放入 Cache(缓存)中。
# set(<variable> <value> [[CACHE <type><docstring> [FORCE]] | PARENT_SCOPE])
set(ProjectName Main)
  1. unset命令:

# unset(<variable> [CACHE])
# 用于移除变量 variable。如果指定了 CACHE 变量将被从 Cache 中移除。
unset(VAR CACHE)
  1. message命令:

# message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] “message todisplay”…)
# 用于输出信息
message(“Hello World”)
  1. include_directories命令:

# include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)
# 用于设定目录,这些设定的目录将被编译器用来查找 include 文件
include_directories(${PROJECT_SOURCE_DIR}/lib)
  1. find_path命令:

# find_path(<VAR> name1 [path1 path2 …])
# 用于查找包含文件name1的路径,如果找到则将路径保存在VAR中(此路径为一个绝对路径),如果没有找到则结果为<VAR>-NOTFOUND.默认情况下,VAR会被保存在Cache中,这时候我们需要清除VAR才可以进行下一次查询(使用unset命令)
find_path(LUA_INCLUDE_PATH lua.h ${LUA_INCLUDE_FIND_PATH})
if(NOT LUA_INCLUDE_PATH)
     message(SEND_ERROR "Header file lua.h not found")
endif()
  1. find_library命令:

# find_library(<VAR> name1 [path1 path2 …])
# 用于查找库文件 name1 的路径,如果找到则将路径保存在 VAR 中(此路径为一个绝对路径),
# 如果没有找到则结果为 <VAR>-NOTFOUND。
# 一个类似的命令 link_directories 已经不太建议使用了
  1. add_definitions命令:

# add_definitions(-DFOO -DBAR …)
# 用于添加编译器命令行标志(选项),通常的情况下我们使用其来添加预处理器定义
add_definitions(-D_UNICODE -DUNICODE)
  1. file命令:

# 此命令提供了丰富的文件和目录的相关操作(这里仅说一下比较常用的)
使用范例:
# 目录的遍历
# GLOB 用于产生一个文件(目录)路径列表并保存在variable 中
# 文件路径列表中的每个文件的文件名都能匹配globbing expressions(非正则表达式,但是类似)
# 如果指定了 RELATIVE 路径,那么返回的文件路径列表中的路径为相对于 RELATIVE 的路径
file(GLOB variable [RELATIVE path][globbing expressions]...)
 
# 获取当前目录下的所有的文件(目录)的路径并保存到 ALL_FILE_PATH 变量中
file(GLOB ALL_FILE_PATH ./*)
# 获取当前目录下的 .h 文件的文件名并保存到ALL_H_FILE 变量中
# 这里的变量CMAKE_CURRENT_LIST_DIR 表示正在处理的 CMakeLists.txt 文件的所在的目录的绝对路径(2.8.3 以及以后版本才支持)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake详细使用 的相关文章

随机推荐

  • python对指定字符串逆序的6种方法

    对于一个给定的字符串 逆序输出 这个任务对于python来说是一种很简单的操作 毕竟强大的列表和字符串处理的一些列函数足以应付这些问题 了 今天总结了一下python中对于字符串的逆序输出的几种常用的方法 方法一 直接使用字符串切片功能逆转
  • cuda学习笔记之异步并行执行

    异步函数使得主机端与设备端并行执行 控制在设备还没有完成前就被返回给主机线程 包括 kernel启动 以Async为后缀的内存拷贝函数 device到device内存拷贝函数 存储器初始化函数 比如cudaMemset cudaMemset
  • linux离线安装llvm,Debian/Ubuntu Linux 下安装LLVM/Clang 编译器

    第一步 首先编辑 etc apt sources list 加入以下源 Debian平台 deb http llvm org apt wheezy llvm toolchain wheezy main deb src http llvm o
  • Qt将文件保存到指定目录下(另存为的功能)

    因为Qt才开始入门 对文件的操作还不是很熟练 经过一段时间查找终于找出一些适用于入门的代码 QDir d d mkpath D 123 file new QFile D 123 tmp file gt open QFile WriteOnl
  • MySQL索引实现原理分析

    目前大部分数据库系统及文件系统都采用B Tree B树 或其变种B Tree B 树 作为索引结构 B Tree是数据库系统实现索引的首选数据结构 在 MySQL 中 索引属于存储引擎级别的概念 不同存储引擎对索引的实现方式是不同的 本文主
  • docker安装Apollo,并用java连接测试

    What is Apollo 背景 随着程序功能的日益复杂 程序的配置日益增多 各种功能的开关 参数的配置 服务器的地址 对程序配置的期望值也越来越高 配置修改后实时生效 灰度发布 分环境 分集群管理配置 完善的权限 审核机制 在这样的大环
  • C语言-文件

    C语言 文件 一 为什么使用文件 二 文件的打开与关闭 1 fopen 1 r w a 2 rb wb ab 3 r w a 4 rb wb ab 2 fclose 三 文件顺序读写函数 1 fgetc fputc 2 fgets fput
  • Ubuntu18.04 python 开发usb通信

    一 安装环境 1 安装pip sudo python3 get pip py 或 sudo i apt update apt install python3 pip 确定pip是否安装成功 xxx desktop pip3 version
  • 【Transformers】第 3 章:自动编码语言模型

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 瑞吉外卖项目——删除和批量删除套餐功能

    需求分析 用户点击删除按钮 可以删除对应的套餐 也可以通过复选框选择多个套餐 点击批量删除 一次性删除多个套餐 注意 对于状态在售卖中的套餐不能删除 需要先停售 之后才能删除 代码开发 前后端发交互 前端携带id发送请求 请求服务端 服务端
  • 牛客网剑指offer java 全部题解

    经过数月的努力 终于更完了牛客网的66道剑指offer 以下的顺序和大家在牛客网的顺序是一样的 排序也花了不少时间 希望对大家找工作 提高算法能力能起到些许帮助 每天一道剑指offer 二维数组中的查找 https mp weixin qq
  • Redis主从连接失败 connected_slaves:0

    进行主从连接配置时 主服务器使用info replication查到的 connected slaves数一直是0 原因是主服务器设置了密码 找到从服务器的配置文件redis conf 在配置文件中找到 masterauth
  • python如何做敏感度分析,使用SALib工具箱从测量数据进行Python敏感性分析

    I would like to understand how to use the SALib python toolbox to perform a Sobol sensitivity analysis to study paramete
  • IDEA 代码提交前流程及提交日志模板化

    前言 在开发大型项目时 通常都是由团队来进行开发 此时 每个人有每个人的代码编写风格和提交习惯 如果放任自由发挥 那么代码质量和代码提交日志就难免风格各异 导致项目代码质量难以保持统一 针对这一问题 往往公司在以项目组进行开发时 在进入正式
  • [转载]Python正则表达式匹配反斜杠'\'问题

    在学习Python正则式的过程中 有一个问题一直困扰我 如何去匹配一个反斜杠 即 一 引入 在学习了Python特殊字符和原始字符串之后 我觉得答案应该是这样的 1 普通字符串 2 原始字符串 r 但事实上在提取诸如 3 8 反斜杠之前的数
  • 高速PCB电路板的信号完整性设计

    目录 高速PCB电路板的信号完整性设计 1信号完整性基本理论 1 1 信号完整性定义 1 2影响信号完整性的主要因素 2高速数据采集系统 3 信号完整性设计 3 1电路板叠层设计 3 2电路板布局设计 3 3电路板布线设计 一 信号完整性是
  • 编译语言的编译和脚本语言的解释

    编译语言的编译和脚本语言的解释 编译语言和脚本语言 这个博主看了几篇帖子 觉得Jonny工作室的这篇文章解释的最简单明了 联想之间之前写的程序 大胆给一点自己的看法 如有不对还望指正 编译语言 脚本语言 c c python 题目出现编译语
  • 智能运维 VS 传统运维|AIOps服务管理解决方案全面梳理

    云智慧 AIOps 社区是由云智慧发起 针对运维业务场景 提供算法 算力 数据集整体的服务体系及智能运维业务场景的解决方案交流社区 该社区致力于传播 AIOps 技术 旨在与各行业客户 用户 研究者和开发者们共同解决智能运维行业技术难题 推
  • java开发Demo~微信扫码支付,java开发示例

    开发所需工具类 以上工具类以上传到我的资源 下载地址 http download csdn net download han xiaoxue 10184832 开发所需jar 具体的代码不贴了 说明下PayConfigUtil中的参数 AP
  • CMake详细使用

    1 CMake简介 CMake是一个用于管理源代码的跨平台构建工具 可以方便地根据目标平台和编译工具产生对应的编译文件 主要用于C C 语言的构建 但是也可以用于其它编程语言的源代码 如同使用make命令工具解析Makefile文件一样 c