ぼくの薄い本

技術的なメモを残していく薄い本的なものです

Makefile で代入の扱い

はじめに

Makefile で := を使った式の評価の挙動がよく分からなかったので、整理のため、まとめてみた

変数の宣言と代入

Makefile では宣言と同時に代入を行う。代入には、以下の4つがある。

  1. 単純展開変数
  2. 再帰属展開変数
  3. 条件付き代入演算子
  4. アペンド

単純展開変数

:= (コロンイコール)を使って、代入を行う。 右辺がただちに評価されて、左辺に代入される

CC := /usr/bin/gcc

以下のように未定義の変数を代入すると、空文字列が代入される

HOGE := $(FUGA)

再帰属展開変数

= (イコール)を使って、代入を行う。 := とは違い、右辺はただちに評価されず、実際に使用する時に評価される。

下記の例だと、HOGE 変数に代入時は、FUGA 変数は評価されず、 実際に ターゲット all で echo が実行されるときに入っている内容が評価される。 つまり、5行目で HOGE 変数に代入している段階で FUGA 変数に何も入っていなくても問題ない。

.PHONY: all
all:
        @echo $(HOGE)

HOGE = $(FUGA)
FUGA := fuga

条件付き代入演算子

?= (クエスチョンマークイコール) を使って、代入を行う。 左辺が定義済みであれば代入され、未定義であれば代入されない。

HOGE = hoge
HOGE ?= hoge2 # 代入されない
FUGA ?= fuga # 代入される

空文字列になったら困る時にデフォルトの値などを入れるために使用される。

アペンド

+= (プラスイコール) を使って、代入を行う。 左辺の定義の後ろに、右辺を繋げる。 下記の例だと、hoge fuga と表示される。

.PHONY: all
all:
        @echo $(HOGE)

HOGE = hoge
HOGE + fuga

INCLUDE や SRC の追加などによく使用される。

終わりに

Makefile が複雑になってくると、どこでどう式が評価されて代入されてしまうとか複雑になってくるから、ベストプラクティスというかあると良いなあ。