Make組み込み関数リファレンス
必須のMake関数を学びます:wildcard、patsubst、filter、foreach、call、shell、およびテキスト操作関数を実用的なビルドシステムの例とともに。
Reference
詳細な説明
必須のMake関数
Makeは文字列操作、ファイル操作、フロー制御のための組み込み関数を提供します。これらの関数は$(function arguments)構文で呼び出されます。
ファイル関数
# 再帰的にすべての.cファイルを検索
SRCS := $(shell find src -name '*.c')
# 1つのディレクトリの.cファイルを検索(shellなし)
SRCS := $(wildcard src/*.c)
# .cファイルを.oファイルに変換
OBJS := $(patsubst src/%.c,build/%.o,$(SRCS))
# 代替置換構文
OBJS := $(SRCS:.c=.o)
wildcardはglobパターンを展開します。patsubstは%をワイルドカードとしてパターン置換を行います。:.c=.o省略形はpatsubst %.c,%.oと同等です。
文字列関数
SRCS = main.c utils.c test_main.c test_utils.c
# filter:マッチする単語のみを保持
TEST_SRCS = $(filter test_%,$(SRCS))
# 結果: test_main.c test_utils.c
# filter-out:マッチする単語を削除
PROD_SRCS = $(filter-out test_%,$(SRCS))
# 結果: main.c utils.c
# ソートと重複除去
UNIQUE = $(sort z a m a z)
# 結果: a m z
# 単語関数
FIRST = $(firstword $(SRCS))
# 結果: main.c
COUNT = $(words $(SRCS))
# 結果: 4
foreachとcall
DIRS = src lib tests
# すべてのディレクトリを作成
$(foreach d,$(DIRS),$(shell mkdir -p $(d)))
# define/callでルールを生成
define COMPILE_RULE
$(2)/%.o: $(1)/%.c
@mkdir -p $$(@D)
$$(CC) $$(CFLAGS) -c -o $$@ $$<
endef
$(eval $(call COMPILE_RULE,src,build))
条件関数
# $(if condition,then,else)
CC := $(if $(shell which clang 2>/dev/null),clang,gcc)
# $(or ...) — 最初の空でない値
PYTHON := $(or $(shell which python3),$(shell which python),python)
# $(and ...) — いずれかの引数が空の場合は空
HAS_TOOLS := $(and $(shell which gcc),$(shell which make))
shell関数
GIT_HASH := $(shell git rev-parse --short HEAD)
NUM_CPUS := $(shell nproc 2>/dev/null || sysctl -n hw.ncpu)
$(shell ...)はコマンドを実行してその標準出力をキャプチャします。:=(即時代入)を使用して、参照のたびにではなくパース時に一度だけコマンドを実行します。
主要なヒント
- 可能な場合は
$(shell find ...)の代わりに$(wildcard)を使用する — より高速 $(sort)はソートと重複除去の両方を行う$(strip)は先頭/末尾の空白を削除する — 変数展開後に便利$(shell)には常に:=を使用して、コマンドの再実行を避ける
ユースケース
ファイルリストの操作、ソースのフィルタリング、動的なターゲット生成、利用可能なシステムツールに基づく条件分岐ロジックが必要な高度なMakefileルールを書く場合に使用します。