0

Make を使用して、科学レポートの図を抽出および生成しています。宣言的であることは、データがどこにあり、どのように図に変換するかを書き留めるのに非常に便利です。私のmakefileは次のようplotsになります(メインターゲットです):

plots: some_specific_figure.png some_other_figure.png yet_another_figure.png

%.png: %.fig.py
    $(GENFIG) $<

%.fig.py: %.raw.fig.py
    cp $< $@

some_specific_figure.raw.fig.py:
    $(GETDATA) some/super/specific/simulation/results/directory/ $@

some_other_figure.raw.fig.py:
    $(GETDATA) some/different/arbitrary/simulation/directory/ $@

yet_another_figure.raw.fig.py:
    # etcetera

最終的に、抽出された生データには正しいプロット/軸/線のタイトル、軸の範囲などが含まれていないため、これらのファイル ( 、など)を手動で編集したいと思います。*.fig.pysome_specific_figure.fig.pysome_other_figure.fig.py

私が Make したいことは、

  • %.fig.raw.py存在しない場合は、データ ディレクトリから抽出します。にコピーして%.fig.py、後で編集できるようにします。
  • %.fig.pyビルド後、ファイルを保管してください。
  • ファイルで上書きせずに%.png、既存のものからビルドするだけです。存在するか編集されている場合、Make はそれをそのまま使用する必要があります。%.fig.py%.raw.fig.py%.fig.py

これを行う簡単/簡潔な方法は何ですか? マーキング.SECONDARY: %.fig.pyは上手くいきませんでし%.fig.pyた。

4

2 に答える 2

2

拡張された

私があなたの問題をよく理解していれば、存在しない場合は %.fig.py を作成し、存在する場合はそのままにしておく必要があります。

最初に、中間ファイルを削除したくない場合は、それらを貴重なものとして定義する必要があります。

.PRECIOUS: %.fig.py %.fig.raw.py

一方、それに%.fig.py依存し%.raw.fig.pyている場合は、後で編集すると再構築されます。したがって、%.fig.py依存しないようにして、処理された%.raw.fig.pyときにのみ作成し%.fig.pyます。

Makefile の例:

#!/usr/bin/make -f

.PHONY: plots clean

plots: a.png

%.png: %.fig.py
        echo +$@+ $<
        touch $@

%.fig.py: 
        echo Construct $(@:.fig.py=.fig.raw.py)
        touch $(@:.fig.py=.fig.raw.py)
        echo +$@+
        touch $@

.PRECIOUS: %.fig.py

clean:
        echo [Clean]
        rm -f *.png *.fig.py *.fig.raw.py

a.png が存在しない場合の出力:

$ ./a.mak 
echo Construct a.fig.raw.py
Construct a.fig.raw.py
touch a.fig.raw.py
echo +a.fig.py+
+a.fig.py+
touch a.fig.py
echo +a.png+ a.fig.py
+a.png+ a.fig.py
touch a.png

a.fig.raw.pyを作成し、a.fig.py最後に .png`を作成します。中間ファイルは削除されません。

a.fig.raw.py編集された場合の出力(私は使用しましtouch a.fig.raw.pyた):

$ touch a.fig.raw.py
$ ./a.mak 
make: Nothing to be done for `plots'.

a.fig.pyが編集された場合の出力:

$ touch a.fig.py; ./a.mak
echo +a.png+ a.fig.py
+a.png+ a.fig.py
touch a.png

この場合a.pngはリメイクされますが、a.fig.raw.pyまったく触れられていません。

追加した

他の興味深い質問は、makefile がディレクトリに依存するようにするにはどうすればよいかということです。たとえば、一部のファイルはディレクトリfoo1/bar1とに作成されますfoo2/bar2。新しいファイルがこのディレクトリの 1 つに書き込まれる場合、ファイルfoo<n>_bar<n>.pngが作成されます。

メイクファイルは次のとおりです。

#!/usr/bin/make -f

.PHONY: clean plots

DIRS := foo1/bar1 foo2/bar2
TARGETS := $(addsuffix .png,$(subst /,_,$(DIRS)))

plots: $(TARGETS)

# Avoid to try to remake the makefile itself
a.mak: ;
# Avoid to try to remake the dirs
$(DIRS): ;

%.png: %.fig.py
        touch "$@"

%.fig.py: %.raw.fig.py
        if [ -s "$@" ]; then touch "$@"; else cp "$<" "$@"; fi

.PRECIOUS: %.fig.py %.raw.fig.py

clean:
        echo [Clean]
        rm -f *.png *.fig.py *.fig.raw.py

.SECONDEXPANSION:
%.raw.fig.py: $$(subst _,/,%)
        echo Check dirs
        touch "$@"

テスト出力:

$ ./a.mak clean
echo [Clean]
[Clean]
rm -f *.png *.fig.py *.fig.raw.py

$ ./a.mak      
echo Check dirs
Check dirs
touch foo1_bar1.raw.fig.py
touch foo1_bar1.fig.py
touch foo1_bar1.png
echo Check dirs
Check dirs
touch foo2_bar2.raw.fig.py
touch foo2_bar2.fig.py
touch foo2_bar2.png

$ touch foo1

$ ./a.mak
make: Nothing to be done for `plots'.

$ touch foo1/bar1

$ ./a.mak
echo Check dirs
Check dirs
touch foo1_bar1.raw.fig.py
touch foo1_bar1.fig.py
touch foo1_bar1.png

$ vim foo1_bar1.fig.py

$ ./a.mak
touch "foo1_bar1.png"

$ ./a.mak
make: Nothing to be done for `plots'.
于 2013-06-18T14:05:26.143 に答える