工具使用——CMake中的函数和宏

工具使用——CMake中的函数和宏 一、CMake脚本CMake应用的过程其实可以当成一种脚本语言的应用。只不过CMake脚本相关的应用要比普通脚本更有专业的指向性。或者说其相对要简单不少。作为脚本当然要支持常见的逻辑控制、变量定义及循环操作等等功能。但最重要的当然是要支持函数和宏的功能即function()和macro()。二、函数和宏在CMake中function()和macro()和普通编程语言中的函数和宏的功能基本类似只是可能没有高级语言那么强大的应用罢了。CMake的函数和宏主要是提供逻辑复用实现封装机制模块化从而达到代码的可读性和可维护性。函数和宏既可以在CMake脚本中调用也可以像命令一样调用它们。可以这样理解函数和宏是CMake开发的重要的基础。三、分析应用对于函数和宏其特点主要包括以下几点作用域的控制函数的引入会从函数范围本身和函数参数范围内引入了相关的作用域。不过由于宏本身是一种替换所以其实际的作用域与最终生成的代码块相关参数的处理函数的参数是CMake脚本中的变量这些变量一般和CMake自身变量的功能相同。但宏的参数只是一种简单的替换不能简单的认为是哪种变量。但在最终实现的代码中则具有相同的语义参数的类别参数和宏可以使用CMake提供的自定义变量如ARGC参数数量、ARGV输入参数列表、ARGN未命名参数列表以及ARG1每一个参数,ARG2…等。它们可以实现类似于C中变参处理的效果。另外为了支持多个可选或可选参数结果CMake还提供了关键字参数。这样开发者就可以通过cmake_parse_arguments()命令来实现动态的扩展处理返回值与C中的函数不同在于CMake中的函数和宏没有返回值直接返回。但可以使用set()与PARENT_SCOPE及类似C函数中的变量作为参数的方法传递。CMake中的return()并不返回值只是将处理返回到父作用域中。但宏中的return()要与最终实际的代码位置共同决定其返回的作用域重载函数和宏可以实现命令当已经存在此命令时CMake中的函数和宏都不会产生重载而只会覆盖。注意即使是函数和宏混合使用亦是如此。但在CMake的内部机制中它支持将原有的命令增加一个下划线的前缀“_”如play_play供在以后区别使用四、函数和宏的不同虽然函数和宏在很多的表现上都非常类似但他们的区别还是不小的作用域的不同函数的作用域是显示的其作用域是独立的函数内外互不干涉而宏的作用域是隐式的对于宏本身没有作用域的说法只是在最终生成的代码块才会体现出作用域变量的实质不同函数的变量就是CMake中的变量不管是任何的类型而宏的变量只是一种类似于占位符的存在用来将替换的文本复制到指定的位置处理机制不同函数中可以通过各种操作进行处理如列表变量等而宏的变量只是一个占位的标志没有处理的意义五、示例在CMake中函数和宏的定义一般如下function(name [arg1 [arg2 [...]]]) # Function body (i.e. commands) ... endfunction() macro(name [arg1 [arg2 [...]]]) # Macro body (i.e. commands) ... endmacro()下面看一些函数和宏的基础应用#简单定义和应用 #函数 function(display) message( demo function) message(end) endfunction() # 调用: display() #宏 function(func testArg) message(testArg ${testArg}) endfunction() macro(macr_fn testArg) message(testArg ${testArg}) endmacro() #调用 func(demo) macr_fn(demo) #return macro(first) message(use first) return() # 不建议在宏内使用比较危险 message(unreached) endmacro() function(second) message(use second) first() message( is unreached ) endfunction() second() //处理返回值 # 定义 function(sum_fn n1 n2 ret_var) math(EXPR sum ${n1} ${n2}) # 使用PARENT_SCOPE将结果返回到调用者作用域 set(${ret_var} ${sum} PARENT_SCOPE) endfunction() # 变量RESULT存储结果 sum_fn(1 6 RESULT) message(STATUS 结果和: ${RESULT}) # 结果: 7 //函数覆盖 function(test) message(my test) endfunction() test() # 输出my test function(test) message(my test once) endfunction() test() # 输出my test once上面只给出一个很基础的例子更详细的可以参看CMake的官方文档。六、总结CMake中的函数和宏为开发者提供了模块化封装的机制让开发者可以更好的进行脚本的功能实现和逻辑控制。特别是在实践的中大规模项目中非常重要。