给定一个具有目标特定
定义的 makefile:
# A target-specific definition for both: 'all' and 'x'.
all : foo += target
x : foo += target
all : x ;
x ::
@echo '$(foo)'
运行,我得到:
# override Makefile-level variables, with a command-line definition.
$ make foo=cmd
cmd
现在,与上面相同的 makefile,但具有特定于模式的
定义:
# A pattern-specific definition that matches both targets: 'all' and 'x'.
% : foo += target
all : x ;
x ::
@echo '$(foo)'
运行,我得到:
# override Makefile-level variables, with a command-line definition.
$ make foo=cmd
cmd cmd cmd
现在,两个 makefile 几乎相同,除了:
- 对于 Makefile 的版本 1:(使用目标特定定义),我们有:
所有:foo += target
x : foo += 目标
- 对于 Makefile 的第 2 版(使用模式特定定义),我们有:
% : foo += 目标
在这两种情况下,我们基本上都有相同的配置:
- 附加到先前值的模式/目标定义。
- 模式/目标定义将两者应用于
所有
和x
目标。 - 我们有一个命令行定义,可以覆盖 makefile 级定义。
现在,解释或实现该覆盖,Make 使用非常不同的方法,版本1(目标定义)与版本2(模式定义)。
让我们看看:
- 对于目标定义,Make 完全忽略 makefile 中定义的任何值。因此,最终值为:
cmd
。 - 然而,对于模式定义,Make 提出了“和解”方法,试图同时满足两者,即 makefile 级定义和命令行定义,因此它:
- 根据覆盖 makefile 定义的命令行,接受最终值为
cmd
。 - 但是,因为 makefile 暗示“模式”应该“附加”附加值——不要介意那些相同的值已被覆盖——Make 仍将“服从”这些附加值,但它会用 完成不同的值(即“获胜”命令行值),从而达到“妥协”,其中 makefile 或命令行也无法单独控制变量的最终值。
- 根据覆盖 makefile 定义的命令行,接受最终值为
好吧,当我们期望得到非常不同的最终结果时,Make 采取这些不同的方法来实现命令行覆盖(每个模式与目标特定变量),甚至更加明显他们分别是:
cmd
(针对特定目标)。cmd cmd cmd
(针对特定模式)。
这合理吗?怎么会这样?
最佳答案
这似乎是一个最小的完整示例:
%: foo += targ
x:
@echo $(foo)
调用为 make foo=cmd
(使用 GNUMake v3.81),生成
cmd cmd
这对我来说像是一个错误。根据the manual :
Variables provided on the command line (and in the environment if the ‘-e’ option is in force) will take precedence [over target-specific variables].
所以 += 语句应该没有效果。但显然,如果赋值是在模式规则中,命令行值会否决规则试图附加的值,而不是附加它的行为,因此Make 将 $(foo)
附加到自身。
关于makefile - 如何从命令行覆盖特定于目标的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32112656/