【CMake 入门与进阶(11)】 CMake宏定义与函数(附代码)

        cmake 提供了定义宏的方法,cmake 中函数 function 和宏定义 macro 在某种程度上来说是一样的,都是创建一段有名字的代码可以在后面被调用,还可以传参数。通过 macro()命令定义宏,如下所示:

macro(<name> [arg1 [arg2 [arg3 ...]]])
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
endmacro(<name>)

        endmacro 括号中的可写可不写,如果写了,就必须和 macro 括号中的一致。参数 name 表示宏定义的名字,在宏定义中也可以使用前面给大家介绍的 ARGVX(X 是一个数字)、ARGC、ARGV、 ARGN 这些变量,所以这些也是宏定义的内部变量,如下所示:

# macro 宏定义测试
macro(XYZ arg1 arg2)
    message("ARGC: ${ARGC}")
    message("ARGV: ${ARGV}")
    message("ARGN: ${ARGN}")
    message("ARGV0: ${ARGV0}")
    message("ARGV1: ${ARGV1}")

    # 循环打印出各个参数
    set(i 0)
    foreach(loop ${ARGV})
        message("arg${i}: " ${loop})
        math(EXPR i "${i} + 1")
    endforeach()
endmacro()

# 使用宏
XYZ(A B C D E)

        源码打印信息如下:

         从定义上看他们貌似一模一样,宏和函数确实差不多,但还是有区别的,譬如,宏的参数和诸如 ARGV、 ARGC、ARGN 之类的值不是通常 CMake 意义上的变量,它们是字符串替换,就像 C 语言预处理器对宏所做的一样,因此,您将无法使用以下命令:

if(ARGV1) # ARGV1 is not a variable
if(DEFINED ARGV2) # ARGV2 is not a variable
if(ARGC GREATER 2) # ARGC is not a variable
foreach(loop_var IN LISTS ARGN) # ARGN is not a variable

        因为在宏定义中,宏的参数和诸如 ARGC、ARGV、ARGN 等这些值并不是变量,它们是字符串替换, 也就是说,当 cmake 执行宏定义时,会先将宏的参数和 ARGC、ARGV、ARGN 等这些值进行字符串替换, 然后再去执行这段宏,其实就像是 C 语言中的预处理步骤,这是与函数不同的地方。 我们来进行测试:

# macro 宏
macro(abc arg1 arg2)
    if(DEFINED ARGC)
        message(true)
    else()
        message(false)
    endif()
endmacro()

# function 函数
function(xyz arg1 arg2)
    if(DEFINED ARGC)
        message(true)
    else()
        message(false)
    endif()
endfunction()

# 调用宏
abc(A B C D)

# 调用函数
xyz(A B C D)

         上面的代码中,我们定义了一个宏 abc 和一个函数 xyz,它们俩的代码是一样的,都是在内部使用 if() 判断 ARGC 是不是一个变量,如果是打印 true,如果不是打印 false;下面会分别调用宏 abc 和函数 xyz,打 印信息如下所示:

        所以从打印信息可知,在宏定义中,ARGC 确实不是变量,其实在执行宏之前,会将 ARGC 进行替换, 如下所示:

if(DEFINED 4)
    message(true)
else()
    message(false)
endif()

        把 ARGC 替换为 4(因为我们实际传入了 4 个参数)。 当然,除此之外,cmake 中函数和宏定义还有其它的区别,譬如函数有自己的作用域、而宏定义是没有作用域的概念。

猜你喜欢

转载自blog.csdn.net/cj_lsk/article/details/131300325