makefile中的模式规则

时间:2016-09-21 14:39:52

标签: makefile

我有以下makefile:

CC = gcc
CFLAGS = -g -O2

ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
TEST_DIR = $(ROOT_DIR)/test

TEST_SOURCES := $(wildcard $(TEST_DIR)/*.c)
TEST_OBJECTS := $(TEST_SOURCES:.c=.o)

.PHONY: test
test: $(TEST_OBJECTS)

$(TEST_DIR)/%.o: $(TEST_DIR)/%.h
    @echo "here"

$(TEST_DIR)/%.h: $(TEST_DIR)/%.c
    java -jar ../aceunit/generator/AceUnit.jar $(basename $<) $(ROOT_DIR)/test/test_map > $@

正如您所看到的,此文件正在编译AceUnit测试文件(.c)。这样做的第一步是使用AceUnit的头生成器,如上一条规则所示。所以我试图在编译之前将头文件(.h)添加为对象(.o)文件的依赖项,但它不起作用。您看到的规则与%.o模式不匹配,而是运行make的默认构建规则。但是,如果我删除了依赖项,则匹配规则并且它会回显here。方法如下:

$(TEST_DIR)/%.o:
    @echo "here"

依赖是如何造成这种情况的?我该如何解决?我也尝试使用$($@:.o=.h)代替$(TEST_DIR)/%.h。虽然规则匹配,但$<变量似乎是空的,但我需要匹配的模式。另外,它根本没有运行最后一条规则,我从源(.c)构建了头文件(.h)。

1 个答案:

答案 0 :(得分:0)

问题在于make正在使用.o规则中的内置.c因为它比通过.h规则更快,因此它具有更高的优先级。

您可以使用%.o: %.ccancel内置规则。

此时make仍会考虑.hintermediate file,并在完成后将其删除。如果这对您没问题,那就完成了!否则,请继续阅读。

阻止删除的正确方法是将.h个文件添加到special target .SECONDARY。遗憾的是,.SECONDARY不接受模式规则,因此您必须创建所有生成标头的显式列表。 .PRECIOUS接受模式规则,但即使出现问题,它也会保留文件,这可能是您不想要的。此外,没有先决条件的.SECONDARY会将所有内容标记为辅助,如果您没有中间目标,这可能是一个可行的解决方案(不幸的是.INTERMEDIATE不会覆盖空的.SECONDARY)。

另一方面,有好消息。让.SECONDARY.INTERMEDIATE接受模式的是TODO list!我打赌它会很棒,他们一直在为17 years工作。