使用大量中间文件制作工作流程

时间:2013-02-08 15:05:23

标签: makefile implicit rule

我的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。但是我不能指定我上次合并步骤的先决条件!有任何想法吗?用另一种工具而不是制造?有什么优雅的吗?

2 个答案:

答案 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 $@

我确信可以做得更好。使用另一种工具而不是制作?