如何从命令行覆盖特定于目标的变量?

时间:2015-08-20 07:58:54

标签: makefile gnu-make

给定一个带有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的第1版: (使用目标 - 特定定义),我们有:
    all : foo += target
    x : foo += target
  • 对于 Makefile的第2版 (使用 pattern - 特定定义),我们有:
    % : foo += target

在这两种情况下,我们基本上都有相同的配置:

  1. 追加到先前值的模式/目标定义。
  2. 模式/目标定义将 应用于allx目标。
  3. 我们有一个命令行定义,假设覆盖 makefile级定义。
  4. 现在,解释或实施覆盖,Make使用一种非常不同的方法,版本 1 (目标定义)而不是版本 2 (模式定义)。

    让我们看看:

    • 对于目标定义,使完全忽略makefile中定义的任何值。因此,最终值为:cmd
    • 然而,对于模式定义,Make提出了" conciliatory"方法,试图满足两者,makefile级别定义和命令行定义,所以它:
      1. 根据覆盖makefile定义的命令行,接受最终值为cmd
      2. 但是,因为makefile意味着"模式"应该"追加"额外的价值观 - 不要介意那些相同的价值观被覆盖了 - Make仍然会遵守"服从"那些追加,但它将用不同的值(即"获胜"命令行值)完成,从而达到"妥协"其中,makefile或命令行也不能单独控制变量的最终值。

    嗯,当我们期望得到的最终结果非常不同时,Make实现命令行覆盖(每个模式与目标特定变量)的这些不同方法更加明显他们分别是:

    1. cmd(针对特定目标)。
    2. cmd cmd cmd(针对特定模式)。
    3. 这是否合理?怎么会这样?

1 个答案:

答案 0 :(得分:3)

这似乎是一个最小的完整示例:

make foo=cmd

调用cmd cmd (使用GNUMake v3.81),生成

$(foo)

这对我来说似乎是一个错误。根据the manual

  

命令行上提供的变量(如果是,则在环境中提供)   '-e'选项有效)优先于[特定于目标的变量]。

所以+ =语句应该没有效果。但显然,如果赋值是在模式规则中,则命令行值会否决规则尝试追加的,而不是追加它的行为,以便将S2: INDEX(ref_player, ref_world, timestamp) 追加到自己身上。