再帰的に make を呼び出す構成では、「トップレベルの make が完了したとき」や「各階層の make が完了したとき」に特定の処理を実行したい場面があります。GNU Make の MAKELEVEL 変数を使うと、現在の再帰呼び出しの深さを判定できます。
MAKELEVEL は GNU Make が自動的に設定する変数で、再帰呼び出しの深さを示します。
012起点の make が完了したときにだけ実行したい処理は、MAKELEVEL が 0 かどうかで判定します。
.PHONY: all
all: subdirs local-build
ifeq ($(MAKELEVEL),0)
@echo "===== トップレベルの make が完了しました ====="
@echo "すべてのビルドが正常に終了"
endif
.PHONY: subdirs
subdirs:
$(MAKE) -C subdir1
$(MAKE) -C subdir2
.PHONY: local-build
local-build:
@echo "ローカルビルド処理"この例では、サブディレクトリの make が完了し、ローカルビルドも終わった後で、トップレベルの場合のみ完了メッセージを表示します。
各階層の make が終わったときに、その階層の情報を含めて処理を実行する例です。
.PHONY: all
all: subdirs local-build
@echo "[MAKELEVEL=$(MAKELEVEL)] この階層の処理が完了: $(CURDIR)"
.PHONY: subdirs
subdirs:
@for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir || exit 1; \
done
.PHONY: local-build
local-build:
@echo "[MAKELEVEL=$(MAKELEVEL)] ローカルビルド実行中"トップレベルでのみビルド結果のサマリを表示する実用的な例です。
.PHONY: all
all: build
ifeq ($(MAKELEVEL),0)
@echo ""
@echo "========================================="
@echo " ビルド完了"
@echo " 出力ディレクトリ: $(OUTPUT_DIR)"
@echo " 生成ファイル数: $$(find $(OUTPUT_DIR) -type f | wc -l)"
@echo "========================================="
endif
.PHONY: build
build: $(TARGETS)すべてのテストが完了した後でのみレポートを生成する例です。
.PHONY: test
test: run-tests
ifeq ($(MAKELEVEL),0)
@echo "テストレポートを生成中..."
$(MAKE) -C report generate
@echo "レポート生成完了: $(REPORT_DIR)/index.html"
endif
.PHONY: run-tests
run-tests:
$(MAKE) -C test/unit
$(MAKE) -C test/integrationMAKELEVEL は文字列として比較されるため、ifeq ($(MAKELEVEL),0) のように記述します$(MAKE) を使わずに直接 make を呼び出すと、MAKELEVEL が正しく設定されません-j オプション) でも MAKELEVEL は正しく動作します