目录

  • 一、基本语法
  • 二、基本用法
  • 三、其他用法
  • 3.1 逻辑运算
  • 3.2 存在性检查
  • 3.3 文件操作
  • 3.4 数值比较
  • 3.5 字符串比较
  • 3.6 版本比较
  • 3.7 路径比较 (CMake 3.24引入)


一、基本语法

if(<condition>)
  <commands>
elseif(<condition>) # optional block, can be repeated
  <commands>
else()              # optional block
  <commands>
endif()

如果需要对项目进行有条件的编译,则需要用到 if-else 语句。

其中,<condition> 可以是常量、变量、字符串。

  • 对于常量:
  • 如果是 1ONYESTRUEY或非零数(包括浮点数),则为 True
  • 如果是 0OFFNOFALSENIGNORENOTFOUND、空字符串或以 -NOTFOUND 后缀结尾,则为 False
  • 布尔常量不区分大小写。
  • 如果参数不是这些特定常量之一,则将其视为变量或字符串。
  • 对于变量:
  • 如果变量未定义,则为 False
  • 环境不能直接参与该判断,如 if(ENV{some_var}) 均判断为 False
  • 如果变量的值不是上述常量中为 False 的任一值,则该变量判断为 True
  • 对于字符串:
  • 带引号的字符串始终判断为 False,除非字符串的值是上述常量中为 True 的任一值。

二、基本用法

比如需要根据操作系统执行不同的代码:

# CMakeLists.txt
# CMake最低版本要求
cmake_minimum_required(VERSION 3.5)

# 项目名称
project(test_6)

if(WIN32)
	message(STATUS "Now is windows")
elseif(APPLE)
	message(STATUS "Now is Apple systens.")
elseif(UNIX)
	message(STATUS "Now is UNIX-like OS's.")
endif()

三、其他用法

3.1 逻辑运算

  • 取反运算
if(NOT <condition>)

如果 condition 不为真,则语句为真。

  • 与运算
if(<cond1> AND <cond2>)

如果两个条件都为真,则语句为真。

  • 或运算
if(<cond1> OR <cond2>)

如果任一条件为真,则语句为真。

  • 括号
if((condition) AND (condition OR (condition)))

首先评估括号内的条件,然后像前面的示例一样评估其余条件。如果有嵌套的括号,则将最里面的括号作为包含它们的条件的一部分进行评估。

3.2 存在性检查

  • 命令、宏或函数
if(COMMAND command-name)

如果给定名称是可以调用的命令,宏或函数,则为 True

  • 策略
if(POLICY policy-id)

如果给定名称是现有策略(格式为CMP<NNNN>),则为 True

  • 目标
if(TARGET <target-name>)

如果给定名称是通过调用 add_executable()add_library()add_custom_target() 创建的现有逻辑目标名称,则为 True

  • 测试
if(TEST test-name)

CMake3.3 新增,如果给定名称是通过调用 add_test() 创建的现有测试名称,则为 True

  • 变量
if(DEFINED <name>|CACHE{<name>}|ENV{<name>})

如果 <name> 是已经定义了的变量、缓存变量或环境变量,则为 True。变量的值无关紧要。
请注意:

  • 宏参数不是变量。
  • CACHE{<name>} 是在 CMake 3.14 才引入的。
  • if(DEFINED someName) 不能区分是缓存变量还是普通变量,只要该变量被定义,都返回 Trueif(DEFINED CACHE{someName}) 仅当缓存变量存在时,才返回 True
    如果需要知道非缓存变量是否存在,需要使用 if(DEFINED someName AND NOT DEFINED CACHE{someName})
  • 列表
if(<variable|string> IN_LIST <variable>)

如果给定元素包含在指定列表变量中,则为 True

3.3 文件操作

  • 存在性检查
if(EXISTS path-to-file-or-directory)

如果指定的文件或目录存在,则为True

如果给定路径是空字符串,则为 False

仅针对显式完整路径明确定义行为(前导~/不扩展为主目录,并被视为相对路径)。

解析符号链接,即,如果命名的文件或目录是符号链接,则如果符号链接的目标存在,则返回 True

  • 新旧比较
if(file1 IS_NEWER_THAN file2)

如果 file1file2 版本更新、时间戳完全相同或两个文件之一不存在,则为 True

仅针对完整路径定义行为。

  • 是否为目录
if(IS_DIRECTORY path-to-directory)

如果给定名称是目录,则为True。仅针对完整路径定义行为。

  • 是否为符号链接
if(IS_SYMLINK file-name)

如果给定名称是符号链接,则为True。仅针对完整路径定义行为。

  • 是否为绝对路径
if(IS_ABSOLUTE path)

如果给定路径是绝对路径,则为True

注意:

  • path 为空值,返回 False
  • 在 Windows 主机上,任何 path 以驱动器号和冒号(例如C:)、正斜杠或反斜杠开头的内容都将评估为 True。例如 C:no\base\dir ,即使路径的非驱动部分是相对路径。
  • 在非 Windows 主机上,任何path以波形符 ( ~) 开头的值都计算为 True

3.4 数值比较

  • 小于
if(<variable|string> LESS <variable|string>)

如果给定的字符串或变量的值是有效数字且小于右边的数字,则为 True

  • 大于
if(<variable|string> GREATER <variable|string>)

如果给定的字符串或变量的值是有效数字并且大于右侧的数字,则为 True

  • 等于
if(<variable|string> EQUAL <variable|string>)

如果给定的字符串或变量的值是有效数字并且等于右侧的数字,则为 True

  • 小于等于 (CMake 3.7引入)
if(<variable|string> LESS_EQUAL <variable|string>)

如果给定的字符串或变量的值是有效数字且小于或等于右侧的数字,则为 True

  • 大于等于 (CMake 3.7引入)
if(<variable|string> GREATER_EQUAL <variable|string>)

如果给定的字符串或变量的值是有效数字并且大于或等于右侧的数字,则为 True

3.5 字符串比较

  • 小于
if(<variable|string> STRLESS <variable|string>)

如果给定的字符串或变量的值在字典上小于右侧的字符串或变量,则为 True

  • 大于
if(<variable|string> STRGREATER <variable|string>)

如果给定的字符串或变量的值在字典上大于右侧的字符串或变量,则为 True

  • 等于
if(<variable|string> STREQUAL <variable|string>)

如果给定的字符串或变量的值在字典上等于右侧的字符串或变量,则为 True

  • 小于等于 (CMake 3.7引入)
if(<variable|string> STRLESS_EQUAL <variable|string>)

如果给定的字符串或变量的值在字典上小于或等于右侧的字符串或变量,则为 True

  • 大于等于 (CMake 3.7引入)
if(<variable|string> STRGREATER_EQUAL <variable|string>)

如果给定的字符串或变量的值在字典上大于或等于右侧的字符串或变量,则为 True

  • 匹配
if(<variable|string> MATCHES regex)

如果给定的字符串或变量的值与给定的常规条件匹配,则为 True。有关正则表达式格式,请参见正则表达式规范。

3.6 版本比较

按组件的整数版本号比较(版本格式为 major[.minor[.patch[.tweak]]],省略的组件视为零)。任何非整数版本组件或版本组件的非整数结尾部分均会在该点处有效截断字符串。

  • 小于
if(<variable|string> VERSION_LESS <variable|string>)

如果给定的字符串或变量的版本号小于右侧的字符串或变量,则为 True

  • 大于
if(<variable|string> VERSION_GREATER <variable|string>)

如果给定的字符串或变量的版本号大于右侧的字符串或变量,则为 True

  • 等于
if(<variable|string> VERSION_EQUAL <variable|string>)

如果给定的字符串或变量的版本号等于右侧的字符串或变量,则为 True

  • 小于等于 (CMake 3.7引入)
if(<variable|string> VERSION_LESS_EQUAL <variable|string>)

如果给定的字符串或变量的版本号小于或等于右侧的字符串或变量,则为 True

  • 大于等于 (CMake 3.7引入)
if(<variable|string> VERSION_GREATER_EQUAL <variable|string>)

如果给定的字符串或变量的版本号大于或等于右侧的字符串或变量,则为 True

3.7 路径比较 (CMake 3.24引入)

if(<variable|string> PATH_EQUAL <variable|string>)

逐级比较两个路径,如每级都相等,则返回 True

注意,多个路径分隔符重叠,会解析为一个,如:a//b///c 会解析为 a/b/c