我在目录中有一堆.c
测试源文件tests/
。现在我想分别编译和链接它们并将可执行文件输出*.out
到tests/
. 所以我写了一个makefile,没有用。
# ...
TestDir := tests
TestSourceFile := $(shell sh -c "ls tests/*.c")
TestTargetFile := $(subst .c,.out,$(TestSourceFile))
TestFrame := testframe.o
TestNeededObjectFile := $(TestFrame) \
+ util.o \
+ tokennames.o \
+ lex.yy.o \
+ hex.o \
.PHONY: test-%
test-%: $(TestDir)/%.out
$^
.PHONY: test
test: $(TestTargetFile)
@for t in $(TestTargetFile); do \
$$t ; \
done
$(TestDir)/%.out: $(TestDir)/%.o $(TestNeededObjectFile)
gcc -o $@ $^
%.o : %.c
gcc -c $(CFLAGS) $^
clean:
rm -rf *.o lextest *.yy.? *.tab.? *.output $(TokenNameFile) \
$(TestDir)/*.out
当我运行make test-add
( add.c
is in tests/
) 时,我期待看到add.out
intests/
但出现错误:
> make test-add
make: *** No rule to make target 'tests/add.out', needed by 'test-add'. Stop.
我想知道如何正确编写这个makefile以及为什么这个makefile是错误的。
如果它们的先决条件不能直接或通过其他模式规则递归地解析为现有文件,则不会考虑 GNU make 中的模式规则[1] :
由于您的
TestNeededObjectFile
宏包含虚假+
s,并且您可能没有任何以这种方式命名的文件,这将违反$(TestDir)/%.out:
规则。[1] 根据 GNU make手册: