【问题标题】:Automatic variable not expanding properly in MakefileMakefile 中的自动变量未正确扩展
【发布时间】:2019-05-09 17:50:59
【问题描述】:

我正在使用以下代码:

HELLO_WORLD=hello

$(HELLO_WORLD): $(addsuffix .c,$@)
        gcc $< -o $@

但是,当我运行代码时,我收到以下错误,暗示 $

gcc  -o hello
gcc: fatal error: no input files

当我使用以下代码时...

HELLO_WORLD=hello

$(HELLO_WORLD): $(addsuffix .c,$@)
        gcc $(addsuffix .c,$@) -o $@

...Makefile 评估为以下命令...

gcc hello.c -o hello

...这正是我想要的。但是,我不想使用 adduffix 两次。如果我更改了先决条件,我想使用 $

【问题讨论】:

  • 请阅读this。尤其是第三段。
  • 啊,所以如果我理解正确的话,自动变量只在配方中定义。因此,在先决条件中,未定义 $@。因为 $
  • 是的。下面的答案正在解释它。
  • 完美!谢谢!

标签: c linux makefile gnu-make


【解决方案1】:

问题不在于配方中 $&lt; 的扩展。问题在于先决条件列表中$@ 的扩展。

自动变量,例如$@,仅在配方中定义,而不在目标或先决条件列表中定义。这在GNU Make manual section on automatic variables 中突出显示:

一个常见的错误是尝试在先决条件列表中使用$@;这行不通。

hello.c 实际上不在先决条件列表中这一事实并不妨碍您调用make hello。这只是意味着make hello 将始终调用编译器,即使hello.c 没有被修改。但这确实意味着$&lt; 将与计算的先决条件列表一样为空。

GNU make 确实有一个功能可以让您对先决条件进行第二次扩展;这在手册中有说明。但更简单的解决方案是根本不依赖先决条件列表中的$@。如果您尝试创建自己的通用 C 编译配方,请为目标文件 (.o) 目标使用模式规则。对于最终的可执行文件,列出最终可执行文件的所有先决条件(几乎可以肯定不止一个文件)。

通常这是使用名称为SRCSOBJS(或SOURCESOBJECTS,如果您不介意输入元音)的单独变量来完成的。通常,您将目标文件作为最终可执行文件的先决条件(这将是一个链接操作),因为每个单独的源文件都有自己的头文件先决条件。

【讨论】:

  • 看起来如果您在 $(HELLO_WORLD) 目标上方添加“SECONDARYEXPANSION:”,并在它起作用的先决条件中使用 $$@ 而不是 $@。这种使模式规则更受欢迎的方法有什么问题吗?
  • 是的,@RomanParise:它是一个不可移植的 GNUism,尽管我猜你已经在这条路上很好了。它也更难阅读,对那些不熟悉它的人来说有些惊讶。更常见的方法是为源列表创建一个单独的变量。当您有多个来源为二进制文件做出贡献时,这尤其有意义。
  • 好吧,我会写一个全面的答案。 +1!谢谢!
  • “一个常见的错误......” - 如果用户长期遭受同样的问题,那么 Make 中存在可用性错误。几十年来,当该工具应该更新以解决可用性问题时,用户被要求改变他们的行为是荒谬的。问题尚未解决指向工程问题:允许开发人员驱动需求。结局总是很糟糕。
  • @jww:有道理,但我认为你应该把它指向参与 GNU Make 开发的人。没有理由相信该集合中的任何人都会阅读此评论线程,即使他们这样做了,这也不适合他们做出回应。我相信 GNU make 的邮件列表仍然有效。
【解决方案2】:

根本问题是自动变量只在配方中定义。因此,在先决条件中,未定义 $@。因为 $

因此,确实有两种方法可以解决此问题。第一种方法有点笨拙,但您可以使用二次扩展。这基本上允许我们做我们想做的事,而无需添加太多代码......

HELLO_WORLD=hello

SECONDARYEXPANSION:
$(HELLO_WORLD): $(addsuffix .c,$$@)
        gcc $< -o $@

更合适的方法是重构 Makefile 和使用模式规则。这为我们提供了构建任何 C 文件的通用方法。使用以下 Makefile,我们可以运行“make”或“make hello”来构建可执行文件。

HELLO_WORLD=hello

all:
        $(MAKE) $(HELLO_WORLD)

%: %.c
        gcc $< -o $@

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多