Makefile问答之05 预定义变量与等号运算符

请列出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 在处理变量时更为灵活,可以适应不同的需求和场景。

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值