我正在尝试创建一个执行以下操作的makefile(GNU make):
- 脚本会生成一堆文件——文件名事先不知道。
- 这些文件中的每一个都转换为不同的文件。
- 全部转换后,所有这些文件都合并为一个输出文件。
如何使用“钟形曲线”模式的依赖图创建生成文件,其中中间源文件和目标文件事先不知道?
从概念上讲,我正在执行以下操作:
combined.pdf: $(filter combined.pdf, $(wildcard *.pdf))
cat *.pdf > combined.pdf
%.pdf: %.svg
cp $^ $@
$(wildcard *.svg):
# recipe is for simple example
# actually the *.svg files are not known in advance
echo a > a.svg
echo b > b.svg
echo c > c.svg
.PHONY: clean
clean:
${RM} *.svg *.pdf *.d
当然这不起作用:Make 在运行实际创建 svg 的目标之前评估目标和源。此外,无法确保所有 svg 在合并之前都已转换。
我意识到我可以创建依赖项并将它们包含到 makefile 中,但是我也很难让它工作:
.PHONY: clean
include deps.d
combined.pdf: deps.d
cat *.pdf > combined.pdf
%.pdf: %.svg
cp $^ $@
deps.d:
@# recipe is for simple example
@# actually the *.svg files are not known in advance
echo a > a.svg
echo b > b.svg
echo c > c.svg
@# we know what files exist now, so we can establish dependencies
@# "a.pdf : a.svg"
echo *.svg : > deps.d
@# combined.pdf: a.pdf b.pdf c.pdf
ls *.svg \
| awk '{targetfn=$$0; sub(/\.svg$$/, ".pdf", targetfn); print targetfn, ":", $$0;}' \
>> deps.d
@# combined.pdf: a.pdf b.pdf c.pdf
echo combined.pdf : $$(echo *.svg | sed -e 's/\.svg/\.pdf/g') >> deps.d
clean:
${RM} *.pdf *.svg *.d
但是,这仍然没有正确连接依赖图。当我运行它时,退出如下:
Makefile:3: deps.d: No such file or directory
echo a > a.svg
echo b > b.svg
echo c > c.svg
echo *.svg : > deps.d
ls *.svg \
| awk '{targetfn=$0; sub(/\.svg$/, ".pdf", targetfn); print targetfn, ":", $0;}' \
>> deps.d
echo combined.pdf : $(echo *.svg | sed -e 's/\.svg/\.pdf/g') >> deps.d
make: Nothing to be done for `a.svg'.
我似乎仍然有 make 不知道 deps.d 中的规则的问题。
此外,这仍然不能解决构建所有依赖项的问题。我想过使用这样的标记文件:
%.pdf: %.svg
cp $^ $@
@# if all svgs are converted, touch a target allpdfs
if [ $(ls -1 *.svg | wc -l) -eq $(ls -1 *.pdf | grep -v combined\.pdf | wc -l) ]; touch allpdfs; fi
但是没有办法告诉 make 这个规则可以创建“allpdfs”。