当前位置: 首页 > news >正文

CMake详细使用

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 以及以后版本才支持)
http://www.lryc.cn/news/229.html

相关文章:

  • 【数据结构与算法】前缀树的实现
  • canvas 制作2048
  • playwright: 全局修改页面等待超时时间
  • C++类和对象(中)
  • Docker安装EalasticSearch、Kibana,安装Elasticvue插件
  • 算法训练营 day39 贪心算法 无重叠区间 划分字母区间 合并区间
  • c/c++开发,无可避免的文件访问开发案例
  • MySQL学习笔记
  • ccs导入工程失败的处理方法
  • 探针台常见的故障及解决方法
  • 域内资源探测
  • c# 将数据导出到EXCEL文件
  • 微服务 分片 运维管理
  • 批量占满TEMP表空间问题处理与排查
  • Pytorch中的tensor和variable
  • 暗月内网渗透实战——项目七
  • 【Java 面试合集】描述下Objec类中常用的方法(未完待续中...)
  • SQLSERVER 的 truncate 和 delete 有区别吗?
  • 【C++】CC++内存管理
  • 数据预处理之图像去空白
  • 真的麻了,别再为难软件测试员了......
  • 2月9日,30秒知全网,精选7个热点
  • 球面坐标系下的三重积分
  • 谷歌 Jason Wei | AI 研究的 4 项基本技能
  • excel数据整理:合并计算快速查看人员变动
  • vit-pytorch实现 MobileViT注意力可视化
  • Python将字典转换为csv
  • EasyX精准帧率控制打气球小游戏
  • 你知道 GO 中什么情况会变量逃逸吗?
  • 一篇文章学懂C++和指针与链表