シェルスクリプト代わりのmake
Makefileをシェルスクリプト代わりに使う。
基本
Makefile
hoge:
echo hoge
fuga:
echo fuga
インデントは<TAB>
で。Makefile
でもmakefile
でもOK(makefile
優先)。
$ make
echo hoge
hoge
$ make fuga
echo fuga
fuga
コマンドがエコーバックされるのが邪魔なら、make --silent
で抑止可能(短縮形は-s
)。特定のターゲットのみ黙らせたいなら、.SILENT
ターゲットに記述。
.SILENT: fuga
あるいは、コマンドごとに@
を前置。
hoge:
@echo hoge
もし、偶然hoge
ファイルが存在してたらコマンドが実行されないので、.PHONY
ターゲットを記述。
.PHONY: hoge fuga
最初のルールがデフォルトで使われるので、usageを書く。コマンドを複数行に分けるときは、行末に\
を。
all:
@echo Usage: make COMMAND
@echo -e COMMAND:\
\\n' hoge: echo hoge'\
\\n' fuga: echo fuga'
使い方を間違ったときのために、全捕捉のターゲットに何もしないコマンドを記述。
%:
@:
%
はワイルドカード。:
は「何もしない」シェルコマンド。
変数
MSG1 = hey
MSG2 ?= hey
MSG3 := ${MSG2}
msg:
@echo $(MSG1)
@echo $(MSG2)
@echo ${MSG3}
=
は変数の定義。?=
は未定義の場合のみ定義。環境変数を優先したいときに便利。
=
や?=
で定義した変数を参照すると、参照するたびに、値が再計算される。参照先で別の変数を参照してたり、関数を呼んでるときに便利。
一方、:=
で定義すると、その時点で値が確定する。
$ MSG1=hi MSG2=yo make msg
hey
yo
yo
変数を参照するときは、$()
でも${}
でも可。
if分岐
ifeq ($(FLAG),1)
MSG := ON
else
MSG := OFF
endif
関数
$(dir hoge/fuga/piyo.txt) hoge/fuga/
$(notdir hoge/fuga/piyo.txt) piyo.txt
$(wildcard *.clj) a.clj b.clj
$(shell find . -name '*.clj') ./a.clj ./b.clj ./hoge/core.clj
$(word 1,$(MAKEFILE_LIST))
イディオム
カレントディレクトリのフルパスを得る。
$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
$(abspath .)
$(shell pwd)
実例
DKIMG := kindlei
DKCON := chona
CURPATH := $(shell pwd)
WORKPATH := $(CURPATH)/books
CMD_LIST := image dev shell attach
all:
@echo Usage: make COMMAND
@echo -e COMMAND:\
\\n' image: Build the docker image.'\
\\n' dev: Start REPL.'\
\\n' shell: Start the container to kindlegen.'\
\\n' attach: Attach to the container.'
.PHONY: $(CMD_LIST)
.SILENT: $(CMD_LIST)
image:
cd docker && docker build --tag=$(DKIMG) .
dev:
clojure -Adev
shell:
mkdir -p $(WORKPATH)
docker run --rm -it \
-v $(WORKPATH):/tmp/kin \
--name $(DKCON) \
--workdir /tmp/kin \
$(DKIMG) /bin/sh
attach:
docker exec -it $(DKCON) /bin/sh
%:
@: