Skip to content

LV020-Makefile中的引号

我们会在 makefile 中接触到三种引号,单引号,双引号和反引号,这一节我们来总结对比一下这三种引号。

一、双引号

  • Make 层make 展开双引号内的 Make 变量(如 $(VAR))。
  • Shell 层:Shell 展开双引号内的 Shell 变量(如 $HOME${HOME}),也允许命令替换。
  • 用途:当我们希望 Make 变量和 Shell 变量都被解析时使用。

示例如下:

makefile
MY_VAR = hello

target_double:
	# 1. Make 先将 $(MY_VAR) 替换为 hello
	# 2. Shell 收到 echo "hello world",执行输出
	echo "$(MY_VAR) world"
	
	# 如果想用 Shell 变量 $HOME,必须写成 $$HOME 让 Make 转义
	echo "Home is $$HOME"

我们会得到以下打印信息:

shell
sumu@virtual-machine:~/hk/alpha$ make
# 1. Make 先将 hello 替换为 hello
# 2. Shell 收到 echo "hello world",执行输出
echo "hello world"
hello world
# 如果想用 Shell 变量 OME,必须写成 $HOME 让 Make 转义
echo "Home is $HOME"
Home is /home/sumu

二、单引号

  • Make 层make 展开单引号内的 Make 变量(注意:这点与 Shell 不同,Make 解析发生在传递给 Shell 之前)。
  • Shell 层:Shell 不会 展开单引号内的任何内容,所有字符都被视为纯文本。
  • 用途:当希望 Make 变量被替换,但防止 Shell 对其中的特殊字符(如 $, *, \)进行二次解析时使用。

示例如下:

makefile
MY_VAR = hello

target_single:
	# 1. Make 先将 $(MY_VAR) 替换为 hello
	# 2. Shell 收到 echo 'hello world',单引号保护内容,直接输出
	echo '$(MY_VAR) world'
	
	# 重点:$$HOME 传给 Shell 变成 $HOME,但在单引号内,Shell 不展开它
	# 输出 literal 字符串:$HOME
	echo 'Home is $$HOME'

我们会得到以下打印信息:

shell
sumu@virtual-machine:~/hk/alpha$ make
# 1. Make 先将 hello 替换为 hello
# 2. Shell 收到 echo 'hello world',单引号保护内容,直接输出
echo 'hello world'
hello world
# 重点:$HOME 传给 Shell 变成 OME,但在单引号内,Shell 不展开它
# 输出 literal 字符串:OME
echo 'Home is $HOME'
Home is $HOME

三、反引号

  • Make 层:在变量赋值中,反引号通常被视为普通字符(除非配合 $(shell ...))。在 recipe(命令列表)中,它被传递给 Shell。
  • Shell 层:Shell 执行反引号内的命令,并将输出结果替换到原位置(命令替换)。
  • 用途:在命令执行时动态获取 Shell 命令的结果。
  • 建议:在 Makefile 变量赋值时,推荐使用 $(shell ...) 函数代替反引号,可读性更好。

示例:

makefile
target_backtick:
	# Shell 执行 date 命令,将结果替换到 echo 中
	echo "Current time: `date`"
	
	# 推荐写法(在变量赋值阶段获取)
	# DATE_VAR = $(shell date)