爱心捐赠网站怎么做,制作网站的步骤和过程,珠海工商年检到哪个网站做,自己做网站前期困难吗目录
引言
1. CMake的安装
2. CMake的原理
3. CMake入门
3.1 CMakeLists.txt与注释
3.2 版本指定与工程描述
3.3 生成可执行程序
3.4 定义变量与指定输出路径
3.5 指定C标准
3.6 搜索文件
3.7 包含头文件
4. CMake进阶
4.1 生成动静态库
4.2 链接动静态库
4.… 目录
引言
1. CMake的安装
2. CMake的原理
3. CMake入门
3.1 CMakeLists.txt与注释
3.2 版本指定与工程描述
3.3 生成可执行程序
3.4 定义变量与指定输出路径
3.5 指定C标准
3.6 搜索文件
3.7 包含头文件
4. CMake进阶
4.1 生成动静态库
4.2 链接动静态库
4.3 日志
4.4 变量操作 4.5 定义宏
5. CMake精通
5.1 CMake的嵌套
5.2 条件判断
5.3 循环
结语 引言
CMake是一个跨平台的项目构筑工具。当项目规模庞大依赖关系错综复杂时编写 makefile 的工作量较大解决依赖关系时也容易出错。同时makefileakefile 非常依赖于当前的编译平台无法跨平台使用。而CMake以其出色的灵活性和强大的功能成为了解决问题的理想选择。
本文笔者将详细介绍CMake的用法帮助你高效地管理项目构建过程。
1. CMake的安装
在这里我们主要介绍Linux与Windows下的安装。 Linux下的安装 在Centos上我们可以使用以下命令
sudo yum install cmake
在Ubuntu或Debian上我们可以使用以下命令
sudo apt install cmake
安装完成后我们可以在终端下输入:
cmake -version
如果安装成功会显示cmake的版本。 Windows下的安装 打开浏览器访问CMake的官方网站下载页面CMake Download。 下滑选择你要安装的版本然后点击链接。 这里推荐选择第一个注意如果选择的是zip格式需要手动解压并设置环境变量。 下载后按指引安装即可。 打开命令窗口输入cmake --version验证CMake 是否已正确安装 2. CMake的原理
CMake并不直接编译源代码它根据开发者在CMakeLists.txt文件指定的编译流程生成适用于不同平台和编译器的本地化构建文件。
在Linux上是makefile文件在Windows是Visual Studio解决方案文件.sln和项目文件.vcxproj或.vcxproj.filters。生成的这些文件也不编译源代码他们用来描述工程的组织架构帮助编译器编译。流程如下图 简而言之CMake之所以可以跨平台是因为其在不同平台可以生成相应的构筑文件。
同时它还能够检测系统环境并设置相应的编译器标志和库路径进一步简化跨平台开发。支持条件逻辑允许开发者根据不同的平台或编译器选项定制构建过程。
3. CMake入门
演示文件介绍
演示目录下共有六个文件: head.h add.cpp div.cpp sub.cpp mul.cpp main.cpp。
add.cpp div.cpp sub.cpp mul.cpp分别定义了加减乘除函数。
//add.cpp#include head.h
int myadd(int x,int y)
{return xy;
}
//sub.cpp#include head.h
int mysub(int x,int y)
{return x-y;
}
//mul.cpp#include head.h
int mymul(int x,int y)
{return x*y;
}
//div.cpp#include head.h
int mydiv(int x,int y)
{return x/y;
} head.h声明了这些函数 。
#pragma once
int myadd(int x,int y);
int mydiv(int x,int y);
int mymul(int x,int y);
int mysub(int x,int y);main.cpp调用了这些函数。
#includeiostream
#includehead.hint main()
{int x6,y3;std::cout x y myadd(x,y) std::endl;std::cout x - y mysub(x,y) std::endl;std::cout x * y mymul(x,y) std::endl;std::cout x / y mydiv(x,y) std::endl;return 0;
}
当使用gcc编译文件我们可以使用以下命令
g -stdc11 -o program *.cpp 可以看到源文件成功编译代码成功运行。 下面我们演示如何使用CMake编译。
3.1 CMakeLists.txt与注释
首先我们需要创建一个CMakeLists.txt注意文件名严格区分大小写。创建成功后我们在文件中编写命令。这是CMake的基石。 行注释 在CMake中我们使用 # 进行行注释。效果类似C/C中的 // 。
#这是一行注释 段注释 当我们要进行段注释时我们使用 #[[ ]] 效果类似C/C中的 /* */ 。
#[[这是一段注释
这是一段注释
这是一段注释
这是一段注释]]
3.2 版本指定与工程描述 版本指定 在CMake的版本更新中会更新新的命令这些命令在低版本并不兼容所以需要通过cmake_minimum_required 指定需要的最低版本。这并不是必须的但如果不加可能会有警告。
示例
#语法
cmake_minimum_required(VERSION [版本号])
#示例
cmake_minimum_required(VERSION 3.0) 工程描述 我们可以使用 project 定义工程名称工程的版本、工程描述、web主页地址、支持的语言默认情况支持所有语言如果不需要这些都是可以忽略的只需要指定出工程名字即可。
定义项目名称: project(PROJECT_NAME) 这是最基本的用法只需要指定项目名称。版本信息: VERSION major[.minor[.patch[.tweak]]] 可以指定项目的版本号。项目描述: DESCRIPTION description 可以为项目添加描述。Web主页地址: HOMEPAGE_URL url 可以指定项目的主页URL。支持的语言: LANGUAGES lang [lang...] 可以指定项目支持的编程语言。如果不指定默认情况下CMake支持多种语言如C和C。忽略可选参数:如果不需要设置版本、描述、主页或特定语言可以忽略这些参数只指定项目名称
示例
#语法
project(PROJECT-NAME[VERSION major[.minor[.patch[.tweak]]]][DESCRIPTION project-description-string][HOMEPAGE_URL url-string][LANGUAGES language-name...])
#示例
#定义项目名称版本描述主页URL以及支持的语言
project(MyProjectVERSION 1.0.0DESCRIPTION 这是一个示例项目HOMEPAGE_URL http://www.example.comLANGUAGES CXX
)
现在我们在CMakeLists.txt中指定版本信息与工程描述。 3.3 生成可执行程序
我们已经指定了版本信息与工程描述。现在我们需要使用 add_executable 定义工程生成的可执行程序。
//语法
add_executable(可执行程序名 源文件名称)
//示例
add_executable(program main.cpp add.cpp sub.cpp mul.cpp div.cpp)
现在我们继续完善CMakeLists.txt 一个基本的 CMakeLists.txt 完成了。
我们使用cmake命令构筑项目。
#语法
cmake CMakeLists.txt文件所在路径
#示例
cmake .
输入cmake . 命令 可以看到当前目录生成了许多文件。 对应的目录下生成了makefile文件此时执行make命令便可到可执行文件。 可以看到编译成功我们执行程序。 程序执行成功。在上面的过程中我们发现执行cmake后会生成一堆文件使得目录十分杂乱。我们可以单独创建一个目录在该目录下执行cmake .. 文件会创建在此目录更加整洁。 需要注意的是此时只能在 build 目录下执行生产的可执行文件也在 build 目录。
3.4 定义变量与指定输出路径
在上面的过程中我们使用了五个源文件。如果这些源文件需要反复使用我们每次都需要将他们的名称写出来这是非常低效的。cmake为我们提供了 set 指令来定义变量与设置宏。
#语法
set(VARIABLE_NAME value [CACHE_TYPE [CACHE_VARIABLE]])
VARIABLE_NAME变量的名称。value为变量赋予的值。CACHE_TYPE可选指定缓存变量的类型如 FILEPATH、PATH、STRING、BOOL 等。CACHE_VARIABLE可选如果指定变量将被存储在 CMake 缓存中而不是只限于当前的 CMakeLists.txt 文件。
后两项我们暂时不做讨论。现在我们可以将要使用的源文件名存储在变量里
#定义一个变量SOURCE_FILE存储源文件名
set(SOURCE_FILE main.cpp add.cpp sub.cpp div.cpp mul.cpp)
如果要取变量中的值语法格式为
${变量名} 现在我们修改CMakeLists.txt使用变量存储文件名。 编译并运行程序。 可以看到程序成功运行。
上面我们提到可以单独创建一个目录在该目录下执行cmake .. 这样的操作使目录更加整洁但这样可执行文件就会生成在build目录下能不能指定可执行文件输出路径呢CMake为我们提供了一个宏 EXECUTABLE_OUTPUT_PATH 我们可以通过设置这个宏指定输出路径。这里的输出路径支持相对路径与绝对路径。我们可以使用 set 命令设置宏。
#定义一个变量存储路径,输出路径为上一级的bin目录
set(OUTPATH ../bin)
#设置宏
set(EXECUTABLE_OUTPUT_PATH ${OUTPATH})
注意如果输出路径中的子目录不存在会自动生成。
现在我们修改CMakeLists.txt指定输出路径。 可以看到成功创建了目录 bin 并生成了可执行程序。
3.5 指定C标准
在这里我们再额外介绍一个宏 CMAKE_CXX_STANDARD 。这个宏用来指定C标准。在CMake中想要指定C标准有两种方式通过set命令指定在执行cmake指令时指定。
我们在main.cpp中添加一行代码
auto x6;
auto关键字在 C11 引入下面我们分别演示用通过set命令指定C11和在执行cmake指令时指定。 通过set命令指定C11 我们需要通过set命令设置 CMAKE_CXX_STANDARD 的值示例如下
set(CMAKE_CXX_STANDARD 11)
同样修改CMakeLists.txt后运行。 文件成功编译。 执行cmake指令时指定 我们注释掉CMakeLists.txt中指定CMAKE_CXX_STANDARD的命令。在执行cmake指令时设置CMAKE_CXX_STANDARD的值。注意 CMAKE_CXX_STANDARD 需要的最低版本为3.1。这里并没有更改最低版本 我们使用cmake命令
cmake .. -DCMAKE_CXX_STANDARD11 可以看到同样编译成功。
3.6 搜索文件
在我们的示例文件中只有五个源文件如果有大量源文件那么需要一个一个罗列出来十分繁琐。cmake中同样提供了搜索文件的命令 aux_source_directory 与 file 命令。 aux_source_directory aux_source_directory 命令可以查找某个路径下的所有源文件语法
aux_source_directory(directory variable)
directory: 要搜索源文件的目录的路径。这可以是相对路径或绝对路径。variable: 用于存储找到的源文件列表的变量名。 示例使用
#搜索上一级目录的源文件
aux_source_directory(.. SOURCE_FILE)
现在我们修改CMakeLists.txt并执行cmake命令。 CMAKE_CURRENT_SOURCE_DIR 是 CMake 中的一个预定义变量它指向当前正在处理的 CMakeLists.txt 文件所在的目录。注意如果使用相对路径相对路径是相对于CMakeLists.txt 文件所在的目录而非执行cmake命令的目录。 可以看到成功编译。 file file 命令用于对文件和目录进行操作包括检查文件属性、读取和写入文件内容、复制文件、删除文件等。在这里我们只介绍一种用法搜索文件。语法
file(GLOB/GLOB_RECURSE VARIABLE PATH)
GLOB/GLOB_RECURSE选择非递归搜索(GLOB)还是递归搜索(GLOB_RECURSE)递归搜索会搜索路径下的所有目录。VARIABLE存储搜索结果的变量。PATH搜索的路径与搜索的文件名。
file使用相对路径时同样相对于CMakeLists.txt 文件所在的目录而非执行cmake命令的目录。 示例
#搜索CMakeLists.txt路径下所有源文件并存储在SOURCE_FILE
file(GLOB SOURCE_FILE ./*.cpp)
修改CMakeLists.txt同样可以成功编译。 3.7 包含头文件
现在我们将工程结构调整为下面的结构(文件搜索路径同步调整) 我们执行cmake命令。 发现执行失败这是为什么我们的源文件都包含了head.h头文件。 #includehead.h 当我们使用 方式包含头文件时默认从当前源文件所在路径搜索。如果当前目录下没有找到编译器会搜索项目中指定的其他包含目录通过编译器的-I选项或在IDE中设置的包含路径来指定的。如果以上目录都没有找到编译器会搜索系统的标准库包含目录。
在我们调整了工程结构后头文件与源文件不在同一目录我们又没有指定头文件搜素路径。所以找不到头文件。我们可以使用include_directories 指定头文件搜索路径。
#语法
include_directories([headpath])
#示例
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
现在我们在 CMakeLists.txt 加入头文件搜索路径。
再次执行cmake与make命令。 程序编译成功。
4. CMake进阶
现在我们来学习使用cmake制作动态库与静态库对动静态库不熟悉的读者可以阅读我的往期博客——动态库与静态库。
4.1 生成动静态库 生成静态库 生成静态库需要用到命令 add_library 语法
#语法
add_library([库名称] SHARED/STATIC [源文件1] [源文件2] ...)
#示例生成一个名为libmymath.a的静态库
add_library(mymath STATIC add.cpp sub.cpp mul.cpp div.cpp)
在Linux中静态库名字分为三部分lib库名.a命令需要指出的是中间部分另外两部分在生成库文件时会自动补全。命令的第二个选项代表生成的是静态库STATIC还是动态库SHARED。
现在我们调整一下工程结构CMakeLists.txt 同步调整 。 在 CMakeLists.txt 中我们删除add_executable添加add_library生成静态库。 我们执行cmake命令 可以看到build 目录下成功生成了静态库文件 libmymath.a 。 生成动态库 生成静态库需要用到命令 add_library 只需将第二个参数由STATIC改为SHARED。我们修改CMakeLists.txt。与静态库相同命令只需要指出名字中间部分 执行cmake命令并编译。 可以看到build 目录下成功生成了动态库文件 libmymath.so 。 指定库文件的输出路径 指定库文件的输出路径有两种方法设置 EXECUTABLE_OUTPUT_PATH 指定输出路径设置 LIBRARY_OUTPUT_PATH 指定输出路径。 使用 EXECUTABLE_OUTPUT_PATH 指定输出路径只对动态库有效因为Linux下生成的动态库默认是有执行权限的而静态库没有。 我们在这只演示通过 LIBRARY_OUTPUT_PATH 指定输出路径。 我们执行cmake并编译。 可以看到库文件被成功生成到指定的目录下。
4.2 链接动静态库
cmake 链接库的命令为target_link_libraries 。target_link_libraries 可以链接动态库与静态库。
target_link_libraries(target PRIVATE|PUBLIC|INTERFACE item...)
target要链接库的目标名称可以是可执行文件或库。PRIVATE|PUBLIC|INTERFACE指定链接库的可见性PRIVATE链接库仅对当前目标有效不会传递给依赖该目标的其他目标。 PUBLIC链接库对当前目标及其依赖者都有效链接属性会传递给依赖该目标的其他目标。 INTERFACE指定仅对依赖该目标的其他目标可见的接口链接库不包括其实现细节。item...一个或多个库的名称或目标名称可以是库文件的路径、目标名称或者是使用 find_package 或 find_library 找到的库名称。
关于可见性问题可能不太好理解我们举例说明。现在有以下CMake命令
# 库A依赖B和C
target_link_libraries(A PUBLIC B PUBLIC C)# 动态库D链接库A
target_link_libraries(D PUBLIC A)
在这个例子中
A链接了B和C并且使用了PUBLIC关键字所以任何链接到A的库包括D也会链接B和C。由于D链接了A并且同样使用了PUBLIC关键字D的任何依赖者也将链接A、B和C。
如果将PUBLIC更改为PRIVATE或INTERFACE链接行为将相应改变
使用PRIVATED将链接A但D的依赖者不会链接A、B或C。使用INTERFACED将不会链接A的实际实现但D的依赖者将能够使用A定义的接口。
如果target_link_libraries 。target_link_libraries 链接的是第三方库需要用 link_directories 指定库所在的路径。
link_directories(libpath)
现在我们调整工程结构如下。 我们链接lib中的 libmymath.so 。向 CMakeLists.txt 中添加以下命令
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
target_link_libraries(program libmymath.so) 我们执行cmake命令并编译 可以看到程序成功运行。需要注意的是 target_link_libraries 。target_link_libraries 命令需要写在生成目标文件之后。
4.3 日志
在CMake中我们可以使用message命令记录日志或输出信息到控制台。这个命令允许输出不同级别的信息包括普通消息、警告和错误。
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR] message)
STATUS显示状态消息通常不是很重要。WARNING显示警告消息编译过程会继续执行。AUTHOR_WARNING显示作者警告消息用于开发过程中编译过程会继续执行。FATAL_ERROR显示错误消息终止所有处理过程。SEND_ERROR显示错误消息但继续执行会跳过生成步骤。
CMake的命令行工具会在stdout上显示STATUS消息在stderr上显示其他所有消息。
我们简单测试一下。 执行cmake命令 可以看到信息正常输出在输出错误信息后编译终止。
4.4 变量操作
在在CMake中所有的变量都为字符串类型变量操作实际上也是字符串操作。CMake提供了多种命令来操作这些字符串变量。 拼结变量 拼接字符串可以通过 list 命令与 set 命令进行。
#使用set进行拼接
set(变量名1 ${变量名1} ${变量名2} ...)
#示例使用
set(variables1 ${variables1} ${variables2})
我们简单演示一下并使用 message 输出。 可以看到成功输出。
使用 list 命令拼接变量
#语法
list(APPEND 变量名1 ${变量名2} ...)
#示例使用
list(APPEND variables1 ${variables2})
我们简单演示一下 移除字符串 有时候我们需要从变量中移除字串这时候我们可以也使用 list
#语法
list(REMOVE_ITEM 变量名 要移除的子串)
#示例
list(REMOVE_ITEM VAR Hello )
我们简单演示一下 list 命令还有许多用法我们这里不再一 一演示。 创建和初始化列表 set(MY_LIST item1 item2 item3) 追加元素list(APPEND ...) list(APPEND MY_LIST new_item1 new_item2) 插入元素list(INSERT ...) list(INSERT MY_LIST 1 item1.5) # 在位置1插入元素 移除元素list(REMOVE_ITEM ...) list(REMOVE_ITEM MY_LIST item2) 移除指定索引的元素list(REMOVE_AT ...) list(REMOVE_AT MY_LIST 1) # 移除索引为1的元素 获取列表长度list(LENGTH ...) list(LENGTH MY_LIST LENGTH_OF_LIST) 获取特定索引的元素list(GET ...) list(GET MY_LIST 0 FIRST_ITEM) 设置特定索引的元素 list(SET MY_LIST 1 new_item2) # 设置索引为1的元素 连接列表元素为字符串list(JOIN ...) list(JOIN MY_LIST , JOINED_STRING) 分割字符串为列表string(REPLACE ...)与list(APPEND ...)结合使用 string(REPLACE , ; MY_LIST ${SOME_STRING}) 查找元素list(FIND ...) list(FIND MY_LIST item1 INDEX) 反转列表list(REVERSE ...) list(REVERSE MY_LIST) 排序列表list(SORT ...) list(SORT MY_LIST) # 默认升序排序 复制列表list(COPY ...) list(COPY MY_LIST COPY_OF_MY_LIST) 清除列表list(CLEAR ...) list(CLEAR MY_LIST) 4.5 定义宏
在CMake中宏主要分为两种CMake脚本中的宏和C源代码中通过CMake定义的条件编译宏。 条件编译宏 进行程序测试的时候我们可以在代码中添加宏定义通过宏来控制这些代码是否生效
#includeiostreamint main()
{
#ifdef DEBUGstd::cout DEBUG std::endl;
#endif
#ifndef DEBUGstd::cout NDEBUG std::endl;
#endifreturn 0;
}
我们可以在CMake脚本中定义条件编译宏 。命令为 add_definitions 。
#定义宏
add_definitions(-D宏名称)
#定义宏并赋值
add_definitions(-DDEBUG1)
我们修改 CMakeLists.txt 并简单测试 可以看到成功定义了DEBUG。 CMake中的宏 CMake中的宏是一系列可以被多次调用的CMake命令可以接收参数类似于函数。用于封装重复使用的构建逻辑。我们可以使用 macro 和 endmacro 命令定义宏。宏在定义它们的CMake文件中全局可见。
macro(MyMacro arg1 arg2) #定义宏message(STATUS Arg1: ${arg1})message(STATUS Arg2: ${arg2})
endmacro() #定义宏结束
# 调用宏
MyMacro(value1 value2)
简单演示一下 5. CMake精通
到这里相信你已经掌握了CMake的基础用法下面让我们进一步学习CMake的使用。
5.1 CMake的嵌套
当我们的项目很大时项目中会有很多的源码目录如果只使用一个CMakeLists.txt会比较复杂我们可以给每个源码目录都添加一个CMakeLists.txt文件这样每个文件都不会太复杂而且更灵活更容易维护。 在这个工程中我们有五个目录我们在 build 目录下执行CMake命令。在src下我们生成一个动态库在test目录下我们链接动态库生成一个可执行文件。
嵌套的CMake是一个树状结构最顶层的 CMakeLists.txt 是根节点其次是子节点。我们需要使用 add_subdirectory() 命令在结点间建立父子关系。
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
source_dir要添加的子目录的路径相对于当前 CMakeLists.txt 文件的路径。binary_dir可选构建输出的目录如果未指定CMake 会使用 source_dir 作为构建目录。EXCLUDE_FROM_ALL可选如果指定该子目录的构建目标不会包含在 all 目标中即默认情况下不会在调用 make 时构建。
后两项我们通常用不到可以忽略在建立关系后父节点的变量可以被子节点继承执行cmake命令时也会一起处理。
下面我们来编写根目录的 CMakeLists.txt 这里只需要定义一下工程名称最低版本建立父子关系定义一些变量即可。 下面我们编写 src 下的 CMakeLists.txt在这部分我们需要生成一个动态库并输出到lib目录下。 在 test 下的 CMakeLists.txt 我们需要链接动态库生成可执行文件。 现在我们完成了准备工作我们在build目录下执行cmake命令。 可以看到程序成功运行。
5.2 条件判断
cmake下的条件判断与C语言基本类似。不同的是cmake需要使用endif() 结束 if 语句块
if(条件1)# 条件为真时执行的命令
elseif(条件2)# 条件为真时执行的命令
else()# 没有条件为真时执行的命令
endif()
条件主要包括以下种类
变量检查变量是否存在或其值是否符合特定条件。平台根据操作系统、编译器等平台特性进行判断。文件和目录检查文件或目录是否存在。逻辑运算使用逻辑运算符来组合多个条件。 变量 变量的判断有以下关键字DEFINED、EXISTS、IS_DIRECTORY
DEFINED:DEFINED 用于检查变量是否已经被定义。它不检查变量的值只检查变量是否存在。
if(DEFINED MY_VARIABLE)message(STATUS MY_VARIABLE is defined.)
endif()
EXISTS: EXISTS 用于检查文件或目录是否存在。接受一个路径作为参数并返回一个布尔值。
if(EXISTS ${CMAKE_SOURCE_DIR}/somefile.txt)message(STATUS The file somefile.txt exists.)
endif() IS_DIRECTORY: IS_DIRECTORY 用于检查给定的路径是否是一个目录。如果路径是一个存在的目录返回布尔值。
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/somedir)message(STATUS The path somedir is a directory.)
endif() 逻辑运算 CMake 支持AND, OR, NOT 逻辑运算符来进行更复杂的条件判断。
AND(同C语言 )逻辑与。两个条件都必须为真整个表达式才为真。OR(同C语言 || )逻辑或。两个条件中至少有一个为真整个表达式就为真。NOT(同C语言 ! )逻辑非。反转条件的真假。 平台 平台判断包括检查操作系统、编译器、架构我们这里主要介绍操作系统判断。
CMake 提供了一些预定义的变量来标识操作系统类型例如 WIN32, UNIX, 和 APPLE。
if(WIN32)message(STATUS Windows) //Windows
elseif(UNIX)message(STATUS Unix) //Linux
elseif(APPLE)message(STATUS macOS) //苹果
endif() 比较 条件判断必不可少涉及到比较。我们这里介绍数值比较与字符串比较。
数值比较: LESS : 检查左侧是否小于右侧。 GREATER : 检查左侧是否大于右侧。 EQUAL : 检查两侧是否数值相等。 NOTEQUAL !: 检查两侧是否数值不相等。
字符串比较:
STRLESS: 字符串是否字典序较小。STRGREATER: 字符串是否字典序较大。STREQUAL: 字符串是否相等。NOT STREQUAL: 字符串是否不相等。
# 定义变量
set(a 10)
set(b 20)# 数值比较
if(a LESS b)message(ab)
endif()if(a EQUAL 10)message(a10)
endif()# 字符串比较
if(a STREQUAL 10)message(a 10)
endif()算术运算 同样在循环与条件判断中算数运算必不可少cmake为我们提供 math 命令用于执行算术运算。
加法
set(counter 1) math(EXPR counter ${counter} 1) # counter 现在是 2
减法
set(counter 5) math(EXPR counter ${counter} - 2) # counter 现在是 3
乘法
set(counter 3) math(EXPR counter ${counter} * 2) # counter 现在是 6
除法
set(counter 20) math(EXPR counter ${counter} / 4) # counter 现在是 5
模运算
set(counter 7) math(EXPR counter ${counter} % 3) # counter 现在是 1
使用变量
set(a 10)
set(b 3)
math(EXPR result ${a} * ${b}) # result 是 30
5.3 循环
CMake中的循环分为两种foreach 循环和 while 循环。 foreach 循环 foreach循环的基本语法如下
foreach(variable IN list)# 命令
endforeach()
variable这是循环变量每次迭代都会赋予它列表中的一个元素。list这是要遍历的元素列表可以是列表、数组或任何可迭代的对象。 示例使用 while循环 while循环比较简单只需要指定出循环结束的条件。
while(condition)# 命令序列
endwhile()
这里的 condition 是一个布尔表达式每次循环迭代开始时都会进行判断。只要条件为真循环就会继续执行。一旦条件为假循环就会终止。
示例使用 结语
到这里我们已经完成了CMake的学习。笔者能力有限如有错漏之处欢迎指正。同时很多命令语法只是讲了基础用法如果有读者想要深入研究可以参考CMake的官方文档。制作不易求点赞关注。