Makefileのあるディレクトリの絶対パスを取得する

$(pwd)や相対パスでは、makeコマンドの実行ディレクトリが基準になってしまう。Makefileの実体があるディレクトリを基準としたいときは、以下のようにROOT_DIRを定義する。

ROOT_DIR = $(dir $(realpath $(firstword $(MAKEFILE_LIST))))

エラー時に処理を続行する

コマンドの前に-(ハイフン)をつける。

.PHONY: cmd
cmd:
 ls
 -fail_command a b c
 ls

インデントはスペースではなくタブを使う

vimrcでset expandtabしている場合にひっかかる。

以下で一時的に解除するか、vimrcでset expandtabするのをやめる、もしくはvimrcでファイル名による分岐で設定する。

:set noexpandtab

.vimrc

set expandtab

let _filename = expand('%:r')
if _filename == 'Makefile'
  set noexpandtab
endif

ファイルの存在に関係なくターゲットを実行する

Makeは本来Cのコンパイルなどに使うとき、ターゲット名に一致するファイルが存在している場合に処理をスキップするようになっている。

一方で、buildというターゲット名を使って、呼び出しのたびにコマンドを実行したいが、buildディレクトリが存在するような場合に困る。

スキップさせないようにするには、.PHONY: ターゲット名を記述する。

.PHONY: cmd
cmd:
 ls

複数のコマンドを1つのシェルで実行する

cmd:
 echo Hello;\
 VAR=World;\
 echo $$VAR
.ONESHELL: cmd
cmd:
 echo "Hello"
 VAR=World
 echo $$VAR

途中のコマンドの終了ステータスを返す

.ONESHELL: cmd
.PHONY: cmd
cmd:
 sh -c 'exit 123'
 EXIT_CODE=$$?
 echo "Exit code: $$EXIT_CODE"
 exit $$EXIT_CODE