首页 > 解决方案 > Makefile 中的自动变量未正确扩展

问题描述

我正在使用以下代码:

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 两次。如果我更改了先决条件,我想使用 $<。我该怎么做呢?

标签: clinuxmakefilegnu-make

解决方案


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

自动变量,例如$@,仅在配方中定义,而不在目标或先决条件列表中定义。这在自动变量的 GNU Make 手册部分中突出显示:

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

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

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

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


推荐阅读