Makefileにおける変数の使い方

変数の基本概念

Makefileにおける変数は、テキスト文字列を保持する識別子であり、ルールのターゲット・依存関係・コマンドなどに展開して利用できる。変数名には:#=、空白を含めることはできない。慣例として大文字が使われることが多いが、内部用途には小文字を使うことを推奨する。

変数参照は$(VAR)または${VAR}で行う。$$はリテラルのドル記号を表す。以下は典型的な使用例:

OBJS = main.o utils.o parser.o
app: $(OBJS)
	gcc -o app $(OBJS)

$(OBJS): config.h

変数の種類と代入方法

再帰的展開(=

値は参照時に展開される。他の変数や関数への参照が含まれる場合、その都度評価される。

CC = gcc
CFLAGS = $(WARNINGS) -O2
WARNINGS = -Wall

build:
	@echo $(CFLAGS)  # 出力: -Wall -O2

ただし、CFLAGS = $(CFLAGS) -gのような自己参照は無限ループを引き起こすため注意が必要。

単純展開(:= または ::=

定義時点で値を一度だけ展開し、その後はリテラルとして扱われる。

X := alpha
Y := $(X) beta
X := gamma

# Y の値は "alpha beta"(X の再定義後も変化しない)

先頭スペースを保持したい場合は次のようにする:

empty :=
space := $(empty) #

即時展開(:::=

定義時に一度展開され、結果がエスケープされて保存される。使用時には再度展開されるが、変数や関数は評価されない。

val = one$$two
VAR :::= $(val)
val = three$$four

# VAR の値は "one$$two"
# 使用時: $(VAR) → "one$two"

条件付き代入(?=

変数が未定義の場合のみ代入する。

INSTALL_DIR ?= /usr/local/bin

高度な変数操作

置換参照

$(VAR:a=b)形式で末尾一致置換が可能。ワイルドカードを使用したパターン置換もサポート。

SOURCES = foo.c bar.c baz.S
OBJECTS = $(SOURCES:.c=.o)        # foo.o bar.o baz.S
OBJS    = $(SOURCES:%.c=%.o)      # 同上(パターン指定)

計算された変数名

変数名自体を動的に構築できる。

arch = x86
x86_flags = -m32
flags = $($(arch)_flags)  # flags = "-m32"

複雑なケースでは複数レベルのネストも可能だが、可読性に注意が必要。

変数の管理と特殊機能

変数への追加(+=

既存の値にテキストを追加。変数の種類に応じて動作が異なる:

  • 再帰的変数:未展開のまま追加
  • 単純展開変数:新値を展開して追加
CFLAGS = -O2
CFLAGS += -g  # 再帰的 → "-O2 -g"(-O2内の変数参照は維持)

overrideディレクティブ

コマンドラインで指定された変数を上書き可能にする。

override CFLAGS += -DDEBUG

複数行変数(define)

改行を含む値を定義できる。

define HEADER
#ifndef CONFIG_H
#define CONFIG_H
#endif
endef

変数の未定義化(undefine)

変数を完全に削除(空文字とは異なる)。

undefine TEMP_VAR
override undefine USER_CFLAGS  # コマンドライン変数も対象

特殊な変数スコープ

ターゲット固有変数

特定のターゲットでのみ有効な変数値を設定。

debug: CFLAGS = -g -O0
debug: app

release: CFLAGS = -O3
release: app

依存ファイルにも継承されるが、private修飾子で抑制可能:

main: private LDFLAGS = -static
main: main.o

パターン固有変数

ファイルパターンにマッチするターゲットに適用。

%.o: CFLAGS = -fPIC
lib/%.o: CFLAGS = -fPIC -g  # より具体的なパターンが優先

組み込み特殊変数

  • MAKEFILE_LIST: 解析中のMakefileパスのリスト
  • .DEFAULT_GOAL: デフォルトターゲットの設定/取得
  • .VARIABLES: 定義済み全変数名のリスト
  • .FEATURES: サポート機能の一覧(jobserver, guile等)
  • .EXTRA_PREREQS: 自動変数に含まれない依存関係の追加
# .EXTRA_PREREQSの使用例
myapp: myapp.o
myapp: .EXTRA_PREREQS = $(CC)

タグ: Makefile gnu-make build-system

6月1日 01:38 投稿