本文继续CMakeLists.txt 语法规则的学习,先完成上篇条件判断的学习。

条件判断

  • COMMAND command-name

如果 command-name 是一个已经定义的命令、宏或函数时,条件判断为真;否则为假。

除了宏之外,在 cmake 中还可以定义函数。

if(COMMAND yyds)message(true)else()message(false)endif()

输出为:false

if(COMMAND project)message(true)else()message(false)endif()

输出为:true

TARGET target-name

如果target-name是add_executable()、add_library()或add_custom_target()定义的目标(这些目标在整个工程中必须是唯一的,不可出现两个名字相同的目标),则判断为真;否则为假。

if(TARGET hello)message(true)else()message(false)endif()

输出为:false

add_library(hello hello.c)if(TARGET hello)message(true)else()message(false)endif()

输出为:true

  • EXISTS path

如果 path 指定的文件或目录存在,则条件判断为真;否则为假。需要注意的是,path 必须是文件或目录的全路径,也就是绝对路径。 譬如工程目录结构如下所示:

├── build├── CMakeLists.txt├── hello│ ├── hello.c│ └── hello.h└── main.c

在顶层 CMakeLists.txt 文件中使用 if(EXISTS path)进行判断:

if(EXISTS ${PROJECT_BINARY_DIR})message(true)else()message(false)endif()

输出为:true

if(EXISTS ${PROJECT_BINARY_DIR}/hello)message(true)else()message(false)endif()

输出为:true

if(EXISTS ${PROJECT_BINARY_DIR}/world)message(true)else()message(false)endif()

输出为:false

if(EXISTS ${PROJECT_BINARY_DIR}/hello/hello.c)message(true)else()message(false)endif()

输出为:true

  • IS_DIRECTORY path

如果 path 指定的路径是一个目录,则条件判断为真;否则为假,同样,path 也必须是一个绝对路径。 还是以上例中的工程目录结构为例:

if(IS_DIRECTORY ${PROJECT_BINARY_DIR}/hello)message(true)else()message(false)endif()

输出为:true

if(IS_DIRECTORY ${PROJECT_BINARY_DIR}/hello/hello.c)message(true)else()message(false)endif()

输出为:true

  • IS_ABSOLUTE path

如果给定的路径 path 是一个绝对路径,则条件判断为真;否则为假。

if(IS_ABSOLUTE ${PROJECT_BINARY_DIR})message(true)else()message(false)endif()

输出为:true

if(IS_ABSOLUTE ./hello)message(true)else()message(false)endif()

输出为:false

  • MATCHES regex

这个表达式用的比较多,可以用来匹配字符串,可以使用正则表达式进行匹配。 如果给定的字符串或变量的值与给定的正则表达式匹配,则为真,否则为假。

set(MY_STR "Hello World")if(MY_STR MATCHES "Hello World")message(true)else()message(false)endif()

输出为:true

其实也可以引用变量:

set(MY_STR "Hello World")if(${MY_STR} MATCHES "Hello World")message(true)else()message(false)endif()

输出为:true

set(MY_STR "Hello World")if("Hello World" MATCHES "Hello World")message(true)else()message(false)endif()

输出为:true

  • IN_LIST

如果左边给定的变量或字符串是右边列表中的某个元素相同,则条件判断为真;否则为假。

set(MY_LIST Hello World China)if(Hello IN_LIST MY_LIST)message(true)else()message(false)endif()

输出为:true

set(MY_LIST Hello World China)set(Hello China)if(Hello IN_LIST MY_LIST)message(true)else()message(false)endif()

输出为:true

  • DEFINED

如果给定的变量已经定义,则条件判断为真,否则为假;只要变量已经被设置(定义),if 条件判断就是真,至于变量的值是真还是假并不重要。

if(DEFINED yyds)message(true)else()message(false)endif()

输出为:false

set(yyds "YYDS")if(DEFINED yyds)message(true)else()message(false)endif()

输出为:true

  • LESS

如果左边给定的字符串或变量的值是有效数字并且小于右侧的值,则为真。否则为假。 测试如下:

if(100 LESS 20)message(true)else()message(false)endif()

输出为:false

if(20 LESS 100)message(true)else()message(false)endif()

输出为:true

  • GREATER

如果左边给定的字符串或变量的值是有效数字并且大于右侧的值,则为真。否则为假。

测试如下:

if(20 GREATER 100)message(true)else()message(false)endif()

输出为:false

if(100 GREATER 20)message(true)else()message(false)endif()

输出为:true

  • EQUAL

如果左边给定的字符串或变量的值是有效数字并且等于右侧的值,则为真。否则为假。

测试如下:

if(100 EQUAL 20)message(true)else()message(false)endif()

输出为:false

if(100 EQUAL 100)message(true)else()message(false)endif()

输出为:true

  • elseif 分支

可以使用 elseif 组成多个不同的分支:

set(MY_LIST Hello World China)if(Hello IN_LIST MY_LIST)message(Hello)elseif(World IN_LIST MY_LIST)message(World)elseif(China IN_LIST MY_LIST)message(China)else()message(false)endif()