如何从命令行覆盖特定于目标的变量?
How to override a target-specific variable from the command-line?
给定一个具有 target-specific
定义的 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,但具有 pattern-specific
定义:
# 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 的 version 1:(使用 target-specific 定义),我们有:
all : foo += target
x : foo += target
- 对于 Makefile 的版本 2(使用 pattern-specific 定义),我们有:
% : foo += target
在这两种情况下,我们基本上都有 相同的 配置:
- 一个 pattern/target 定义 附加 到先前的值。
- pattern/target 定义将 应用于
all
和 x
目标。
- 我们有一个命令行定义,假设覆盖 makefile 级定义。
现在,解释或实现 override,Make 使用非常不同的方法,版本 1(目标定义)与版本 2(模式定义).
让我们看看:
- 对于目标定义,Make 完全忽略 makefile 中定义的任何 值。因此,最终值为:
cmd
.
- 然而,对于模式定义,Make 提出了 "conciliatory" 方法,试图同时满足 ,makefile 级定义和命令行定义,所以它:
- 根据覆盖 makefile 定义的命令行,接受最终值为
cmd
。
- 但是,因为 makefile 暗示 "patterns" 应该 "append" 附加值 - 不要介意那些相同的值已被覆盖 - Make 仍然会 "obey" 这些追加,但它会用 不同的 值(即 "winning" 命令行值)完成,从而达到 "compromise" 生成文件或命令行也没有完全控制变量的最终值。
好吧,Make 实现命令行 override 所采用的这些不同方法(每个模式与目标特定变量),当我们期望非常不同的时候更加明显我们为他们得到的最终结果分别是:
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)
附加到自身。
给定一个具有 target-specific
定义的 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,但具有 pattern-specific
定义:
# 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 的 version 1:(使用 target-specific 定义),我们有:
all : foo += target
x : foo += target
- 对于 Makefile 的版本 2(使用 pattern-specific 定义),我们有:
% : foo += target
在这两种情况下,我们基本上都有 相同的 配置:
- 一个 pattern/target 定义 附加 到先前的值。
- pattern/target 定义将 应用于
all
和x
目标。 - 我们有一个命令行定义,假设覆盖 makefile 级定义。
现在,解释或实现 override,Make 使用非常不同的方法,版本 1(目标定义)与版本 2(模式定义).
让我们看看:
- 对于目标定义,Make 完全忽略 makefile 中定义的任何 值。因此,最终值为:
cmd
. - 然而,对于模式定义,Make 提出了 "conciliatory" 方法,试图同时满足 ,makefile 级定义和命令行定义,所以它:
- 根据覆盖 makefile 定义的命令行,接受最终值为
cmd
。 - 但是,因为 makefile 暗示 "patterns" 应该 "append" 附加值 - 不要介意那些相同的值已被覆盖 - Make 仍然会 "obey" 这些追加,但它会用 不同的 值(即 "winning" 命令行值)完成,从而达到 "compromise" 生成文件或命令行也没有完全控制变量的最终值。
- 根据覆盖 makefile 定义的命令行,接受最终值为
好吧,Make 实现命令行 override 所采用的这些不同方法(每个模式与目标特定变量),当我们期望非常不同的时候更加明显我们为他们得到的最终结果分别是:
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)
附加到自身。