CMake主要语法

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")
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值