Makefileでよく使うパターンを検証しました。
検証用のファイルは、下記の通りです。
ソースがtest1ディレクトリの*.txt
でtest2ディレクトリの*.obj
がターゲットファイルという想定です。
できるだけ、Makefileがシンプルになるように工夫してみました。
$ tree ./test? ./test1 ├── a.txt └── b.txt ./test2 └── a.obj 0 directories, 3 files $
ワイルドカード
ワイルドカードで指定したファイルに対して操作をする場合、$(wildcard)
を使います。
$(wildcard 正規表現)
でソースファイルのリストを作ることができます。そのリストに対して$(SRC:.txt=.obj)
でソースファイルの拡張子を変更したリストを作ることができます。
$ cat Makefile SRC=$(wildcard test1/*.txt) OBJ=$(SRC:.txt=.obj) all: @echo src=$(SRC) @echo obj=$(OBJ) $ make src=test1/a.txt test1/b.txt obj=test1/a.obj test1/b.obj $
ルールの追加
*.txt
から*.obj
を作るためのルールを追加します。
$ cat Makefile SRC=$(wildcard test1/*.txt) OBJ=$(SRC:.txt=.obj) all: $(OBJ) %.obj: %.txt @echo compile src=$< obj=$@ $ make compile src=test1/a.txt obj=test1/a.obj compile src=test1/b.txt obj=test1/b.obj $
ターゲットファイルのディレクトリを変更
ソースがtest1ディレクトリ、ターゲットがtest2ディレクトリで拡張子のルールを使う場合、下記のようにターゲットをtest1ディレクトリに作成してtest2にコピーしました。
コピー先のファイル名を$(addprefix ./test2/, $(notdir $@))
でディレクトリ部分のみ変更しています。
$ cat Makefile SRC=$(wildcard test1/*.txt) OBJ=$(SRC:.txt=.obj) all: $(OBJ) %.obj: %.txt @echo compile src=$< obj=$@ @echo cp -p $@ $(addprefix ./test2/, $(notdir $@)) $ make compile src=test1/a.txt obj=test1/a.obj cp -p test1/a.obj ./test2/a.obj compile src=test1/b.txt obj=test1/b.obj cp -p test1/b.obj ./test2/b.obj $
仕上げ
echo
を実際のコマンドに置き換えて動作をチェックします。
clean
ターゲットも追加して動作を確認します。
$ cat Makefile SRC=$(wildcard test1/*.txt) OBJ=$(SRC:.txt=.obj) all: $(OBJ) %.obj: %.txt @echo compile src=$< obj=$@ touch $@ cp -p $@ $(addprefix ./test2/, $(notdir $@)) clean: -@rm -rf $(OBJ) $ make -n echo compile src=test1/a.txt obj=test1/a.obj touch test1/a.obj cp -p test1/a.obj ./test2/a.obj echo compile src=test1/b.txt obj=test1/b.obj touch test1/b.obj cp -p test1/b.obj ./test2/b.obj $ make compile src=test1/a.txt obj=test1/a.obj touch test1/a.obj cp -p test1/a.obj ./test2/a.obj compile src=test1/b.txt obj=test1/b.obj touch test1/b.obj cp -p test1/b.obj ./test2/b.obj $ make make: Nothing to be done for 'all'. $ make clean $ make compile src=test1/a.txt obj=test1/a.obj touch test1/a.obj cp -p test1/a.obj ./test2/a.obj compile src=test1/b.txt obj=test1/b.obj touch test1/b.obj cp -p test1/b.obj ./test2/b.obj $
本当は、ターゲットのtest2/*.obj
とtest1/*.txt
のタイムスタンプを比較して、test1/*.txt
から直接test2/*.obj
を作りたです。