下面是一个例子:
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
...这正是我想要的。但是,我不想使用addsuffix两次。我想在我改变先决条件的情况下使用$〈。我该如何着手做这件事呢?
2条答案
按热度按时间dffbzjpn1#
问题不在于配方中
$<
的扩展。问题在于先决条件列表中$@
的扩展。自动变量,如
$@
,只在方法中定义,而不在目标或先决条件列表中定义。这在GNU Make手册中关于自动变量的章节中有重点介绍:一个常见的错误是试图在先决条件列表中使用
$@
;这是行不通。hello.c
实际上不在先决条件列表中,这并不妨碍调用make hello
。这只是意味着make hello
将始终调用编译器,即使hello.c
没有被修改。但这确实意味着$<
将与计算出的先决条件列表一样为空。GNU make确实有一个特性让你做二次扩展的先决条件;这在手册中有解释。但是更简单的解决方案是不依赖先决条件列表中的
$@
。如果你试图创建你自己的通用C编译方法,对目标文件(.o
)目标使用模式规则。对于最终的可执行文件,列出最终可执行文件的所有先决条件(几乎肯定不止一个文件)。一般来说,这是通过使用单独的变量来完成的,变量的名字类似于
SRCS
和OBJS
(或者SOURCES
和OBJECTS
,如果你不介意键入元音字母的话)。通常你会把目标文件作为最终可执行文件的先决条件(这将是一个链接操作),因为每个单独的源文件都有自己的头文件先决条件。pbpqsu0x2#
基本问题是自动变量只在配方中定义。因此,在先决条件中,$@没有定义。因为$〈将引用依赖于$@的表达式,而$@并不存在,因此$〈也将不存在。
所以,有两种方法可以解决这个问题。第一种方法有点笨拙,但是你可以使用二次扩展。这基本上允许我们做我们想做的事情,而不需要添加太多代码...
更正确的方法是重构Makefile文件并使用模式规则。这为我们提供了构建任何C文件的通用方法。使用下面的Makefile文件,我们可以运行“make”或“make hello”来构建可执行文件。