此函数向项目添加一个选项,可以包含选项介绍及默认值。
option(<OPTION_NAME> "<help_text>" [value])
进阶的。我们可以根据一些选项而额外设置其他选项值。
cmake_dependent_option(<OPTION_NAME> "<help_text>" <default_value> <depends> <force_value>)
CMAKE_DEPENDENT_OPTION(ENABLE_SAMPLE_TESTING "Enable sample test programs" ON
"ENABLE_SAMPLE_BUILD;NOT DISABLE_TESTING" OFF)
第一个参数为选项名称。
第二个参数为选项介绍。
第三个参数为默认值。
当第四个参数为TRUE时,开启此选项并自动设置第二个参数的值为默认值。否则,将强制设置该选项默认值为第五个参数值,使用者不能修改。
在此示例中,如果 ENABLE_SAMPLE_BUILD 为 ON,且 DISABLE_TESTING 为 OFF, 则自动设置 ENABLE_SAMPLE_TESTING 为 ON,且该值可以通过cmake传入来覆盖,否则 ENABLE_SAMPLE_TESTING 会被强制设置为 OFF 且无法通过cmake传入覆盖。
值得注意的是,第四个参数中可以用分号代表与的关系,也可以仅添加一个判断选项。
cmake作为一个弱类型语言,一个变量可代表多种类型,当我们设置一个变量并赋予初始值时,一般使用该函数。
set(<variable_name> <value>... [PARENT_SCOPE])
set(<variable_name> <value>... CACHE <type> <docstring> [FORCE])
set(ENV{<variable>} [<value>])
第一种:
第二种:
第三种:
cmake中使用每个变量,或者说获取变量的值有两种方式:
${SAMPLE_SOURCES}
大部分情况下我们通常使用此种方式将变量转化为值来使用。
需要注意的是,经过此种方式转化的值,会被还原为该变量类型。
如果变量是string,则最后相当于设置了一个 "abc" ;
如果变量是布尔值,则相当于 ON ;
如果是路径,则相当于 c:/windows ;
如果是list,则相当于传递了多个参数。
直接使用变量名
注意:如果使用以下代码,则相当于调用 unset 函数来解除此变量:
set(VARIABLE_ONE)
对应的,该函数是解除一个变量声明。
unset(<variable> [CACHE | PARENT_SCOPE])
unset(ENV{<variable>})
该函数专门用于字符串处理,包含正则表达式匹配功能。
string(operator ...)
常用的如下:
string(APPEND STRING_1 "world")
string(PREPEND STRING_1 "hello")
string(REPLACE "hello" "world" STRING_2 ${STRING_1})
string(LENGTH STRING_1 STRING_1_LEN)
string(SUBSTRING STRING_1 0 4 STRING_2)
string(TOUPPER STRING_1 STRING_2)
string(TOLOWER STRING_1 STRING_1)
string(FIND STRING_1 "hello" STRING_HELLO_INDEX)
正则匹配机制
此关键字声明使用正则匹配,包含几个子关键字:
MATCH 匹配一次
MATCHALL 全部匹配
REPLACE 匹配并替换字符串
经常用的如下:
^ 表示开头
$ 表示结尾
. 一个任意字符
* 多次匹配
+ 至少一次匹配
? 匹配0次或者1次
() 提取其中内容
[] 匹配其中任意字符
| 匹配两侧任意一个
\ 转义符
string(REGEX REPLACE "^(.*)world$" "HELLO" STRING_1 "${STRING_1}")
如果使用“()”,在第四个参数(替换成的字符串)中可使用 “\\<MATCH_INDEX>”的形式来直接表示其匹配到的内容,
例如 \\1 。从1开始计算index。
处理列表操作。
list(operator <LIST_NAME> ...)
几个常用的:
APPEND追加一项:
list(APPEND LIST_1 ${STRING_1})
INSTERT插入一项:
list(INSERT LIST_1 1 ${STRING_1})
REMOVE_ITEM删除指定项:
list(REMOVE_ITEM LIST_1 ${STRING_1})
REMOVE_AT删除指定位置项:
list(REMOVE_AT LIST_1 1 )
REMOVE_DUPLICATES
list(REMOVE_DUPLICATES LIST_1)
LENGTH获取列表项数:
list(LENGTH LIST_1 LIST_1_LEN)
FILTER使用正则表达式删除匹配到或未匹配到项:
list(FILTER LIST_1 "" INCLUDES REGEX "^hello world$")
TRANSFORM
子关键字有:
APPEND / PREPEND向列表中每一项 追加或头插 字符串。
list(TRANSFORM LIST_1 APPEND "hello " LIST_2)
TOLOWER / TOUPPER将列表中每一项转为全小写或全大写。
list(TRANSFORM LIST_1 TOUPPER)
STRIP删除列表中每一项开头或结尾的空格。
list(TRANSFORM LIST_1 STRIP)
REPLACE替换列表中每一项的部分内容。
list(TRANSFORM LIST_1 REPLACE "hello" "HELLO")
此项可使用正则表达式。
这些子关键字还可以附加以下规则以确定作用范围:
1.AT 从哪条开始(到哪条结束)
2.FOR 执行范围:开始-结束。
3. REGEX 正则表达式确定范围。
4. 例如:
string(TRANSFORM LIST_1 REPLACE "hello" "HELLO" REGEX "^.*world$")
判断语句在程序中不可缺少,
if (CONDITION_1)
# do something
elseif (CONDITION_2)
# do something
else()
# do something
endif()
每个条件前可加 NOT 表明取反, 条件间可加 AND 或 OR 说明 关联关系。
条件中可使用变量、字符串、数字、列表、版本号及target。以下详细说明:
变量
if (VAR_1 STREQUAL "")
...
endif()
if (DEFINED VAR_1)
...
endif()
if (VAR_1)
...
endif()
字符串
STREUQAL
if (STRING_1 STREQUAL "hello world")
...
endif()
if (NOT "${STRING_1}" STREQUAL "HELLO WORLD" AND NOT "${STRING_1}" STREQUAL "hello world")
...
endif()
这两种均可,个人建议第二种,声明了两边均为字符串。
MATCHES
if (STRING_1 MATCHES "^.*(world)$")
...
endif()
数字
LESS
GREATER
EQUAL
LESS_EQUAL
GREATER_EQUAL
if (LIST_1_COUNT LESS 5)
...
endif()
列表
if ("feature_name1" IN_LIST FEATURES)
...
endif()
版本号
VERSION_LESS
VERSION_GREATER
VERSION_EQUAL
VERSION_LESS_EQUAL
VERSION_GREATER_EQUAL
if (CURL_VERSION VERSION_LESS 3.3.1)
...
endif()
target
if (NOT TARGET CURL::curl)
...
endif()
cmake使用 foreach 作为遍历函数名称。
foreach(<loop_var> <operator> <items>)
<commands>
endforeach()
break:声明跳出遍历。
continue:直接遍历下一条。
foreach (ONE_ITEM IN LISTS LIST_1 LIST_2 LIST_3)
if (...)
break()
endif()
...
endforeach()
foreach (ONE_ITEM IN ITEMS STRING_1)
if (...)
continue()
endif()
...
endforeach()
foreach (ONE_ITEM RANGE 0 3)
...
endforeach()
当然,cmake也提供while函数,不过用的甚少(场景略少)。
while(<condition>)
<commands>
endwhile()
和 foreach 差不多用法,不过你没法在里面直接使用每一个项。所以用的很少。
我们的调试工作一般情况下全靠它了。
message([<mode>] "message text" ...)
其中mode有多种,一些常用的:
FATAL_ERROR 打印错误信息并终止整个配置流程
WARNING 打印警告信息
DEPRECATION 打印弃用信息
STATUS 打印状态信息
DEBUG 打印调试信息
空 或 NOTICE 打印普通信息。
message("hello world!")
message(WARNING "Warning!")
message(STATUS "Continue...")
message(DEBUG "string 1 is: ${STRING_1}")
message(FATAL_ERROR "Error!")