我的Makefile遇到了一些问题:
# Manage rendering of images
.PHONY: explode
all: explode anime.apng
out.ppm: file.code
./pgm -f $<
explode: out.ppm
split -d -a 3 --lines=$(N) --additional-suffix=.ppm $< frame
# Convert to multiple png
%.png: %.ppm
convert $< $@
optipng $@
# Assemble in one animated png
anime.apng: %.png
apngasm $@ frame000.png
我的问题是:我不知道我将有多少中间文件来生成我的最终目标,因此我无法提前指定它们。示意性地:
1 file.code -> 1 out.ppm |> LOADS of .ppm |> LOADS of .png -> 1 anime.apng
+> … +> …
+> … +> …
为此我使用隐式规则%.png: %.ppm
。但是我不能指定我上次合并步骤的先决条件!有任何想法吗?用另一种工具而不是制造?有什么优雅的吗?
答案 0 :(得分:2)
我认为一个简单而相当简洁的方法是将变量记录为ppm的“LOADS”列表,在我的例子中它是变量STEP2。 当然你可以使用让你从'1 out.ppm'到'LOADS of .ppm'的程序来列出你将获得的.ppm文件。
有一个非常简单的例子,其中out.ppm将是一个列出要生成的.ppm名称的文本文件,你可以这样写:
SOURCE = file.code
STEP1 = out.ppm
STEP2 = $(shell cat $(STEP1))
STEP3 = $(STEP2:%.ppm=%.png)
TARGET = anime.apng
然后,您需要编写规则以从文件$(STEP1)获取STEP2中列出的所有文件。这是逐个文件完成的,就好像它是一个带有%模式的隐式规则,假设你的程序被称为'extractor':
$(STEP2): $(STEP1)
extractor $^ $@
对于STEP2中列出的每个文件,此规则将应用一次。这假设您的程序只需要源文件和输出文件的名称。如果您希望传递输出文件的主干,您仍然可以使用普通的'隐式规则:
$(STEP2):%.ppm: $(STEP1)
extractor $^ $*
($(STEP2):在开始时是为了防止make使用此规则生成out.ppm)
然后,在编译时,一切都和往常一样,您可以调整规则来编译和链接任何C项目。 %.ppm - &gt; %.png步骤就像将%.c编译为%.o:
%.png: %.ppm
convert $< $@
optipng $@
最后对所有内容进行分组(相当于将几个%.o链接到一个二进制文件中):
$(TARGET): $(STEP3)
apngasm $@ $^
我在这里假设apngasm可以将所有内容的列表放在一起作为参数àla tar。
希望它足够明确和有用。
答案 1 :(得分:0)
临时解决方法是从a close question获取灵感,并使用子制作调用在子文件夹中渲染图像。类似的东西:
<强>生成文件强>:
# Manage rendering of images
.PHONY: explode
all: explode anime.apng
out.ppm: file.code
./pgm -f $<
explode: out.ppm
split -d -a 3 --lines=$(N) --additional-suffix=.ppm $< subfolder/frame
ppm2png: explode
$(MAKE) -C subfolder
# Assemble in one animated png
anime.apng: ppm2png
apngasm $@ subfolder/frame000.png
<强>温度/生成文件强>:
SOURCES := $(wildcard *.ppm)
OUTPUTS = $(patsub %.ppm,%.png,%(SOURCES))
.PHONY: all
all: $(OUTPUTS)
# Convert to multiple png
%.png: %.ppm
convert $< $@
optipng $@
我确信可以做得更好。使用另一种工具而不是制作?