3.1 if 控制流程
if( <condition>)
<commands>
elseif( <condition>) # optional block, can be
repeated
<commands>
else() # optional block,
<commands>
endif()
if( <constant>) # 这里的条件填写常量 ,1, ON ,YES ,TRUE ,Y 或者非0数字就是真
0 ,OFF,NO, FALSE ,N, IGNORE, NOTFOUND ,空字符串,或者以suffix结尾, -NOTFOUND则为假
if(<variable>) # 这里的条件写变量 , 非假值常量为真,未定义和其他为假 。 环境变量总为假 。 宏参数不是变量
字符串的值是常量真则为真 ,其他带引号的字符串始终计算为false
#201cmake_if/CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(cmake_if)
#[[
if(<condition>)
<commands>
elseif(<condition>) # optional block, can be repeated
<commands>
else() # optional block
<commands>
endif()
]]
#[[
if(<常量>) #constant 常量
如果常量是1, ON, YES, TRUE,Y或非零数(包括浮点数),则为真True。
如果常量是0, OFF, NO, FALSE, N, IGNORE, NOTFOUND, 空字符串,或以-NOTFOUND结尾则为假False
命名布尔常量不区分大小写
]]
if(1)
message("1 is true")
endif()
if(0) #0 false
message("0 is true?")
else()
message("0 is false?")
endif()
if(OFF) #false
message("OFF is true?")
elseif(NO) #false
message("NO is true?")
else()
message("OFF NO is false!")
endif()
if() # flase
message("empty is true?")
else()
message("empty is false?")
endif()
if(-1)
message("-1 is true")
endif()
if(333)
message("333 is true")
endif()
if(0.1)
message("0.1 is true")
endif()
if(-NOTFOUND)
message("-NOTFOUND is true")
else()
message("-NOTFOUND is false")
endif()
#[[
if(<variable>)
如果给定一个定义为非假常量的值的变量,则为真否则为 False,包括变量未定义时。
宏参数不是变量。环境变量if(ENV{some_var})总是会评估为假。
]]
if(VAR_NOT_DEF) #未定义变量为false
message("VAR_NOT_DEF is true?")
else()
message("VAR_NOT_DEF is false?")
endif()
set(VAR1_TRUE TRUE)
if(VAR1_TRUE)
message("VAR1_TRUE is true!")
endif()
#[[
if(<string>)
带引号的字符串计算为 false,除非字符串的值是真正的常量之一
]]
if("TRUE")
message("string TRUE is true!")
endif()
if("ON")
message("string ON is true!")
endif()
if("test") #字符串值不是常量真都是false
else()
message("string test is false")
endif()
if("1234")
message("string 1234 is true")
endif()
#[[
逻辑运算符
if(NOT <condition>)
如果条件不为真,则为真。
if(<cond1> AND <cond2>)
如果两个条件都是真的,则为真。
if(<cond1> OR <cond2>)
如果任一条件是真的,则为真。
if((condition) AND (condition OR (condition)))
首先评估括号内的条件,然后评估其余条件。
]]
set(VAR_OFF OFF)
if(NOT VAR_OFF) #如果条件不为真,则为真。
message("NOT VAR_OFF (true)")
endif()
if(TRUE AND ON)
message("TRUE and ON is true")
endif()
if(TRUE AND OFF)
message("TRUE and OFF is true?")
else()
message("TRUE and OFF is false?")
endif()
if(TRUE OR OFF)
message("TRUE OR OFF is true?")
else()
message("TRUE OR OFF is false?")
endif()
if(TRUE AND (OFF OR ON))
message("TRUE AND (OFF OR ON) is true?")
endif()
3.6 cmake cache 缓存变量的设置
cmake -S . -B build 的时候会生成缓存变量 ,当第二次执行的时候用原来的值是不变的.
1缓存变量会被写下来存在cmake生成的一系列变量中;2 缓存变量是全局的
缓存变量基础语法和使用: set ( <variable> <value> ..... CACHE <type> <docstring >[FORCE])
CACHE覆盖策略的设置
CMAKE的内置缓存变量
-D 传递缓存变量
sub1/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(sub1)
message("in sub1 VAR_NORMAL = ${VAR_NORMAL}")
set(VAR_SUB1 "sub1 value")
message("in sub1 VAR_SUB1 = ${VAR_SUB1}")
#全局缓存变量
set(VAR_CACHE_SUB1 "VAR_CACHE_SUB1 value" CACHE STRING "sub1 doc")
message("== in sub1 VAR_CACHE_SUB1 = ${VAR_CACHE_SUB1}")
sub2/CMakeLists.txt
# 202cmake_cache/sub2/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(sub2)
message("in sub2 VAR_NORMAL = ${VAR_NORMAL}")
message("in sub2 VAR_SUB1 = ${VAR_SUB1}")
# 访问SUB1 中的全局缓存变量
message("== in sub2 VAR_CACHE_SUB1 = ${VAR_CACHE_SUB1}")
根目录的CMakeLists.txt
# 202cmake_cache/CMakeLists.txt
#[[
set(<variable> <value>... CACHE <type> <docstring> [FORCE])
type
BOOL
ON/OFF 选择框
FILEPATH
文件选择
PATH
目录选择
STRING
字符串
INTERNAL
内部变量
docstring
变量说明
FORCE
强制修改缓存,不设置第二次调用值不改
]]
cmake_minimum_required(VERSION 3.20)
project(cmake_cache)
#设置缓存变量 字符串类型
set(VAR1 "CACHE VAR1 VALUE1-1 " CACHE STRING "cache doc")
#缓存变量第二次修改不生效
set(VAR1 "CACHE VAR1 VALUE1-2 " CACHE STRING "cache doc")
message("VAR1 = ${VAR1}")
# 强制修改缓存 FORCE
set(VAR1 "CACHE VAR1 VALUE1-3 FORCE" CACHE STRING "cache doc" FORCE)
message("VAR1 = ${VAR1}")
# CACHE变量作用域是全局的
# 普通变量的作用域 自身和子模块
set(VAR_NORMAL "test normal")
message("in main")
message("VAR_NORMAL = ${VAR_NORMAL}")
add_subdirectory(sub1) #子目录会获取当前普通变量
add_subdirectory(sub2)
# 无法访问SUB1中的普通变量
message("in main VAR_SUB1 = ${VAR_SUB1}")
# 访问SUB1 中的全局缓存变量
message("== in main VAR_CACHE_SUB1 = ${VAR_CACHE_SUB1}")
#[[
BOOL
ON/OFF 选择框
FILEPATH
文件选择
PATH
目录选择
STRING
字符串
INTERNAL
内部变量
]]
#BOOl勾选
set(VAR_BOOL1 "ON" CACHE BOOL "VAR bool 001")
set(VAR_BOOL2 "OFF" CACHE BOOL "VAR bool 002")
message("-------------------------------------------")
message("VAR_BOOL1 = ${VAR_BOOL1}")
message("VAR_BOOL2 = ${VAR_BOOL2}")
#选择文件
set(VAR_FILE "filepath" CACHE FILEPATH "var FILEPATH")
#选择文件夹
set(VAR_PATH "PATH" CACHE PATH "var PATH")
#内部缓存变量
set(VAR_INTERNAL "INTERNAL" CACHE INTERNAL "var INTERNAL")
option(OPT1 "opt1 doc" OFF)
option(OPT2 "opt2 doc" ON)
#普通变量
set(NVAR1 "normal var1")
#设置缓存变量覆盖同名普通变量的策略
# OLD 删除同名普通变量
# NEW 不删除普通变量,要访问cache要用 $CACHE{var_name}
cmake_policy(SET CMP0126 NEW)
#cache变量
set(NVAR1 "cache var1" CACHE STRING "cache doc")
message("NVAR1 = \t ${NVAR1}")
message("CACHE{NVAR1} = \t $CACHE{NVAR1}") #直接查找缓存变量
message("\n\n=================")
#命令行传递缓存变量
#cmake -S . -B build -D PARA1=para001 这个命令就把 “para001” 传递给变量PARA1了
message("PARA1 = ${PARA1}")
set(BUILD_SHARED_LIBS OFF CACHE BOOL "so or a")
message("BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}")
message("\n=================")
cmake-gui 和ccmake
ccmake 是修改缓存用的
3.10 CACHE覆盖策略设置
cmake_policy( SET CMP0126 NEW) 不会删除同名的普通变量 ,另外这个CMP0126是查手册查到的
cmake_policy( SET CMP0126 OLD) 会删除同名的普通变量
3.11 传递缓存变量
3.12cmake 属性说明set_property
变量是有作用域的。
缓存变量没有作用域,但是它是个缓存,第二次设置的时候如果已经有值不会更改。
全局属性就是没有缓存的全局变量。
main.cpp
#include<iostream>
using namespace std;
int main()
{
cout<<"Test cmake property"<<endl;
cout<<"PARA1 = "<<PARA1<<endl;
return 0;
}
根目录下CMakeLists.txt
#203cmake_property/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(cmake_property)
#[[
这个是属性的语法
set_property(<GLOBAL |
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
SOURCE [<src1> ...]
[DIRECTORY <dirs> ...]
[TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
TEST [<test1> ...] |
CACHE [<entry1> ...] >
[APPEND] [APPEND_STRING]
PROPERTY <name> [<value1> ...])
get_property(<variable>
<GLOBAL |
DIRECTORY [<dir>] |
TARGET <target> |
SOURCE <source>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
TEST <test> |
CACHE <entry> |
VARIABLE >
PROPERTY <name>
[SET | DEFINED | BRIEF_DOCS | FULL_DOCS])
define_property(<GLOBAL | DIRECTORY | TARGET | SOURCE |
TEST | VARIABLE | CACHED_VARIABLE>
PROPERTY <name> [INHERITED]
[BRIEF_DOCS <brief-doc> [docs...] ]
[FULL_DOCS <full-doc> [docs...] ]
[INITIALIZE_FROM_VARIABLE <variable>])
]]
# 全局属性
#设置全局属性
set_property(GLOBAL PROPERTY TEST_GLOBAL "test global 001")
#获取全局属性
get_property(val GLOBAL PROPERTY TEST_GLOBAL)
message("TEST_GLOBAL = ${val}")
#访问子目录中的全局属性
add_subdirectory(sub1)
get_property(val GLOBAL PROPERTY SUB1_GLOBAL)
message("SUB1_GLOBAL = ${val}")
#APPEND APPEND_STRING
# APPEND 数组方式添加 TEST_APPEND = append 001;append 002;append 003
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 001")
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 002")
set_property(GLOBAL APPEND PROPERTY TEST_APPEND "append 003")
get_property(val GLOBAL PROPERTY TEST_APPEND)
message("TEST_APPEND = ${val}")
# APPEND_STRING 字符串拼接 append string 001 append string 002 append string 003
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 001 ")
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 002 ")
set_property(GLOBAL APPEND_STRING PROPERTY TEST_APPEND_STRING "append string 003 ")
get_property(val GLOBAL PROPERTY TEST_APPEND_STRING)
message("TEST_APPEND_STRING = ${val}")
#get_property SET | DEFINED
set_property(GLOBAL PROPERTY P1 "p1")
get_property(var GLOBAL PROPERTY P1)
message("P1 SET = ${var}")
if(var)
message("P1 is set")
else()
message("P1 not set")
endif()
#只有调用define_property之后才会为1
get_property(var GLOBAL PROPERTY P1 DEFINED)
message("P1 DEFINED = ${var}")
if(NOT var)
message("P1 not defined")
endif()
#定义属性 不需要赋值
define_property(GLOBAL PROPERTY TEST_DEF BRIEF_DOCS "p1 brief docs")
get_property(var GLOBAL PROPERTY TEST_DEF DEFINED )
message("TEST_DEF DEFINED = ${var}")
#获取属性概要说明BRIEF_DOCS
get_property(var GLOBAL PROPERTY TEST_DEF BRIEF_DOCS )
message("TEST_DEF BRIEF_DOCS = ${var}")
#目录属性
set_property(DIRECTORY . PROPERTY DIR1 "dir001")
get_property(var DIRECTORY . PROPERTY DIR1)
message("DIR1 = ${var}")
#拿到子目录sub1的属性
get_property(var DIRECTORY sub1 PROPERTY DIR1)
message("sub1 DIR1 = ${var}")
#文件属性
set_property(SOURCE main.cpp PROPERTY S1 "s1 value")
get_property(var SOURCE main.cpp PROPERTY S1)
message("SOURCE S1 = ${var}")
# cmake传递变量给c++
# cmake 预置属性 COMPILE_DEFINITIONS 传递预处理变量(宏变量) -DPARA1 1234
set_property(SOURCE main.cpp PROPERTY COMPILE_DEFINITIONS "PARA1=1234")
add_executable(${PROJECT_NAME} main.cpp)
sub/CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(sub1)
#全局属性
set_property(GLOBAL PROPERTY SUB1_GLOBAL "sub1 global val")
# 目录属性
set_property(DIRECTORY . PROPERTY DIR1 "sub1 dir1")