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

标签 makefile gnu-make

给定一个具有目标特定定义的 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 += 目标

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

  1. 附加到先前值的模式/目标定义。
  2. 模式/目标定义将两者应用于所有x目标。
  3. 我们有一个命令行定义,可以覆盖 makefile 级定义。

现在,解释或实现该覆盖,Make 使用非常不同的方法,版本1(目标定义)与版本2(模式定义)。

让我们看看:

  • 对于目标定义,Make 完全忽略 makefile 中定义的任何值。因此,最终值为:cmd
  • 然而,对于模式定义,Make 提出了“和解”方法,试图同时满足两者,即 makefile 级定义和命令行定义,因此它:
    1. 根据覆盖 makefile 定义的命令行,接受最终值为 cmd
    2. 但是,因为 makefile 暗示“模式”应该“附加”附加值——不要介意那些相同的值已被覆盖——Make 仍将“服从”这些附加值,但它会用 完成不同的值(即“获胜”命令行值),从而达到“妥协”,其中 makefile 或命令行也无法单独控制变量的最终值。

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

  1. cmd(针对特定目标)。
  2. 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/

相关文章:

c - 如何从对象或静态库创建共享库

makefile - 在 Makefile 变量中使用 `date`

linux - 与 GNU Make 链接时参数列表太长

c - 如何将宏定义作为参数传递给 make?

makefile - GNU 使 : Using the filter function in prerequisites

makefile - 如何从终端覆盖 makefile 中的变量

c - 内核模块 makefile 输出名称

c++ - 从 Eclipse 自动生成的依赖项中排除文件夹?

c - 如何使用 gcc -M 作为自动依赖生成器

带有假的 Makefile 通配符(静态规则?)