语法
CMake中的if命令用于有条件地执行一组命令,其格式如下:
if(<condition>)
<commands>
elseif(<condition>) # optional block, can be repeated
<commands>
else() # optional block
<commands>
endif()
根据Condition syntax评估if子句的条件参数(<condition>)。如果结果为true,则执行if块(block)中的命令。否则,以相同方式处理可选的elseif块.最后,如果没有条件为true,则执行可选else块中的命令。
1.Basic Expressions:
if(<constant>)
:如果常量为1, ON, YES, TRUE, Y或非零数(包括浮点数),则为true。如果常量为0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串或以后缀-NOTFOUND结尾,则为false.命名布尔常量不区分大小写。如果参数不是这些特定常量之一,则将其视为变量或字符串,并适用以下两种形式之一if(<variable>)
:如果给定一个定义非false常量的值的变量,则为true。否则为false,包括变量未定义时。注意:宏参数不是变量。环境变量也不能以这种方式测试,例如if(ENV{some_var})将始终评估为false.if(<string>)
:带引号的字符串始终评估为false,除非:字符串的值是真正的常量之一,或者Policy CMP0054为设置为NEW,并且字符串的值恰好是受CMP0054行为影响的变量名称。
if(ON)
message("on") # print
endif()
if(OFF)
message("off") # won't print
endif()
if(YES)
message("yes") # print
endif()
if(NO)
message("no") # won't print
endif()
if(true)
message("true") # print
endif()
if(TRUE)
message("TRUE") # print
endif()
if(FALSE)
message("FALSE") # won't print
endif()
set(ENV{CMAKE_PREFIX_PATH} "github/fengbingchun")
if(ENV{CMAKE_PREFIX_PATH})
message("env") # won't print
endif()
if("csdn")
message("csdn") # won't print
endif()
2.Logic Operators:
- if(NOT <condition>):如果条件不为ture,,则为true.
- if(<cond1> AND <cond2>):如果这两个条件都被单独被认为是true,则为true.
- if(<cond1> OR <cond2>):如果任一条件单独被认为是true,则为true.
- if((condition) AND (condition OR (condition))):首先评估括号内的条件,然后像其它示例一样评估其它条件。在有嵌套括号的地方,最里面的小括号作为条件的一部分被评估
set(var "csdn")
if(NOT var2)
message("not var2") # print
endif()
if(var OR var2)
message("var OR var2") # print
endif()
if(var AND var2)
message("var AND var2") # won't print
endif()
3.Existence Checks
- if(COMMAND command-name):如果给定的name是可以调用的命令、宏或函数,则为true.
- if(POLICY policy-id):如果给定的name是存在的policy(形式为CMP<NNNN>),则为true.
- if(TARGET target-name):如果给定的name是通过调用(在任何目录中)add_executable, add_library, 或add_custom_target命令创建的现有逻辑目标名称(existing logical target name),则为true.
- if(TEST test-name):如果给定的name是由add_test命令创建的现有测试名称(existing test name),则为true.
- if(DEFINED <name>|CACHE{<name>}|ENV{<name>}):如果定义了给定<name>的变量、缓存变量或环境变量,则为true.变量的值无关紧要。注意:宏参数不是变量。无法直接测试<name>是否为非缓存变量。如果存在缓存或非缓存变量someName,则表达式if(DEFINED someName)将评估为true.相比之下,表达式if(DEFINED CACHE{someName})仅在缓存变量someName存在时才为true。如果你需要知道是否存在非缓存变量,则需要测试两个表达式:if(DEFINED someName AND NOT DEFINED CACHE{someName})
function(func)
message("hello func")
endfunction()
if(COMMAND func)
message("func") # print
endif()
if(POLICY CMP0010)
message("policy") # print
endif()
find_package(OpenCV 3.4.2) # -- Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
if(TARGET opencv_core)
message("opencv_core") # print
endif()
set(var OFF) # 变量的值无关紧要
if(DEFINED var)
message("defined var") # print
endif()
set(var2 )
if(DEFINED var2)
message("defined var2") # won't print
endif()
4.File Operations
- if(EXISTS path-to-file-or-directory):如果指定的文件或目录存在,则为true。仅针对显式完整路径(Behavior is well-defined only for explicit full paths).解析符号链接,如果符号链接的目标存在,则为true.
- if(file1 IS_NEWER_THAN file2):如果file1比file2新,或两个文件中的一个不存在,则为true。仅针对完整路径。如果文件时间戳完全相同,则IS_NEWER_THAN比较返回true,这包括为file1和file2传递相同文件名的情况。
- if(IS_DIRECTORY path-to-directory):如果给定name是目录,则为true。仅针对完整路径。
- if(IS_SYMLINK file-name):如果给定name是符号链接,则为true.仅针对完整路径。
- if(IS_ABSOLUTE path):如果给定路径是绝对路径,则为true。注意以下特殊情况:空路径评估为false。在windows主机上,任何以驱动器号和冒号(例如 C:)、正斜杠或反斜杠开头的路径都将评估为true.这意味着像C:no\base\dir这样的路径将评估为true.在非windows主机上,任何以波浪号(~)开头的路径都为true.
if(EXISTS /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage)
message("exists messy_usage") # print
endif()
if(EXISTS ../../Samples_Make)
message("exists samples_make") # won't print
endif()
if(/home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/test_find_package.cmake IS_NEWER_THAN /home/spring/GitHub/Linux_Code_Test/Samples_CMake/messy_usage/test_xxxx.cmake)
message("is newer") # print
endif()
if(IS_DIRECTORY /home/spring/GitHub)
message("is directory")
endif()
if(IS_SYMLINK /usr/bin/gcc) # /usr/bin/gcc -> gcc-11*
message("is symlink") # print
endif()
if(IS_ABSOLUTE ~/.bashrc)
message("is absolute") # print
endif()
5.Comparisons
- if(<variable|string> MATCHES regex):如果给定的字符串或变量的值与给定的正则表达式匹配(matches),则为true.
- if(<variable|string> LESS <variable|string>):如果给定的字符串或变量的值是有效数字且小于右侧的数字,则为true.
- if(<variable|string> GREATER <variable|string>):如果给定的字符串或变量的值是有效数字且大于右侧的数字,则为true.
- if(<variable|string> EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且等于右侧的数字,则为true.
- if(<variable|string> LESS_EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且小于或等于右侧的数字,则为true.
- if(<variable|string> GREATER_EQUAL <variable|string>):如果给定的字符串或变量的值是有效数字且大于或等于右侧的数字,则为true.
- if(<variable|string> STRLESS <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)小于右侧的字符串或变量,则为true.
- if(<variable|string> STRGREATER <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)大于右侧的字符串或变量,则为true.
- if(<variable|string> STREQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)等于右侧的字符串或变量,则为true.
- if(<variable|string> STRLESS_EQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)小于或等于右侧的字符串或变量,则为true.
-if(<variable|string> STRGREATER_EQUAL <variable|string>):如果给定的字符串或变量的值按字典顺序(lexicographically)大于或等于右侧的字符串或变量,则为true.
if("cSdN" MATCHES [A-Za-z])
message("matches") # print
endif()
set(var1 4.1)
set(var2 4.2)
if(var1 LESS var2)
message("less") # print
endif()
if(var2 GREATER var1)
message("greater") # print
endif()
if(var1 EQUAL var1)
message("equal") # print
endif()
set(var3 "abc")
set(var4 "ABC")
if(var4 STRLESS var3)
message("strless") # print
endif()
if(var4 STRLESS_EQUAL var3)
message("strelss equal") # print
endif()
if(var3 STRGREATER var4)
message("strgreater") # print
endif()
示例
1、判断两个字符串是否相等
set(NAME_1 yexindong)
# 判断2个值或字符串是否相等
if(${NAME_1} VERSION_EQUAL yexindong)
message(STATUS "yes")
endif()
打印
-- yes
2、判断文件路径是否目录
file (GLOB dirs *) # 创建变量files
# 循环
foreach(item ${dirs})
if(IS_DIRECTORY ${item}) # 判断是否目录,必须加上${} ,如果不加 ${} 就是字符串,无法判断是否目录
message(STATUS "is dir" ${item})
endif()
endforeach()
打印
-- is dir/Users/yexd/Documents/project_cpp/cpp_learn/.git
-- is dir/Users/yexd/Documents/project_cpp/cpp_learn/.idea
-- is dir/Users/yexd/Documents/project_cpp/cpp_learn/cmake-build-debug
-- is dir/Users/yexd/Documents/project_cpp/cpp_learn/lesson_17_header_file
-- is dir/Users/yexd/Documents/project_cpp/cpp_learn/lesson_20_class