LoginSignup
0
0

More than 1 year has passed since last update.

Makefileで多数のファイルを処理する

Last updated at Posted at 2020-08-25

目的

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

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0