makefile 使用变量
在Makefile中,变量是一种非常重要的机制,它们允许我们存储和重用文本字符串,从而简化构建过程。变量的使用有两大特色,分别是递归调用扩展型变量和简单扩展型变量。 让我们来理解递归调用扩展型变量。这种类型的变量在定义时,其值中的其他变量引用不会立即展开,而是等到变量被引用时才会进行递归展开。例如,`foo = $(bar)`,`bar = $(ugh)`,`ugh = Huh?`。当我们尝试打印`$(foo)`时,会得到`Huh?`,因为变量的引用会逐层展开。这种方式的优点在于可以方便地组合和嵌套变量,比如`CFLAGS = $(include_dirs) -O`,其中`include_dirs`的值在扩展`CFLAGS`时被插入。然而,它的缺点在于无法安全地追加内容,如`CFLAGS = $(CFLAGS) -O`可能会导致无限递归,并且在函数和通配符的使用上存在不确定性。 为了克服这些问题,引入了简单扩展型变量。简单扩展型变量在定义时就一次性完全展开,这意味着在定义时所有变量引用和函数都会被计算。这种类型的变量使用`:=`进行定义,例如`CFLAGS := $(CFLAGS) -O`,这里的`CFLAGS`会被立即扩展,不会产生递归问题。这种方式确保了在定义时就确定了变量的值,避免了无限递归的风险,也解决了函数和通配符处理的问题,提高了性能的可预测性和效率。 在Makefile中,变量的引用可以通过两种形式表示,即`$(foo)`和`${foo}`,它们是等价的。如果变量名由一个非字母数字的字符开始,可以使用`$x`的形式进行引用,但通常应避免这样做,除非是在处理自动变量的特殊情况。 Makefile中的变量名是大小写敏感的,推荐使用小写字母作为内部变量名,而保留大写字母用于控制隐含规则和命令选项参数。此外,还有一类特殊的变量,称为自动变量,它们有预定义的用途,如`$@`表示目标文件,`$<`表示第一个依赖文件等。 在编写Makefile时,理解变量的引用和扩展特性至关重要,这能帮助我们更有效地组织构建规则,减少重复代码,提高可维护性。正确使用变量可以使Makefile更加灵活,减少错误,并且能够适应项目结构的变化。因此,掌握变量的使用是编写高效Makefile的关键步骤。