公式のマニュアル。
2005 年に出版されているオライリーの書籍が無料公開されています。大感謝。凝ったことをするつもりはないので、とりあえず第 3 章あたりまで読んでみました。
環境
基本的な記法
Makefile
というファイル名で、以下のシンタックスで情報を記述したファイルを作ります。
(作成ファイル): (依存関係のあるファイル) (実行するコマンド)
Makefile
の例です。
target.txt: require.txt echo "Create a target.txt." touch target.txt
実行してみます。
$ # 依存関係のファイルがない状態で実行すると怒られる $ make target.txt make: *** No rule to make target 'require.txt', needed by 'target.txt'. Stop. $ # 依存関係のファイルを用意した後に実行すると、正しくコマンドが流れる $ touch require.txt $ make target.txt echo "Create a target.txt." Create a target.txt. touch target.txt $ # もう1度実行すると、作成するファイルが最新状態のためコマンドは流れない $ make target.txt make: 'target.txt' is up to date. $ # 依存関係のファイルを再作成した後に実行すると、コマンドが流れる $ touch require.txt $ make target.txt echo "Create a target.txt." Create a target.txt. touch target.txt
@ マーク
実行するコマンドの冒頭に @
をつけると、実行コマンドが表示されなくなります。
target.txt: require.txt @echo "Create a target.txt." touch target.txt
実行すると、echo 文の表示されなくなります。
$ make target.txt
Create a target.txt.
touch target.txt
.PHONY マーク
.PHONY マーク
を利用することで、具体的なファイル名ではなく、擬似的な名前でルールを記述できるようになります。
以下は run1
と run2
という疑似ターゲットを利用している例です。 run1
や run2
といったファイルの管理が不要になります。
.PHONY: run1 run1: @echo "run1 executed." .PHONY: run2 run2: run1 @echo "run2 executed."
実行してみます。
$ make run1
run1 executed.
$ # 疑似ターゲットは常に最新でないと判断され、その依存されているファイルも含めてかならず再構築されます。
$ make run2
run1 executed.
run2 executed.
その他の特殊ターゲットたちです。
4.9 Special Built-in Target Names
make コマンドを再帰的に実行
依存関係で管理するのではなく、make コマンドを再帰的に実行したい場合の例です。
.PHONY: run3 run3: $(MAKE) run2 @echo "run3 executed."
実行してみます。
$ make run3 make run2 make[1]: Entering directory '/home/zunda/work/make' run1 executed. run2 executed. make[1]: Leaving directory '/home/zunda/work/make' run3 executed.
変数
Makefile での変数の宣言は、以下の方法があります。
種類 | 記法 | 説明 |
---|---|---|
単純展開変数 | := | Makefike を読み込んだ時に変数を評価 |
再帰展開変数(遅延評価変数) | = | 変数を利用する度に変数を評価 |
条件付き展開変数 | ?= | その変数が宣言されていない場合に評価 |
Makefile の例です。$@
は用意されている自動変数(予約変数)となり、ターゲット名の値を持っています。
VAR1 := "apple" VAR2 := "banana" VAR2 ?= "carrot" .PHONY: run4 run4: @echo "VAR1: $(VAR1)" @echo "VAR2: $(VAR2)" @echo "Automatic Variables: $(@)"
実行してみます。
$ make run4 VAR1: apple VAR2: banana Automatic Variables: run4
自動変数(予約変数)の一覧は下記です。
VPATH
デフォルトでは、Make はカレントディレクトリにあるファイルを探しに行きますが、VPATH
に Path の値をを追加することで、捜査先のディレクトリを追加することができます。
4.5 Searching Directories for Prerequisites
以下は ./subdir
という Path を追加した Makefile 例です。
VPATH := src:./subdir run5: require.txt subdir.txt @echo $(?)
実行してみます。subdir ディレクトリ下にあるファイルも見つけてくれています。
$ make run5 require.txt ./subdir/subdir.txt
シェルスクリプトの呼び出し
シェルスクリプトを呼び出してみます。
以下のコマンドライン引数と変数を扱うスクリプトを用意します。ファイル名は test1.sh
。
#!/bin/bash echo "Hello." # コマンドライン引数を表示 echo "\$1: ${1}" # 変数 VAR4 を表示 echo "VAR4: ${VAR4}"
Makefile の記述です。
VAR3 := "AAA" .PHONY: run6 run6: @export VAR4="BBB" @sh test1.sh $(VAR3) @echo "=============" @export VAR4="BBB"; \ sh test1.sh $(VAR3);
実行してみます。Makefile は、実行するコマンドを 1 行ずつ別プロセスを起動するため、同一のコマンドラインで実行するとシェルスクリプト内の変数をそのまま操作できるようになります。
$ make run6 Hello. $1: AAA BBB: ============= Hello. $1: AAA BBB: bbb
シェルスクリプトの呼び出し(read コマンド)
以下のような read コマンドを利用してシェルスクリプトも扱えます。ファイル名は test2.sh
。
#!/bin/bash read -p "Are you deploying the production environment? (Y, N): " INPUT if [ ${INPUT} = "Y" ]; then echo "true" else echo "false" fi
Makefile です。
.PHONY: run7 run7: @sh test2.sh
ちゃんと標準入力を扱ってくれます。
$ make run7 Are you deploying the production environment? (Y, N): Y true
コマンドオプション
make コマンドのオプションは man で確認できます。
ドライランの実行。
$ make run1 --dry-run echo "run1 executed."
デバックの表示。
$ make run1 --debug=v --debug=j GNU Make 4.3 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Reading makefiles... Reading makefile 'Makefile'... Updating makefiles.... Updating goal targets.... Considering target file 'run1'. File 'run1' does not exist. Finished prerequisites of target file 'run1'. Must remake target 'run1'. Putting child 0x55e543240260 (run1) PID 8363 on the chain. Live child 0x55e543240260 (run1) PID 8363 run1 executed. Reaping winning child 0x55e543240260 PID 8363 Removing child 0x55e543240260 PID 8363 from chain. Successfully remade target file 'run1'.