【Makefile】中間ディレクトリを作成するターゲットの指定方法

2026-06-11

Makefileでオブジェクトファイルなどの中間ファイルをソースと別のディレクトリに押し込めたい派なんだけど、その際に出力先のディレクトリを生成するためのターゲットの書き方をメモ。

旧手法

今まではオブジェクトファイルを生成するルールにmkdir -p objと書いて目的ディレクトリを作成するようにしていたんだけど、これだとオブジェクトのコンパイルの度にmkdirが試みられることになり、無駄といえば無駄:

SRC_DIR:=src  # ソースファイル格納ディレクトリ
OBJ_DIR:=obj # オブジェクトファイル出力先ディレクトリ

clean:
rm -rf $(OBJ_DIR) # クリーン時にはオブジェクトディレクトリごと削除してしまう

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
mkdir -p $(OBJ_DIR) # ここで毎回mkdirを呼び出している
$(CC) $(CFLAGS) -o $@ $<

うまくいかない方法

オブジェクトファイルの依存関係に足せばできるかと書いてみる:

OBJS:=...

# ここで依存関係を指定
$(OBJS): $(OBJ_DIR)

$(OBJ_DIR):
mkdir $(OBJ_DIR)

一見普通に動くんだけど再度makeをするとobjディレクトリが更新されたと判定されてしまい、すべて再ビルドになってしまう。

新手法

mkdir -p方式で特に困ってはなかったんだけど、下記のように書けることを知った:

# これを書き換え
$(OBJS): | $(OBJ_DIR)

|と書くと「順序依存」指定となって、ディレクトリ内部やそのもののタイムスタンプが新しくなってもオブジェクトファイルは更新対象にはならず、再ビルドを防ぐことができる。

リンク