目的
Makefileでプログラムをコンパイルする方法はよく解説されているが,データ処理のタスクランナーにも使いたい場合の資料は少ないので例示したい.良い処理や書きかたをさらに思いついたら加筆の予定.
単数のデータ => 単数のデータ
exe.x
に00000を渡すとdirA/dataA00000.dat
を読み込んで,
dirB/dataB00000.png
が出力されるような場合,以下のように書けば良い.
dirB/dataB%.png: dirA/dataA%.dat exe.x
exe.x $*
つまりソースとターゲットの共通部分の文字列を%としておいて,コマンドでその共通部分を参照したいときには$*を使う.
複数のデータ=>複数のデータ
では,dataBを全部作りたい時にはどうするのか?
DATAA = $(shell ls dirA/dataA*.dat)
DATAB = $(patsubst dirA/dataA%.dat,dirB/dataB%.png,$(DATAA))
all: ${DATAB}
dirB/dataB%.png: dirA/dataA%.dat exe.x
exe.x $*
これはまずls
と*
をつかってdataA
を全部まとめたものをDATAA
という変数にいれる.
そのDATAA
からできるファイルはpatsubst
をつかって変換して全部まとめたものをDATAB
という変数にいれる.あとは適当にDATAB
をソースやターゲットとして設定すればよい.
複数のデータ=>単数のデータ
ffmpegとかで複数のpngファイルからmp4のファイルを作りたいような場合.
DATAA = $(shell ls dirA/dataA*.dat)
DATAB = $(patsubst dirA/dataA%.dat,dirB/dataB%.png,$(DATAA))
dirC/dataC%.mp4: ${DATAB} makemovie.sh
makemovie.sh
データが存在するかどうかで処理を変える
以下の例ではbindata/unf00001.dat
がある場合とない場合で処理を変えている。期待されているファイルが一つでもある場合はls
を使って処理されるべきファイルを設定しするが、もしそのファイルがない場合はそのファイルを作ろうとする。
filename = bindata/unf00001.dat
fileexists = $(shell ls | grep ${filename})
ifeq (${fileexists}, ${filename})
BIN= $(shell ls bindata/unf*.dat)
else
BIN= ${filename}
endif
VOR = $(patsubst bindata/unf%.dat,output/vor%.dat,$(BIN))
VORPNG= $(patsubst output/vor%.dat,figures/vor%.png,$(VOR))
よく使う変数
よく使う変数についてもメモしておく。
FC=ifort -extend-source
FLAG1= -g -traceback -O2
program.x: code.F
${FC} ${FLAG} $? -o $@
$@
はターゲット。つまり:
の左のファイル。
$?
は筆頭の依存ファイル。つまり:
の右のファイル。
よく使うオプション
よく使うオプションについてもメモしておく。
>make --debug