GNU Make 触ってみる

GNU Make、いわゆる make コマンドを叩くアレ。2019年になって初めて使い方を学習してみる。

目次

Make って何

make は、プログラムのビルド作業を自動化するためのツール。make 自体にビルド機能やコンパイラが搭載されているワケではなく、ファイルの依存関係を解決して、ビルド用コマンドを呼び出してくれるツール。Java でいう Apache Ant とか、Ruby における Rake なんかが近い存在。C 言語のビルドによく使われるが、C 言語に限らず使える。

make の実装にはいくつか種類があり、MacOS Mojave や Linux に搭載されているのは GNU Make と呼ばれるモノ ($ make --version と叩くと GNU Make 3.81 などと表示されるはず。gmake)。Windows に搭載されているのは nmake という別のモノ。いずれにおいても、「シェルスクリプトをそのまま実行できるモノ」ではないことは覚えておきたい (make 独自の記法がある)。

Make の基本ルール

makefile を書く前に押さえておきたい基本ルールは以下のとおり。

とりあえずココまでのルールを頭に入れて、サンプルの makefile を見てもらおう。

makefile を実装してみた

サンプルの makefile を以下に掲載。

# makefile

# 引数を指定しない場合に実行されるタスク
.PHONY: help
help:
  # コマンドを出力しないようにするには、コマンドの手前に `@` を指定する
   @echo 'Help.'

# make は、ターゲット名と同じ名前のファイルが存在すると、そのターゲットを実行しない仕組みになっている (更新日時をチェックしている)
# 以下の install タスクの場合、`install` というファイルが存在すると、`$ make install` コマンドが動作しなくなる
# コレにより、再ビルドする際に余計なタスクが動作しないように作られている
install:
  # 以下は @ を付けていないので、コマンド自体が標準出力に表示される
  echo 'Install'

# ファイルを生成しないタスクの場合は、以下のように `.PHONY: 【ターゲット名】` という行を書いておく
# こうすると、`build` というファイルが存在しても、そのタスクが実行されるようになる
# コレを Phony Target と呼ぶ
.PHONY: build
build:
   @echo 'Build'

# 依存関係を記すための例
.PHONY: before-test
before-test:
   @echo 'Before Test'

# ターゲット名の後ろにターゲット名を書くことで依存関係を示せる
# 以下の `test` タスクは、`before-test` タスクを先に実行してから実行される
.PHONY: test
test: before-test
   @echo 'Test'

# 別ディレクトリの `makefile` を実行するには `cd` すれば良い
# 行を別けて書くと、カレントディレクトリは元に戻る
.PHONY: call-sub
call-sub:
   @echo "Let's Call Sub!"
   @cd ./sub/ && make && pwd  # 移動した先のディレクトリパスが表示される
   @pwd  # 呼び出し元のディレクトリパスが表示される

以上

こんな感じ。Make 特有の「マクロ」などの説明は省略したが、それでも Make の可能性が伝わったかと思う。

参考文献