来自docs:
-n
,-t
和-q
选项不会影响配方行 以+
字符开头或包含字符串$(MAKE)
或${MAKE}
。 请注意,只有包含+
字符或字符串的行 无论这些选项如何,都会运行$(MAKE)
或${MAKE}
。其他线路 除非它们也以+
开头或包含,否则不会运行同一规则$(MAKE)
或${MAKE}
。
现在,给定一个makefile:
# 'test -f foo' is "false".
$(shell rm -rf foo)
# 'test -f bar' is "true".
$(shell rm -rf bar; touch bar)
# 'test -f bar' will be executed, even for -[tnq] command-line options. NOT SO, for 'test -f foo'.
define cmd
test -f 'foo'
+test -f 'bar'
endef
1 2 ::
$(cmd)
正在运行,我们得到:
$ make --just-print 1
test -f 'foo'
test -f 'bar'
#####################
$ make --just-print 2
test -f 'foo'
test -f 'bar'
#####################
$ make --just-print 1 2
test -f 'foo'
test -f 'bar'
test -f 'foo'
makefile:14: recipe for target '2' failed
make: *** [2] Error 1
#####################
$ make --just-print 2 1
test -f 'foo'
test -f 'bar'
test -f 'foo'
makefile:14: recipe for target '1' failed
make: *** [1] Error 1
显然,我们有4个案例:
make --just-print 1
test -f foo
,显然是“假”命令,成功。这是因为--just-print
命令行选项,所以Make并没有真正“运行”它。这只是一个 echo 。test -f bar
,由于+
前缀,实际运行的命令。但鉴于这个配方是一个“真正的”命令,它成功并不奇怪。make --just-print 2
2
与1
),但执行的配方是100%相同< / strong>即可。这包括他们成功背后的“逻辑”,在case 1
中解释。make --just-print 1 2
case 1
开始,出于同样的原因,两者都有:test -f foo
和test -f bar
成功。2
的配方,会发生致命错误。为什么?make --just-print 2 1
case 3
相同,但2
和1
目标在这里扮演的是“相反”的角色。也就是说,2
的执行成功(按照case 2
),但在目标1
上失败。
现在,毫无疑问,这里出了点问题。
在test -f foo
模式下执行时,--just-print
的Make永远不会失败。
简单地说,因为不允许Make执行命令。它应该只是回应它!
那么,这里有什么问题?
答案 0 :(得分:0)
它与多行变量的扩展有关,其中包含+
的内容在一行而不是其他行。如果使用普通内容而不是多行变量编写规则,则它适用于所有情况:
1 2 ::
test -f 'foo'
+test -f 'bar'
您应该提交有关此特殊情况的错误。包含多行的变量很棘手,因为它们在首次被make解析时只显示为一行,但在执行时会扩展为多行。