《Cmake构建实战》3 Cmake基础语法学习
[复制链接]
本帖最后由 maskmoo 于 2024-10-20 21:45 编辑
第3章主要描述Cmake的基本使用语法,结合书中的实例整理如下
CMake程序
cmake的文件类型包括CMakeList.txt文件和扩展名为.cmake的文件。其中CMakeList.txt是用于组织构建项目源文件的目录结构,.cmake文件可以作为脚本和模块两种类型。
目录(CMakeList.txt) 脚本(<script>.cmake) 模块 (<module>.cmake)
注释
主要分为单行注释和多行注释,其中多行注释本质上是单行注释+括号参数的组成形式
#单行注释
#[=[多行注释 ]=]
命令调用
message if for等
命令参数
引号参数
#包含换行
message("CMake
你好!")
#不包含换行
message("\
CMake\
您好!\
")
非引号参数
message("x;y;z") # 引号参数
message(x y z) # 多个非引号参数
message(x;y;z) # 非引号参数
变量引用
set(var_a 您好)
set(var_b a)
message(${var_${var_b}})
转义字符
cmake_minimum_required(VERSION 3.20)
set("a?b" "变量a?b")
# \? 转义为 ?
message(${a\?b})
message(今天是几号\?)
# \n 转义为换行符,\t 转义为制表符,\! 转义为 !
message(回答:\n\t今天是1号\!)
set("a;b" "变量a;b")
# 非引号参数中 \; 转义为 ;,且不分隔变量
message(x;y\;z)
# 引号参数中 \; 不转义
message("x;y\;z")
# 变量引用中 \; 转义为 ;
message("${a\;b}")
括号参数
message([==[
abc
def
]==])
message([===[abc
def
]===])
message([===[
随便写终止方括号并不会导致文本结束,
因此右边这两个括号]]也会包括在原始文本中。
下一行中最后的括号也是原始文本的一部分,
因为等号的数量与起始括号不匹配。]==]
]===])
变量
预定义变量
message("CMake命令行:${CMAKE_COMMAND}")
message("OS:${CMAKE_HOST_SYSTEM_NAME}")
定义普通变量
需要注意的是变量的作用域
function(f)
set(a "我是修改后的a")
set(b "我是b")
set(c "我是c" PARENT_SCOPE)
endfunction()
set(a "我是a")
f()
message("a: ${a}")
message("b: ${b}")
message("c: ${c}")
缓存变量
cmake_minimum_required(VERSION 3.20)
project(Notepad)
set(path_to_notepad "" CACHE FILEPATH "Path to notepad.exe")
# 下面的命令将会用记事本打开同一目录中的in.txt
execute_process(COMMAND "cmd" "/c"
${path_to_notepad} ${CMAKE_CURRENT_LIST_DIR}/in.txt)
环境变量
message("main \$ENV{PATH}: $ENV{PATH}")
列表
定义列表变量
include(print_list.cmake)
set(a "a;b;c")
set(b a;b;c)
set(c a b c)
print_list(a) # 输出:a | b | c
print_list(b) # 输出:a | b | c
print_list(c) # 输出:a | b | c
控制结构
if while foreach break continue
条件语法
常量条件
变量条件
cmake_minimum_required(VERSION 3.20)
set(on "OFF")
if(on)
message("ON")
else()
message("OFF")
endif()
if(${on})
message("ON")
else()
message("OFF")
endif()
字符串条件
if(ABC)
else()
message("ABC不是一个已定义的变量,因此条件为假")
endif()
set(a "XYZ")
set(b "0")
set(c "a-NOTFOUND")
if(a)
message("a是一个变量,其值非假值常量,因此条件为真")
endif()
if(b)
else()
message("b是一个变量,其值为假值常量,因此条件为假")
endif()
if(c)
else()
message("c是一个变量,其值为假值常量,因此条件为假")
endif()
逻辑运算
cmake_minimum_required(VERSION 3.20)
if(NOT OFF)
message("NOT OFF为真")
endif()
if(ON AND YES)
message("ON AND YES为真")
endif()
if(TRUE AND NOTFOUND)
else()
message("TRUE AND NOTFOUND为假")
endif()
if(A-NOTFOUND OR YES)
message("A-NOTFOUND OR YES为真")
endif()
单参数条件
set(a 1)
if(DEFINED a)
message("DEFINED a为真")
endif()
if(CACHE{b})
else()
message("CACHE{b}为假")
endif()
if(COMMAND set)
message("COMMAND set为真")
endif()
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/逻辑运算.cmake")
message("EXISTS \"${CMAKE_CURRENT_LIST_DIR}/逻辑运算.cmake\"为真")
endif()
双参数条件
cmake_minimum_required(VERSION 3.20)
set(a 10)
set(b "abc")
set(list 1;10;100)
if(11 GREATER a)
message("11 GREATER a为真")
endif()
if(1 LESS 2)
message("1 LESS 2为真")
endif()
if(b STRLESS "b")
message("b LESS \"b\"为真")
endif()
if(1.2.3 VERSION_LESS 1.10.1)
message("1.2.3 LESS 1.10.1为真")
endif()
if(abc MATCHES a..)
message("abc MATCHES a..为真")
endif()
if(ab MATCHES a..)
else()
message("ab MATCHES a..为假")
endif()
if(a IN_LIST list)
message("a IN_LIST list为真")
endif()
括号和条件优先级
cmake_minimum_required(VERSION 3.20)
if(NOT TRUE AND FALSE OR TRUE)
message("NOT FALSE AND TRUE OR FALSE为真")
endif()
if(NOT (TRUE AND (FALSE OR TRUE)))
else()
message("NOT FALSE AND TRUE OR FALSE为假")
endif()
变量展开
cmake_minimum_required(VERSION 3.20)
set(A FALSE)
set(B "A")
if(B)
message("B为真")
endif()
if(${B})
else()
message("\${B}为假")
endif()
while(NOT ${B})
message("NOT \${B}为真")
break()
endwhile()
命令定义
宏定义
macro(my_macro a b)
set(result "参数a: ${a}, 参数b: ${b}")
endmacro()
my_macro(x y)
message("${result}") # 输出:参数a: x, 参数b: y
MY_macro(A;B)
message("${result}") # 输出:参数a: A, 参数b: B
MY_MACRO(你 好)
message("${result}") # 输出:参数a: 你, 参数b: 好
函数定义
function(my_func a b)
set(result "参数a: ${a}, 参数b: ${b}" PARENT_SCOPE)
endfunction()
my_func(x y)
message("${result}") # 输出:参数a: x, 参数b: y
MY_func(A;B)
message("${result}") # 输出:参数a: A, 参数b: B
MY_FUNC(你 好)
message("${result}") # 输出:参数a: 你, 参数b: 好
参数访问
macro(my_macro p)
message("ARGC: ${ARGC}")
message("ARGV: ${ARGV}")
message("ARGN: ${ARGN}")
message("ARGV0: ${ARGV0}, ARGV1: ${ARGV1}")
endmacro()
function(my_func p)
message("ARGC: ${ARGC}")
message("ARGV: ${ARGV}")
message("ARGN: ${ARGN}")
message("ARGV0: ${ARGV0}, ARGV1: ${ARGV1}")
endfunction()
my_macro(x y z)
my_func(x y z)
参数的设计与解析
function(my_copy_func)
message("ARGN: ${ARGN}")
set(options OVERWRITE MOVE)
set(oneValueArgs DESTINATION)
set(multiValueArgs PATHS)
cmake_parse_arguments(
my
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
message("OVERWRITE:\t${my_OVERWRITE}")
message("MOVE:\t\t${my_MOVE}")
message("DESTINATION:\t${my_DESTINATION}")
message("PATHS: \t\t${my_PATHS}")
message("---")
endfunction()
my_copy_func(DESTINATION ".." PATHS "1.txt" "2.txt" OVERWRITE)
my_copy_func(MOVE DESTINATION "../.." PATHS "3.txt" "4.txt")
my_copy_func(DESTINATION "../folder;name" PATHS 1.txt;2.txt)
宏和函数参数的区别
macro(my_macro p)
message("-- my_macro --")
if(p)
message("p为真")
endif()
set(i 1)
message("ARGV i: ${ARGV${i}}")
endmacro()
function(my_func p)
message("-- my_func --")
if(p)
message("p为真")
endif()
set(i 1)
message("ARGV i: ${ARGV${i}}")
endfunction(my_func)
my_macro(ON x)
my_func(ON x)
|