基本上,我有一个'blah.txt'文件。该文件由“编译器”解析,并从中生成N个输出.c文件。我想要一个makefile,它将从该.txt文件生成c文件,然后编译所有这些文件并将它们存档在libmystuff.a中
我想要这样的事情:
all: dogen libmystuff.a
dogen: source.txt
mycompiler $^
libmystuff.a: $(addsuffix .o, $(shell ls *.c))
$(AR) rcs $@ $^
.PHONY: dogen
但显然这不起作用,因为依赖关系是在开始时进行评估的,那时* .c只是不会产生任何东西,因为它们不存在。
有没有人知道如何实现这一目标(没有明确列出所有生成的* .c)?
答案 0 :(得分:3)
使用sentry“makefile”强制make重新读取makefile并替换*.c
处的正确列表:
include sources-sentry
sources-sentry: source.txt
mycompiler $^
touch $@
libmystuff.a: $(addsuffix .o, $(shell ls *.c))
$(AR) rcs $@ $^
include
指令用于包含其他makefile(就像C的#include
)。它具有良好的特性,如果它包含的makefile是一个目标本身,make
程序首先将其视为目标并尝试更新。如果它不是最新的,make会调用更新它所需的命令,然后重新读取makefile,再次替换所有变量。
因此,如果source.txt自您上次处理它以来已更改(时间记录为sources-sentry file 的时间戳),则将更新源并重新调用make ,*.c
被替换为c文件的更新集。
答案 1 :(得分:2)
如果您的.c文件仅由.txt生成,那么您可以让libmystuff.a依赖于txt,并在规则体中评估$(shell ls * .c)。
答案 2 :(得分:1)
Pavel Shved是对的(*),你必须重新运行Make。这是一个我很自豪的技巧。它将处理可能尚不存在的对象的依赖关系,并且不会不必要地运行。
SOURCES = $(wildcard *.c) OBJECTS = $(SOURCES:.c=.o) all: libmystuff.a ifeq ($(MAKELEVEL),0) libmystuff.a: source.txt mycompiler $^ @$(MAKE) -s $@ else libmystuff.a: $(OBJECTS) $(AR) rcs $@ $^ endif
(*)我的老对手,我们再见面。
修改:
如果某些其他打电话这个制作......我没有想到这一点。但我认为这将解决它:
SOURCES = $(wildcard *.c) OBJECTS = $(SOURCES:.c=.o) all: libmystuff.a libmystuff.a: source.txt mycompiler $^ @$(MAKE) -s phonyLib .PHONY: phonyLib phonyLib: $(OBJECTS) $(AR) rcs libmystuff.a $^
(是的,我知道,如果你想要建立一个名为“phonyLib”的文件,你将无法用这个makefile来做,但不要乖张。)