Makefile 将目标名称评估为空字符串

问题描述 投票:0回答:2

我正在尝试制作一个 makefile,而不必手动输入我的所有目标。

我有一个与该函数同名的几乎每个函数的文件,然后是另一个同名的文件,后跟“_test”,其中包含尝试使用该函数的主要方法(不是超级严格,但我不需要完整的单元测试)。

我的 Makefile 看起来像这样:

CFLAGS = -g -Wall
TARGETS = add_tag tag_known

$(TARGETS) : $(addsuffix _test.o, $@) [email protected]
   $(CC) $(CFLAGS) -o $(addsuffix _test, $@) $(addsuffix _test.o, $@) [email protected]

%.o : %.c 
   $(CC) $(CFLAGS) -c $< -o $@

clean :
   rn -f *.o $(TARGETS) $(addsuffix _test, $(TARGETS))

除了第一个目标之外,一切正常。要求 $(addsuffix _test.o, $@) 等,看起来它们只是评估空字符串,这会导致 C 编译器抛出错误。

c makefile gnu-make
2个回答
0
投票

这行不通:

$(TARGETS) : $(addsuffix _test.o, $@) [email protected]

如果您检查

$@
等自动变量的文档,您会发现它们仅在规则配方的上下文中设置。它们在配方之外没有任何价值(在本例中,在先决条件列表中)。

您可以为此使用模式规则:

% : %.o %_test.o
        $(CC) $(CFLAGS) -o $@ $^

或者,可能更好,使用静态模式规则:

$(TARGETS) : % : %.o %_test.o
        $(CC) $(CFLAGS) -o $@ $^

请注意:

-o $(addsuffix _test, $@)

总是 (*) 错误。每个配方都应该创建目标的确切名称(即

$@
)而不是其他文件。如果你的规则在于 make 关于它的作用,那么 make 会变得非常混乱。

(*) 就像任何事情一样,在极少数情况下这会很有用。


0
投票

这里的问题是自动变量(在本例中为

$@
)不能在规则的先决条件列表中使用https://www.gnu.org/software/make/manual/html_node/Automatic-Variables .html

此外,无法在规则的先决条件列表中直接访问它们。一个常见的错误是尝试在先决条件列表中使用 $@;这是行不通的。

但从好的方面来说,您可以通过多种方式解决这个问题!一种方法是“二次扩张”。如果您有兴趣,我链接的文档会更深入地介绍这一点。我个人很难理解大量使用二次扩展的 makefile,因此我会引导您进行我能想到的另一个修复,即根据

TARGETS
变量定义第一个目标的先决条件,如下所示只是工作:

$(TARGETS) : $(addsuffix _test.o, $(TARGETS)) $(addsuffix .o, $(TARGETS))
        $(CC) $(CFLAGS) -o $(addsuffix _test, $@) $(addsuffix _test.o, $@) [email protected]
© www.soinside.com 2019 - 2024. All rights reserved.