Makefileに関するあれこれ(2/2)
長いんでエントリわけてみた。
Makefileで使える関数とかまとめてみた。
これで全部じゃないかも。
subst/patsubst
文字列の置換
patsubstの方はパターン付き.
$(subst .c,.o,file1.c file2.c.c file3.h) # -> file1.o file2.o.o file3.h $(patsubst %.c,%.o,file1.c file2.c.c file3.h) # -> file1.o file2.c.o file3.h
substは空白をアンダーバーに、とかそういうので使えそう。
拡張子を変える、とかならpatsubstを使おう。
strip
無駄な空白等の削除。
$(strip a b c ) # -> a b c
$(if...)とかと組み合わせるといいみたい。
あまり使わない気がする。というか使ったことない...。
findstring
文字列の検索
$(findstring a,a b c) # -> a $(findstring d,a b c) # ->
見つかったらその文字、見つからなかったら空欄を返すっぽい。
filter/filter-out
マッチするもの/しないものをフィルターする。
$(filter %.c %.s,file1.c file2.s file3.h) # -> file1.c file2.s $(filter-out %.h,file1.c file2.s file3.h) # -> file1.c file2.s
そのまんま。
結構使えるかも。
sort
ソート
$(sort file3.c file1.c file2.c) # -> file1.c file2.c file3.c
word/wordlist/words/firstword/lastword
リストの要素関係の関数。
# $(word n,LIST): n番目の要素。 $(word 2,file1.c file2.c file3.c) # -> file2.c # $(word n,m,LIST): n番目からm番目の要素(リスト) $(wordlist 2,3,file1.c file2.c file3.c) # -> file2.c file3.c # $(words LIST): 要素数 $(words file1.c file2.c file3.c) # -> 3 # $(firstword LIST): 最初の要素 $(firstword file1.c file2.c file3.c) # -> file1.c # $(lastword LIST): 最後の要素 $(lastword file1.c file2.c file3.c) # -> file3.c
dir/notdir/suffix/basename/addsuffix/addprefix
ファイル名の操作とか
# ディレクトリの取得 $(dir dir/file1.ext file2.ext file3) # -> dir ./ ./ # ファイル名(ディレクトリ以外の部分)の取得 $(notdir dir/file1.ext file2.ext file3) # -> file1.ext file2.ext file3 # 拡張子の取得 $(suffix dir/file1.ext file2.ext file3) # -> .ext .ext # 拡張子を除いたもの(basenmae(1)とは挙動が違うので注意!!! $(basename dir/file1.ext file2.ext file3) # -> dir/file1 file2 file3 # suffix/prefixの追加 $(addsuffix .ext,file1 file2) # -> file1.ext file2.ext $(addprefix dir/,file1 file2) # -> dir/file1 dir/file2
basenameの挙動にすこしハマった...。
関係としては
オリジナルパス = dir + notdir = basename + suffix
って感じ。
wildcard
$(wildcard *.c) # -> hoge.c fuga.c ...
そのまんま"*.c"でもいけないこともないのだが、wildcard使って展開した方が無難。
たしかマッチするファイルの有無で挙動が分かるはず。
"*.c"だと、マッチするファイルがない場合"*.c"と言うファイルをさすことになる。
wildcardを使うと、マッチするファイルがないときには空欄(empty)になる。
realpath/abspath
相対パスを絶対パスに変換する。
realpathとabspathの違いは"./"や"../"を含まないものの処理の方法だけ...ナノカナ?
$(realpath ../hoge fuga) # -> /someplace/hoge $(abspath ../hoge fuga) # -> /someplace/hoge fuga
if/or/and
条件分岐
$(if CONDITION,THEN[,ELSE]) $(or CONDITION1[,CONDITION2[,CONDITION3...]]) $(and CONDITION1[,CONDITION2[,CONDITION3...]])
foreach
リスト全部に処理する。
$(foreach VAR,LIST,TEXT)
と書くと、LISTの全要素分TEXTが実行されて、TEXT中の$(VAR)がLISTの各要素になる。
具体例だと
DIRS=. kazuhiki mp files=$(foreach dir,$(DIRS),$(wildcard $(dir)/*))
とやると
DIRS=. kazuhiki mp files=$(wildcard ./*) $(wildcard kazuhiki/*) $(wildcard mp/*)
とやったのと同じになって、カレントディレクトリとkazuhiki,mp以下のファイルを拾ってくることができる。
origin/flavor
変数の出所(!?)を調べる。
$(origin VAR) # -> "undefined" "default" "environment" "environment override" # -> "file" "command line" "override" "automatic"のいずれか $(flavor VAR) # -> "undefined" "recursize" "simple" のいずれか
どこで宣言されたか、とかを調べるらしい。
個人的に使いそうなのは"undefined"かどうか?ぐらいな気がしないでもない...。
shell
外部プログラムを起動する
$(shell TEXT)
そのまんま。lsとか起動するとwildcard代わりになるかも。