makeの覚書
a.out: gcc hello.c
空行には, tab, 空白などの空白文字はない。入れるとエラー。 一段下がっている行の先頭にはtabがある。
定型の操作を簡潔に表現する方法。phpファイルからhtmlファイルを作成 するとする。makefileにはphpとhtmlが拡張子であることと, 操作方法を 教える。
# htmlとphpは拡張子である。 .SUFFIXES: .html .php # .phpから.htmlを作成する。 .php.html: php $< > $@ all: index.html foo.html$<, $@は自動変数(Automatic Variables)。$<が入力で, $@が作成対象。
いくつかのファイルを一つづつ操作したいとき。たとえば, いくつかの別のディレクトリのmakefileを実行したいとき。
SUBDIR=foo bar all: list="$(SUBDIR)"; \ for i in $$list; do \ echo $$i; \ cd $$i; make; cd ..; \ done
各コマンド行の最後の"\"を抜かすと動かないので注意。最後の 行のみ不要。また, 各コマンドの最後の";"を抜かすと動かないので 注意。最後のコマンドのみ不要。なお, 当方の環境はbashで確認 しています。csh, tschで動かした場合は確認していません。
STR= all: printstr createdir # STRになにか設定されていたら表示する。 printstr: @if test "$(STR)" != ""; then \ echo "$(STR)"; \ fi # ディレクトリfooがなければfooを作成 createdir: @if [ ! -d foo ]; then \ mkdir foo; \ echo 'create dir foo'; \ fi # 本来はfooを作成のターゲットにすべき
ディレクトリ中のファイル命の取得などが可能。
objects=$(patsubst %.php, %.html, $(wildcard *.php)) no_public=foo.html index.html all: echo $(objects) echo $(wildcard *.php) echo $(wildcard *.html) echo $(filter-out $(no_public), $(objects))
patsubstrは文字を変換するための文字関数(text function)。 ... %.php, %.html ... で拡張子をphpからhtmlに変換している。
wildcardで指定された文字にマッチするファイルの取得。 $(wildcard *.php)でディレクトリ中の拡張子phpのファイルを 全て空白区切りで列挙。
filter-outは第一引数の文字(空白区切りで複数可能)を第二引数から 取り除く文字関数。objectsにfoo.html, index.htmlがあっても no_publicで指定されているので表示されない。
原則としてmakeにて実行される命令はコンソールに表示されるが, それを抑制したい場合は, 命令の先頭に@をつける。
all: @echo 'hello world'
原則としてmakeはエラーが起きたところで処理を中断する。 たとえば存在しているディレクトリを作成しようと するとエラーになる。 それを無視するには命令の先頭に"-"をつける。
all: -mkdir foo @echo 'create directory foo'
ここでは存在しているディレクトリを作成しようとしてエラーに しているが, これは例のためであって, 本来は 作成するディレクトリをターゲットにするか, 先にディレクトリの存在をチェックすべきである。
makefile
include def.mk all: echo $(DEF1)
def.mk
DEF1 = hello make
実行結果
$ make echo hello make hello make
現在は発生しないようだが, 以前makefile中でリダイレクトを使用すると Error 57というエラーが出ることがあった。その場合, makefileの先頭に
SHELL=/bin/bash
と書くと直った。makefile全体の例。
SHELL=/bin/bash all: echo 'hello' > build.log