You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Makefile中'$$directoryName'与'$(directoryName)'差异及语法疑问

Makefile变量与自动变量常见问题解析

1. $$directoryName 和 $(directoryName) 的区别

这俩核心是展开时机和主体完全不同:

  • $(directoryName) 是Make自身的变量引用,会在Make解析规则的阶段直接展开成变量对应的值。比如你定义了dir=../dir1,那$(dir)就会被Make替换成../dir1,再把替换后的完整命令传给shell执行。
  • $$directoryName 是给shell变量的转义写法。因为Make会把所有$当作自己的变量标识,如果你想让shell拿到$directoryName这个shell变量,就得用$$转义——Make处理时会把$$转换成单个$,最终传给shell的就是$directoryName,由shell来解析这个变量。

2. 为什么for循环用$$dir,简单规则用$(dir)?

咱们结合你的例子拆解看:

简单规则场景

dir = ../dir1
test: $(MAKE) -C $(dir)

这里的$(dir)是让Make直接把变量值展开,最终传给shell执行的命令是make -C ../dir1,全程不需要shell处理变量,所以直接用Make的变量引用就够了。

for循环场景

DIRS = dir1 dir2 dir3
test: for dir in $(DIRS); do \ if $(MAKE) -C $$dir ; then \ true; \ else \ exit 1; \ fi; \ done

这个规则里的命令是一段shell脚本,我们需要shell来循环处理dir这个shell变量。如果直接写$(dir),Make会先把它替换成自己的dir变量值(没定义就是空),这完全不是我们想要的——我们要的是shell循环里的$dir。所以用$$dir让Make转义,处理后传给shell的就是$dir,这样shell才能识别这是自己的循环变量,依次取dir1、dir2、dir3来执行命令。

3. 循环里的$@是什么意思?

$@是Make的自动变量,它代表当前规则的目标名。在你给的规则里:

all clean dep depend print: for dir in $(DIRS); do \ if $(MAKE) $(MAKE_FLAGS) -C $$dir $@; then \ true; \ else \ exit 1; \ fi; \ done

这是个多目标规则,目标包含all、clean、dep等。比如你执行make clean时,$@就会被Make替换成clean,最终传给每个子目录的命令就是make $(MAKE_FLAGS) -C dir1 clean、make $(MAKE_FLAGS) -C dir2 clean……这样每个子目录都会执行对应的目标,完美实现批量处理子目录的同名操作。

内容的提问来源于stack exchange,提问作者emacos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:35:08