* 3 変数とマクロ
- makeは2つの言語で構成されていると言える。
- ターゲットと前提条件とがつくる依存関係グラフ
- マクロ言語(テキストの置換を行う)
- 変数の形式
- 変数名につかえない文字は、':'、'#'、'='の三文
字。
- case sensitive
- 値の参照は、$(変数名)または${変数名}。ただし
変数名が一文字なら、$変数名もOK。
- 変数への値の束縛/代入において、後続の空白も値
とみなされる点に注意。例
------
CC := gcc # gccの定義
------
この場合、CCの値は、"gcc "となる。
** 3.1 変数を何に使うべきか
- ポータビリティおよびセキュリティのために、コマ
ンドゾーンのプログラム名を変数化するのはよくあ
ること。
** 3.2 変数の種類
- 単純展開変数と再帰展開変数の2種類がある。
- 詳細は3.4を参照
- 単純展開変数
- :=代入演算子で値を代入した変数のこと。
- 再帰展開変数
- =代入演算子で値を代入した変数のこと。
*** 3.2.1 その他の代入
- ?= 条件付き代入演算子
変数に値が無いときだけ代入が実行される。
- += アペンド
変数の値に文字列を追加していく。
** 3.3 マクロ
- =代入演算子の複数行版かな。
------
define print-info
@echo execuring $@ ...
pwd
uname -a
ls -l
endef
------
** 3.4 変数はいつ展開されるか
- makeの二段階処理
1. 第一段階 (read-in phase):
依存関係グラフの作成
makefile及びそれがincludeしているファイルを読
み込み、依存関係グラフを作成する。
依存関係グラフの作成にあたって、全ての変数と
値とルールとを内部に取り込む。
2. 第二段階(target-update phase):
ルール連鎖特定とコマンド実行
存在するファイルの情報と依存関係グラフから構
築に必要なルール連鎖を特定し、それに従ってコ
マンドを実行する。
- makeの変数を展開する2つの文脈
1. 即時文脈(IMMEDIATE):即時文脈にあるとき変数は
第一段階で展開される。
2. 遅延文脈(DEFERRED):遅延文脈にあるとき変数は展
開されずそのままとなる。ただし第一段階の処理
を進めていった結果、それがIMMEDIATEの位置に現
れたら、そのときに展開される。IMMEDIATEの位置
に現れないものは、第二段階で展開される。
- 変数の展開の要点
- 変数代入
IMMEDIATE = DEFERRED
IMMEDIATE ?= DEFERRED
IMMEDIATE := IMMEDIATE
IMMEDIATE += DEFERRED or IMMEDIATE
define IMMEDIATE
DEFERRED
endef
- +=について
左辺が以前に:=で代入されているならIMMEDIATE
になり、それ以外はDEFERREDになる。
- ルール
IMMEDIATE : IMMEDIATE ; DEFERRED
DEFERRED
- 実証用makefile
------
###
### =、?=、:= の基本
###
A1 = $(X1)
B1 := $(X1)
C1 ?= $(Y1)
A1 ?= $(Y1)
X1 := value1
Y1 := value2
.PHONY: all test-1 test-2 test-3 test-4 test-5 test-6
all: test-1 test-2 test-3 test-4 test-5 test-6
test-1:
# =、?=、:= の基本
# A1=$(A1), B1=$(B1), C1=$(C1)
#
# 実行結果
# A1=value1, B1=, C1=value2
###
### += の基本
###
A2 = $(X2)
B2 := $(X2)
A2 += - $(Y2)
B2 += - $(Y2)
X2 := value1
Y2 := value2
test-2:
# += の基本
# A2=$(A2)#
# B2=$(B2)#
#
###
### defineの基本
###
define A3
$(X3)
endef
X3 := value1
test-3:
# defineの基本
# $(A3)
#
###
### DEFFEREDが実行時の値であることの明示的確認
###
X4 := value1
A4 = $(X4)
X4 := value2
test-4:
# DEFFEREDが実行時の値であることの明示的確認
# A4=$(A4)
#
###
### DEFERREDの文脈だったものがIMMEDIATEに移る例
###
X5 := value1
A5 = $(X5)
B5 := $(A5)
X5 := value2
test-5:
# DEFERREDの文脈だったものがIMMEDIATEに移る例
# A5=$(A5), B5=$(B5)
#
###
### 左辺が即時であることの確認
###
VAR_NAME := A6
$(VAR_NAME) := value1
test-6:
# 左辺が即時であることの確認
# A6=$(A6)
#
------
実行結果
------
# =、?=、:= の基本
# A1=value1, B1=, C1=value2
#
# += の基本
# A2=value1 - value2#
# B2= - #
#
# defineの基本
# value1
#
# DEFFEREDが実行時の値であることの明示的確認
# A4=value2
#
# DEFERREDの文脈だったものがIMMEDIATEに移る例
# A5=value2, B5=value1
#
# 左辺が即時であることの確認
# A6=value1
#
------
** 3.5 ターゲットとパターンに固有の変数
- これ、節題が多少わかりにくいのですが、個別ター
ゲットや個別パターンにて変数の値をカスタマイズ
する、ということ。例。
------
SHEBANG = "\#!/bin/sh"
%: %.sh
echo $(SHEBANG) > $@
cat $< >> $@
chmod a+x $@
hoge: SHEBANG += -
------
これを'make hoge'したときと'make piyo'したとき
ではSHEBANGの値は異なる。
** 3.6 変数はどこからくるのか
- ファイル
makefile本体やincludeしたもの
- コマンドライン
例。
------
make CFLAG=-g
------
- 環境
いわゆる環境変数はmakeの変数として取り込まれる。
- 自動変数
ルールのコマンドゾーン実行直前に、自動変数とそ
の値を作成する。
** 3.7 条件判断とinclude命令
- 条件判断命令によって、makeの読み込みを制御でき
る。
- 形式は次のとおり。
CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
endif
CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
else
TEXT-IF-FALSE
endif
CONDITIONAL-DIRECTIVE
TEXT-IF-ONE-IS-TRUE
else CONDITIONAL-DIRECTIVE
TEXT-IF-TRUE
else
TEXT-IF-FALSE
endif
- CONDITIONAL-DIRECTIVE
`ifeq (ARG1, ARG2)'
`ifeq 'ARG1' 'ARG2''
`ifeq "ARG1" "ARG2"'
`ifeq "ARG1" 'ARG2''
`ifeq 'ARG1' "ARG2"'
`ifneq (ARG1, ARG2)'
`ifneq 'ARG1' 'ARG2''
`ifneq "ARG1" "ARG2"'
`ifneq "ARG1" 'ARG2''
`ifneq 'ARG1' "ARG2"'
`ifdef VARIABLE-NAME'
`ifndef VARIABLE-NAME'
*** 3.7.1 include命令
- 他のファイルを取り込むことができる。
例。
------
include header.mk
------
- ファイル指定部分は、ワイルドカードや変数を使う
ことができる。
*** 3.7.2 includeと依存関係
- includeファイル自身をターゲットとすることができ
る。このことは、
- makefileをはじめて読んだときは、include対象ファ
イルは存在しないかもしれない。
- makefileを読んだときにinclude対象ファイルは存
在するが、それを読み込んで処理を進めていった
ら、それ自身がターゲットになっており更新対象
であった。
というケースを発生させる。
- makeではこれらの状況に備えて次の処理手順となっ
ている。
- include対象ファイルが存在しない場合
- include行はスキップして処理を進める。
- include対象ファイルのターゲットが存在する場
合
- ターゲットを構築する。
- makeの内部データベースをクリアする。
- 始めから処理をする。(このときには、
include対象ファイルが存在する。)
- include対象ファイルのターゲットが存在しない
場合
- include対象ファイルが存在する場合
- include行でファイルを取り込む。
- include対象ファイルのターゲットが存在する場
合
- ターゲットの再構築が必要な場合
- ターゲットを再構築する。
- makeの内部データベースをクリアする。
- 始めから処理をする。(このときには、
include対象ファイルが存在する。)
- ターゲットの再構築が不要な場合
- そのまま処理をすすめる。
- include対象ファイルのターゲットが存在しない
場合
- そのまま処理をすすめる。
** 3.8 標準的なmake変数
- MAKE_VERSIONなどのmakeのメタ情報を保持する変数
が定義済みである。
- 組み込みルールはカスタマイズに備えて変数を多用
している。変数の命名則は次のとおり。
ACTION.suffix
- C/C++の例
COMPILE.c
COMPILE.cpp
LINK.o
...
こつこつ。
0 件のコメント:
コメントを投稿