请列出Makefile预定义变量名,比如 $*,说明它们的用途并举例
在 Makefile 中,预定义变量(自动变量)用于在规则中引用目标文件、源文件、目录等信息。以下是一些常用的 Makefile 自动变量及其用途,以及相应的示例。
常用自动变量
- $@:表示规则的目标文件名(完整路径)。
示例:
target: source.c - gcc -o $@ $<
- 在这个例子中,如果目标是 target,则 $@ 将被替换为 target,所以命令行将变为 gcc -o target source.c。
- $<:表示规则中的第一个依赖文件。
示例:
target.o: source.c - gcc -c $< -o $@
- 在这个例子中,$< 表示 source.c,因此命令行将变为 gcc -c source.c -o target.o。
- $^:表示规则中的所有依赖文件(去重),以空格分隔。
示例:
target: file1.o file2.o - gcc -o $@ $^
- 在这个例子中,$^ 将被替换为 file1.o file2.o,因此命令行将变为 gcc -o target file1.o file2.o。
- $+:表示规则中的所有依赖文件(不去重),以空格分隔。这个变量在某些情况下比 $^ 更精确,特别是当依赖文件可能重复时。
示例:
target: file1.o file2.o file1.o - gcc -o $@ $+
在这个例子中,$+ 将被替换为 file1.o file2.o file1.o,因此命令行将变为 gcc -o target file1.o file2.o file1.o。- $*:表示规则中的目标文件名的基础部分(去掉扩展名)。只在模式规则中有效。
示例:
%.o: %.c - gcc -c $< -o $@
如果规则应用于 source.c,$* 将被替换为 source(不包括 .c),但在这个例子中 $* 并没有直接用到。- $(@D):表示目标文件的目录部分,不包括文件名。
示例:
target_dir/%.o: src/%.c - mkdir -p $(@D)
- gcc -c $< -o $@
- 在这个例子中,如果目标是 target_dir/target.o,$(@D) 将被替换为 target_dir,命令 mkdir -p $(@D) 将创建 target_dir 目录。
- $(@F):表示目标文件的文件名部分,不包括目录。
示例:
target/%.o: src/%.c - gcc -c $< -o $@
- echo "Building $(@F)"
- 在这个例子中,如果目标是 target/target.o,$(@F) 将被替换为 target.o,命令 echo "Building $(@F)" 将输出 Building target.o。
- $(@D):表示目标文件的目录部分(和 $(@D) 作用相同)。
使用示例
# 编译器
CC = gcc
# 编译选项
CFLAGS = -Wall -Wextra -Wpedantic
# 目标
all: program
# 链接目标
program: main.o utils.o
$(CC) -o $@ $^
# 编译目标
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# 清理
clean:
rm -f program *.o
在这个示例中:
- $(CC) -o $@ $^:$@ 被替换为 program,$^ 被替换为 main.o utils.o。
- $(CC) $(CFLAGS) -c $< -o $@:$< 被替换为 %.c 文件,$@ 被替换为 %.o 文件。
通过合理使用这些自动变量,你可以编写更加灵活和通用的 Makefile,提高构建过程的效率和可维护性。
Makefile等号类运算符有哪些,请举例说明
在 Makefile 中,等号类运算符用于定义和处理变量。以下是常用的等号类运算符及其用途说明,并附带示例。
常用等号类运算符
- =:简单赋值。每次引用该变量时,它的值都会被重新计算。
示例:
VAR = value - all:
- echo $(VAR)
- 在这个例子中,VAR 被赋值为 value,在 make 执行时会输出 value。
- :=:立即赋值。赋值时会立即计算变量的值,并且后续对该变量的引用不会重新计算。
示例:
VAR := $(shell date) - all:
- echo $(VAR)
在这个例子中,VAR 的值是在 Makefile 解析时被计算并固定为当前日期。$(VAR) 会输出 Makefile 被解析时的日期。- ?=:条件赋值。仅当变量未定义时才赋值。
示例:
VAR ?= default_value - all:
- echo $(VAR)
- 如果 VAR 已经被定义,VAR ?= default_value 不会重新赋值。只有在 VAR 未定义时,它才会被赋值为 default_value。
- +=:追加赋值。将新的值追加到现有值后面。
示例:
VAR = initial_value - VAR += additional_value
- all:
- echo $(VAR)
在这个例子中,VAR 的最终值将是 initial_value additional_value。+= 运算符在现有值后追加内容。- = 和 := 的差异:
- = 会延迟计算变量的值,直到实际使用时才计算。
- := 立即计算变量的值,并且在定义后不再重新计算。
- 示例对比:
- VAR1 = $(shell date)
- VAR2 := $(shell date)
- all:
- echo "VAR1: $(VAR1)"
- echo "VAR2: $(VAR2)"
如果在 make 执行时,系统时间发生变化,VAR1 的值可能不同于 VAR2。VAR1 会在每次使用时重新计算,而 VAR2 只在定义时计算一次。- define:用于定义多行变量。这种定义方式支持多行文本。
示例:
define MULTILINE_VAR - This is the first line.
- This is the second line.
- This is the third line.
- endef
- all:
- echo "$(MULTILINE_VAR)"
- 在这个例子中,MULTILINE_VAR 被定义为一个多行字符串,在 make 执行时,echo "$(MULTILINE_VAR)" 会输出定义的多行文本。
总结
- =:简单赋值,每次引用时计算。
- :=:立即赋值,计算一次后固定值。
- ?=:条件赋值,仅当变量未定义时才赋值。
- +=:追加赋值,将新值添加到现有值后面。
- define:定义多行变量,适用于复杂文本的处理。
这些运算符使得 Makefile 在处理变量时更为灵活,可以适应不同的需求和场景。