次のことを行うメイクファイル (GNU make) を作成しようとしています。
- スクリプトは一連のファイルを生成します。ファイル名は前もって知られていません。
- これらのファイルはそれぞれ別のファイルに変換されます。
- すべてが変換された後、これらのファイルはすべて 1 つの出力ファイルに結合されます。
中間のソース ファイルとターゲット ファイルが事前にわからない「ベルカーブ」パターンの依存関係グラフを含むメイクファイルを作成するにはどうすればよいですか?
概念的には、次のことを行っています。
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 が変換されていることを確認する方法はありません。
依存関係を作成してメイクファイルに含めることができることに気付きましたが、これも機能させるのに苦労しました。
.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
しかし、この規則によって「allpdfs」が作成される可能性があることを make に通知する方法はありません。