Makefile中$与$$的符号用法差异及适用场景咨询
嘿,这个问题问得特别到位——Makefile里的$和$$确实容易让人迷糊,我结合实际用法给你讲明白:
单个$:Makefile自身的语法符号
单个$是给Make工具自己解析用的,主要用在这两个场景:
引用变量:包括Make的预定义变量和你自己定义的变量
Make有很多预定义变量,比如$@代表当前规则的目标文件,$<代表规则里的第一个依赖文件;自定义变量比如VAR=test,可以用$(VAR)或者$VAR来引用。
举个实际例子:# 自定义变量示例 GREET = "Hi there!" say_hi: echo $(GREET) # 这里用$引用自定义变量,执行时输出Hi there! # 预定义变量示例 copy_file: source.txt cp $< $@ # $<对应source.txt,$@对应copy_file,完成复制操作调用Make函数:Make内置了很多函数,比如文件匹配、字符串替换,调用时需要用
$()包裹函数名和参数
比如$(wildcard *.c)可以匹配当前目录下所有.c文件,$(patsubst %.c,%.o,$(SRC))把所有.c文件名替换成.o:# 匹配所有C源文件 SRC_FILES = $(wildcard *.c) # 把源文件转换成目标文件 OBJ_FILES = $(patsubst %.c,%.o,$(SRC_FILES)) all: $(OBJ_FILES)
两个$$:转义后交给Shell或输出的符号
当你需要让$绕过Make的解析,直接传递给Shell或者写入目标文件时,就需要用$$来转义:
在Shell命令中引用Shell变量
因为Make会优先解析单个$,如果你的命令里需要Shell的变量(比如$HOME、循环变量$i),必须写成$$HOME、$$i,这样Make会把$$转换成单个$,再交给Shell执行。
例子:show_home: echo "你的家目录是:$$HOME" # Make处理后变成echo "你的家目录是:$HOME",Shell执行后输出实际家目录 loop_test: for num in 1 2 3; do echo "数字:$$num"; done # $$num被Make转成$num,Shell能正确遍历循环生成包含
$的文件内容
如果你的Makefile要生成脚本或其他文件,而这些文件里需要包含单个$,那在Makefile里就要写$$,这样Make不会解析它,直接把单个$写入目标文件。
例子:create_script: echo "echo 当前用户:\$$USER" > my_script.sh # 生成的my_script.sh里内容是echo 当前用户:$USER,运行脚本时能输出当前用户
简单总结:单个$是Make自己的“专属语法”,用来处理变量和函数;$$是“转义符”,告诉Make把这个符号原封不动(变成单个$)传给Shell或者写入文件。
内容的提问来源于stack exchange,提问作者Niklas Rosencrantz

