CMake基础篇(四)——函数

前言:
   本篇文章帮助你快速熟悉CMake函数的使用。

1 定义函数

  CMake支持函数定义,CMake的变量是区分大小写的,包括函数的传入参数,但函数名不区分大小写。
  以下定义了一个名为 FunName 的函数。

1
2
3
4
5
6
7
8
9
10
project(ProjectName)

function(FunName Param0 Param1)
message(STATUS "${Param0}")
message(STATUS "${Param1}")
# message(STATUS "${param1}") # Error.
endfunction()

FunName(5 10)
funname(1 2)

  执行结果为。

1
2
3
4
5
╰─ cmake ..
-- 5
-- 10
-- 1
-- 2

  也可以通过 cmake_language 调用函数。

1
cmake_language(CALL FunName 2 3)

2 函数参数

  先讨论实参为值的情况。CMake的函数允许传入的参数比定义的函数形参多(甚至函数定义时没有形参),仍然可以获取到这些多出来的参数值。

  • ARGC : 传入函数的参数的个数。
  • ARGV : 为所有传入的函数参数,用 ; 分隔,也可以在后面加个数字编号获取第n个传入参数,n从0开始。
  • ARGN : 为传入函数时实参比形参多处来的部分。
1
2
3
4
5
6
7
8
9
project(ProjectName)

function(FunName Param0 Param1)
message(STATUS "Numbers: ${ARGC}, Val0: ${ARGV0}, Val1: ${ARGV1}, Val2: ${ARGV2}, Val3: ${ARGV3}")
message(STATUS "All parameter: ${ARGV}")
message(STATUS "Over parameter: ${ARGN}")
endfunction()

FunName(5 10 11 12)

  输出结果为。

1
2
3
4
╰─ cmake ..
-- Numbers: 4, Val0: 5, Val1: 10, Val2: 11, Val3: 12
-- All parameter: 5;10;11;12
-- Over parameter: 11;12

  若传入函数的实参是变量而不是值。此时在函数内部访问此变量需要用两个 ${} 符号。以下是示例。

1
2
3
4
5
6
7
8
9
10
project(ProjectName)

function(FunName Param0 Param1)
message(STATUS "Param0: ${Param0} = ${${Param0}}, Param1: ${Param1}")
endfunction()

set(Var0 1)
set(Var1 2)

FunName(Var0 ${Var1})

  输出结果为。

1
2
╰─ cmake ..
-- Param0: Var0 = 1, Param1: 2

3 函数内部修改外部变量

  如果要在函数内修改一个在函数外部定义的变量,需要在 set() 函数中增加 PARENT_SCOPE 字段说明变量处于父作用域。

1
2
3
4
5
6
7
8
9
10
project(ProjectName)

set(Var0 3)

function(FunName)
set(Var0 5 PARENT_SCOPE)
endfunction()

FunName()
message(STATUS "${Var0}")

  输出结果为5。

4 函数作用域

  函数内部可以访问在函数为iabu定义的变量,只要该变量在该函数的调用位置前即可(注意,不是函数的定义位置),而函数外部不能访问函数内部定义的变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
project(ProjectName)

set(Var0 0)

function(FunName)
set(Var1 1)
message(STATUS "${Var0}")
message(STATUS "${Var1}")
message(STATUS "${Var2}")
endfunction()

set(Var2 2)

FunName()
message(STATUS "-------------")
message(STATUS "${Var0}")
message(STATUS "${Var1}")
message(STATUS "${Var2}")

  输出结果为。

1
2
3
4
5
6
7
8
╰─ cmake ..
-- 0
-- 1
-- 2
-- -------------
-- 0
--
-- 2

5 函数返回值

  CMake函数并不支持函数返回值机制,但可以用修改外部变量的方式实现。

1
2
3
4
5
6
7
8
9
project(ProjectName)

function(FunName Param0 Param1 RtnVal)
math(EXPR Sum "${Param0} + ${Param1}")
set(${RtnVal} ${Sum} PARENT_SCOPE)
endfunction()

FunName(1 2 Var)
message(STATUS "${Var}")

  输出为。

1
2
╰─ cmake ..
-- 3

  如果函数想返回多个值,可用多个 RtnVal 这样的变量,或者让这个变量带有多个值。