make
ユーティリティは,プログラムの最新バージョンを作成します。make
ユーティリティは,大規模なプログラミング・プロジェクトで,多数のソース・ファイルを組み合わせて 1 つのプログラムを作成したり,1 つの製品またはアプリケーションを構成するプログラム群を作成したりする場合などに最適です。
この章では,次の情報について説明します。
make
コマンドには,ビルド処理の実行を制御したり変更したりするためのオプションが用意されています。make
ユーティリティは,同じソース・ファイルの 2 つ以上のバージョンを保守するという問題は扱いません。
プログラムの保守に
make
ユーティリティを使用すると,次のことが実行できます。
大規模なプログラムを作成するための命令群を 1 つのファイルにまとめる。
マクロを定義して
make
記述ファイル内で使用する。
シェル・コマンドを使用する。
ライブラリを作成したり更新する。
別のプログラムからファイルをインクルードする。
オペレーティング・システムは,いくつかのバージョンの
make
コマンドを提供します。
この章では,省略時のバージョンの
make
(1)make
(1)make
(1u)make
(1p)make
(1p)make
コマンドです。
make
(1)make
(1u)make
(1p)
詳細については,
make
(1)make
(1u)make
(1p)make
(1)7.1 make ユーティリティの動作
make
ユーティリティは,ターゲットまたはターゲット・ファイルと呼ばれるプログラムの作成日と,従属ファイルまたは従属と呼ばれるターゲットを構成する各ファイルの日付とを比較することによって作動します。
ターゲットの従属ファイルの中にターゲットよりも新しいものがあれば,make
は既存のターゲットを古いものと見なします。
この場合,make
はコンパイルやリンクなど,必要な手順を実行してターゲットを再作成します。
従属ファイルはまた,同時にターゲットでもあります。
たとえば,実行可能プログラムは複数のオブジェクト・モジュールから作成されます。
オブジェクト・モジュールは,複数のソース・ファイルから作成されます。
ターゲットよりも新しい従属は,若い (younger) ファイルと呼ばれます。
make
ユーティリティはファイルのタイム・スタンプを使用します。
分散システム上で
make
を正しく作動させるには,ネットワーク上のすべてのシステムの日付および時刻が一致していなければなりません。
make
ユーティリティは,次の段階的な手順でターゲット・ファイルをビルドします。
記述ファイル内のターゲット・ファイルの名前を見つける。
従属行と呼ばれるターゲットの従属を示す行を見つける。
ターゲットの従属ファイルのすべてが存在することおよび最新であることを確認する。
ターゲットがその従属に対して最新であるかどうかを判定する。
ターゲットまたは従属のいずれかが古いものであった場合には,次のいずれかの方法を使用してターゲットをビルドする。
記述ファイルからコマンドを実行する。
内部規則が適用される場合は,その規則を使用してファイルをビルドする。
記述ファイルから省略時の規則を使用する。
make
が実行された時点で,従属行に記されたすべてのファイルが最新のものであれば,make
は,ターゲットが最新であることを示して実行を停止します。
ターゲットよりも新しい従属がある場合,make
は,古いターゲットだけを再ビルドします。
存在していないファイルは,古いものであると見なされます。
所定のターゲットに従属がない場合には,ターゲットは常に古いものと見なされ,make
を実行するたびにターゲットは作り直されます。
make
の処理は,再ビルドする必要のあるターゲットを決定する際にはトップダウン方式で行われ,実際の再ビルド時にはボトムアップ方式で作動します。
ターゲットをビルドするために,make
ユーティリティがコマンドを実行する時点で,make
は各マクロをその値に置き換えて各コマンド行を標準出力にエコーし,コマンドを実行します。
マクロについての詳細は,7.2.9 項を参照してください。make
ユーティリティは,rm
や
cc
などの直接実行できるコマンドを新しいシェルを呼び出さずに実行します。
make
ユーティリティは,新しいシェルのパイプやリダイレクションなどのシェル関数を指定した各コマンド行を実行します。
make
ユーティリティは,記述ファイルのあるディレクトリで起動します。make
コマンドの構文は,次のとおりです。
make
[
[-f
]
makefile
]
[ options
]
[ targets
]
[ macro definitions
]
make
ユーティリティは,コマンド行のエントリを確認して実行する動作を判断します。
まず
make
ユーティリティは,コマンド行 (等号を含むエントリ) のマクロ定義がある場合にはこれに値を割り当て,次に記述ファイルのマクロ定義に値を割り当てます。
コマンド行に定義されたマクロ名が記述ファイルにも定義されている場合,make
はコマンド行の定義を使用し,記述ファイルの定義を無視します。
次に,make
はオプションを確認します。make
がサポートするオプションの一覧については,
make
(1)
make
ユーティリティは,残りのコマンド行エントリをターゲット名であると解釈して,左から右の順にそれらのターゲットを処理します。
コマンド行にターゲットがまったく存在しない場合には,make
は記述ファイルで最初に指定されたターゲットを処理して実行を停止します。
7.2 記述ファイル
記述ファイルには,ターゲットに含める従属とそれらの従属とプロシージャ内の他のファイルとの関係を定義して,ターゲットのビルド方法を
make
に指示します。
記述ファイルには,次の情報が含まれます。
記述ファイル内のマクロの定義
1 つまたは複数のターゲット名
ターゲット・ファイルを構成する従属ファイル名
従属からターゲット・ファイルをビルドするためのコマンド
.DEFAULT
,.IGNORE
,.PRECIOUS
,.SILENT
,または
.SUFFIXES
のいずれかの擬似ターゲット
これらの識別子は,実際のターゲットではないために擬似ターゲットと呼ばれます。
これらは,make
が特別な方法で解釈する組み込み名です。
たとえば
.SILENT
は,make
がコマンド行を実行する際にエコーしないように指示します。
擬似ターゲットを実際のターゲット名として使用してはなりません。
擬似ターゲットの詳細は,
make
(1)
make
ユーティリティは,従属ファイルの日付を確認することによって,ターゲットを最新に保つためにビルドするファイルを決定します。
前回ターゲットをビルドした後に従属ファイルが変更されている場合,make
は,そのターゲットを含めて,従属ファイルの変更によって影響を受けるすべてのファイルをビルドします。
ほとんどの場合記述ファイルは簡単に記述でき,何度も変更されることはありません。
通常
make
ユーティリティは,makefile
または
Makefile
と名付けられた記述ファイルを探します。
記述ファイル名として
makefile
または
Makefile
を使用し,その記述ファイルが存在するディレクトリで作業している場合には,オプションおよび引数を省略して
make
コマンドを入力すると,make
が前回ターゲットをビルドしてから変更されたファイルの数にはかかわらず,最初のターゲットおよびその従属ファイルを更新します。
次の例のように,make
ユーティリティに
-f
オプションを使用すると,省略時のファイル名の代わりに任意の記述ファイル名を指定することができます。
% make -f my_makefile
このオプションを使用することにより,複数の記述ファイルを同じディレクトリに保存することができます。
この節では,記述ファイルの次の事項について説明します。
記述ファイル・エントリの形式 (7.2.1 項)
記述ファイルでのコマンドの使用 (7.2.2 項)
make
ユーティリティのコマンド・エコーの防止 (7.2.3 項)
make
ユーティリティのエラーによる停止の防止 (7.2.4 項)
省略時の条件の定義 (7.2.5 項)
make
によるファイル削除の防止 (7.2.6 項)
簡単な記述ファイル (7.2.7 項)
記述ファイルの簡素化 (7.2.8 項)
マクロの定義 (7.2.9 項)
記述ファイルでのマクロの使用 (7.2.10 項)
記述ファイルからの make ユーティリティの呼び出し (7.2.11 項)
内部マクロ (7.2.12 項)
make ユーティリティによる環境変数の使用 (7.2.13 項)
内部規則 (7.2.14 項)
他のファイルのインクルード (7.2.15 項)
記述ファイルのテスト (7.2.16 項)
記述ファイル (7.2.17 項)
[target1 [ target2... ]
]
[:
]
[
[:
]
]
[
[dependent...
]
]
[
[;
]
commands
]
[
[#
]
comment...
]
大カッコ内の項目は省略可能です。
ターゲット (target) および従属 (dependent) は,文字,数字,ピリオド,あるいはスラッシュで構成される文字列によるファイル名です。make
コマンドは,アスタリスク ( *
) および疑問符 ( ?
) などのワイルドカード文字を認識します。
ターゲット名を含む記述ファイルの各行は,従属行と呼ばれます。
従属行では,ターゲット名の後に,ターゲットをビルドするための処理手順を指定する 1 つまたは複数のコマンド行 (commands) が続きます。
make
では,マクロの指定にドル記号 ( $
) を使用するため,ドル記号 ( $
) をターゲットおよび従属のファイル名に使用してはなりません。
同様に,定義した
make
マクロを参照する場合以外には,記述ファイル内のコマンドにドル記号を使用してはなりません。
マクロについては,7.2.9 項,7.2.10 項,および7.2.12 項を参照してください。
記述ファイル内にコメント (comment) を書く場合には,番号記号 ( #
) を使用してコメント・テキストを開始してください。make
ユーティリティは,番号記号以降にある同じ行上の番号記号とすべての文字を無視します。
空白行も無視されます。
バックスラッシュ ( \
) を行の終わりに置くことによって,入力デバイスの行幅よりも長い行を入力することができますが,この方法でコメント行を拡張してはなりません。
各行に 1 つの番号記号を付けて新しいコメント行を開始してください。
7.2.2 記述ファイルでのコマンドの使用
コマンドは,番号記号や改行文字を除いた,任意の文字からなる文字列です。
コマンドは,従属行のセミコロン ( ;
) の後または従属行の直後の行に現れます。
従属行の後の各コマンド行は,単一のタブ文字で開始する必要があります。
記述ファイル内でターゲットにコマンド・シーケンスを定義する場合には,各ターゲットにコマンド・シーケンスを 1 つ指定するか,または特定の従属の集合に別のコマンド・シーケンスを指定します。
各ターゲットを使用するたびにコマンド・シーケンスを 1 つ使用するには,従属行のターゲット名に続けてコロン ( :
) を 1 つ使用します。
たとえば,次の例では,test
というターゲット名とターゲットを作成するための従属ファイルの集合およびコマンドの集合が定義されています。
test: dependency list1... command list...
.
.
.
test: dependency list2...
ここに示されているように,1 つのターゲット名が,記述ファイル内の複数の箇所に,異なる従属リストを伴って現れますが,このターゲット名に関連付けられるコマンド・リストは 1 つだけです。make
ユーティリティは,所定のターゲットのすべての従属行を見つけて,それらの従属リストのすべてを1つのリストに連結します。
従属のいずれかが変更された場合に,make
は当該ターゲットをビルドするために 1 つのコマンド・リストにあるコマンド群を実行します。
特定のターゲット・ファイルをビルドするために,コマンドの集合を 2 つ以上指定する場合には,2 つ以上の従属定義を入力します。
各従属行には,ターゲット名の後にコロンを 2 つ ( ::
) 加え,その後に 1 つの従属リスト,および,従属リストのファイルのいずれかが変更された場合に
make
が使用するコマンド・リストを続けなければなりません。
たとえば,次の例ではターゲット・ファイル
test
をビルドするために 2 つの異なる処理を定義しています。
test:: dependency list1... command list1...
.
.
.
test:: dependency list2... command list2...
make
は,従属リスト
list1
のファイルのいずれかが変更された場合にはコマンド
list1
を,従属リスト
list2
のファイルのいずれかが変更された場合には
list2
を実行します。
衝突を避けるため,1 つの従属ファイルを従属リストの
list1
および
list2
の両方に指定することはできません。
注意
make
は,先行する各コマンド行および後続のコマンド行から独立したものとして各コマンドを実行するので,たとえば,一定のコマンド (cd
など) を使用する場合には注意が必要です。 次の例では,cd
コマンドは,後続のcc
コマンドには影響を与えていません。test: test.o cd /u/tom/newtest cc main.o subs.o -o test
cc
コマンドにcd
コマンドを作用させるには,次のように,両方のコマンドを同じ行に置いてセミコロンで区切ります。test: test.o cd /u/tom/newtest; cc main.o subs.o -o test
次のように,バックスラッシュを後続する行の先頭に置くことによって,複数の行からなるシェル・スクリプトをシミュレートすることができます。
test: test.o cd /u/tom/newtest; \ cc main.o subs.o -o test
これは,直前の例とまったく同じ作用をします。 バックスラッシュによって接続する各行 (この例では
cd
の行) には,バックスラッシュの前にセミコロンを置かなければなりません。
7.2.3 make ユーティリティのコマンド・エコーの防止
make
が実行中のコマンドを標準出力にエコーしないようにするには,次の手順のうちの 1 つを実行します。
make
コマンドで
-s
フラグを指定する。
記述ファイルに擬似ターゲット名
.SILENT:
という単独の 1 行を置く。
擬似ターゲットの詳細については,7.2 節を参照してください。
記述ファイル内で,make
がエコーする必要のない各コマンド行の文字開始位置 (タブの直後) にアットマーク ( @
) を入力する。
7.2.4 make ユーティリティのエラーによる停止の防止
いずれかのコマンドがゼロ以外の状態コードを返した場合,make
ユーティリティは通常,実行を停止してエラーを表示します。
エラーで
make
が終了しないようにするには,次の手順のいずれかを実行します。
make
コマンドで
-i
フラグを指定する。
記述ファイルに擬似ターゲット名
.IGNORE:
という単独の 1 行を置く。
擬似ターゲットの詳細については,7.2 節を参照してください。
記述ファイル内で,make
をエラーで停止させたくない,各コマンド行の文字開始位置 (タブの直後) に,ハイフン ( -
) を入力する。
make
がターゲットをビルドするにあたって,明示されたコマンド行や内部規則を見つけることができない場合には,記述ファイル中の省略時の条件を調べます。
この場合に
make
が実行するコマンドを定義するには,記述ファイル中に擬似ターゲット名
.DEFAULT:
を使用し,その他の任意のターゲットの場合と同様に,省略時のコマンド・シーケンスを入力します。
擬似ターゲット
.DEFAULT:
は,エラー回復の手順や
make
ユーティリティの内部規則に定義されていないプログラムで,すべてのファイルをビルドするための一般的な手順として使用することができます。
7.2.6 make によるファイル削除の防止
不正のおそれのあるターゲット・ファイルを使用してビルドしないように,make
は通常,途中でエラーが返された場合にはターゲット・ファイルを削除します。
エラーが検出された場合にも,make
がファイルを削除しないようにするには,記述ファイル内に擬似ターゲット
.PRECIOUS:
を使用してください。
擬似ターゲット名の後に,セーブする必要のあるターゲット名を挙げてください。
コマンド行に
-u
オプションを指定した場合,make
はチェックアウトされた RCS ファイルを削除しません。make
が RCS
と対話する方法についての詳細は,
make
(1)7.2.7 簡単な記述ファイル
例 7-1
では,x.c
,y.c
,および
z.c
の 3 つの C 言語ファイルをロードしてコンパイルすることによって,prog
と名付けられたプログラムがビルドされます。
ファイル
x.c
および
y.c
は,defs
という名前のファイルの中でいくつかの宣言を共有しますが,ファイル
z.c
はこれを共有しません。
例 7-1: 記述ファイルの例
# Make prog from 3 object files prog: x.o y.o z.o # Use the cc program to make prog cc x.o y.o z.o -o prog # Make x.o from 2 other files x.o: x.c defs # Use the cc program to make x.o cc -c x.c # Make y.o from 2 other files y.o: y.c defs # Use the cc program to make y.o cc -c y.c # Make z.o from z.c z.o: z.c # Use the cc program to make z.o cc -c z.c
このファイルを
makefile
と名付けた場合,4 つのソース・ファイル
x.c
,y.c
,z.c
,および
defs
のいずれかのファイルを変更した後では,オプションも引数も使用しないで
make
コマンドを入力するだけで,prog
の最新コピーを作成することができます。
7.2.8 記述ファイルの簡素化
記述ファイルをより簡単にするには,make
ユーティリティの内部規則を使用します。make
は,ファイル・システムの命名規則によって,必要な
.o
ファイルと対応する 3 つの
.c
ファイルを認識します。make
には,ソース・ファイルからオブジェクト・ファイルを生成する処理 (cc -c
コマンドの実行) も組み込まれています。
これらの内部規則を活用することによって,前述の記述ファイルは次のように簡素化されます。
# Make prog from 3 object files prog: x.o y.o z.o # Use the cc program to make prog cc x.o y.o z.o -o prog # Use the file defs and the appropriate .c file # when making x.o and y.o x.o y.o: defs
make
が使用する内部規則については,7.2.14 項を参照してください。
7.2.9 マクロの定義
マクロとは,1 つまたは複数の名前の代わりに使用される別名のことで,長い文字列を短縮するために使用されます。 マクロは,記述ファイル内またはコマンド行上に定義することができます。 記述ファイル内にマクロを定義する方法は次のとおりです。
新しい行をマクロ名で開始する。
名前の後に等号 ( =
) を入力する。
等号の右にマクロ名が表す文字列を入力する。 文字列には空白を含めることができる。
マクロ定義では,等号の前後に空白を指定しても結果には影響を与えません。
ただし,等号の前にコロン ( :
) またはタブを指定することはできません。make
ユーティリティは,マクロ定義の文字列に先行および後続する空白を無視します。
次にマクロ定義の例を示します。
# Macro ABC has a value of "ls -la" ABC = ls -la # Macro LIBES has a null value LIBES = # Macro DIRECT includes the definition of macro ROOT # The expanded value of DIRECT is "/usr/home/fred" ROOT = /usr/home DIRECT = $(ROOT)/fred
この例にある
DIRECT
マクロは,自身の定義の一部として別の定義を使用します。
マクロを使用する際の手順については,7.2.10 項を参照してください。
コマンド行上でマクロを定義するには,記述ファイル内でマクロを定義する場合と同じ構文に従いますが,同じ行の中にすべてのマクロを定義してください。
コマンド行上で空白を含んだマクロを定義する場合には,( "name = definition"
) のように引用符で定義を囲みます。
引用符を付けない場合,シェルは,空白がパラメータ・セパレータであり,マクロの一部ではないと解釈します。
7.2.10 記述ファイルでのマクロの使用
記述ファイルでマクロを定義した後に,マクロ名の前にドル記号 ( $
) を置くことによって記述ファイルのマクロの値を参照します。
マクロ名が 1 文字より長い場合には,次の例で示されるように,カッコまたは中カッコで囲んでください。
$(CFLAGS) ${xy} $Z $(Z)
最後の 2 つの例は,同じ結果になります。
7.2.10.1 マクロの置換
マクロの定義値の一部またはすべてを,異なる値に置換することができます。 次に,マクロ置換の 3 つの形式を示します。
形式 1
MACRO の定義された値の中のすべての string1 を string2 に置換します。
[$(MACRO:string1=string2)
]
次に例を示します。
# Define macro MAC1 MAC1 = xxx yyy zzz
.
.
.
# Evaluate MAC1 project: @ echo $(MAC1:yyy=abc)
この記述ファイルを使用して
make
を実行した場合,make
は,yyy
を
abc
に置換して,次の行を表示します。
xxx abc zzz
形式 2
定義された値の各ワードを置換します。location パラメータは,ワードのどの部分が string に置換されるかを指定します。
[$(MACRO/location/string)
]
location パラメータは,次の値に限定されています。
string の値が,定義された各ワードにプレフィックスとして追加されます。 次にその例を示します。
# Define macro MAC1 MAC1 = abc def ghi
.
.
.
# Evaluate MAC1 project: @ echo $(MAC1/^/xyz)
この記述ファイルを使用して
make
を実行した場合,make
は,定義された各ワードの先頭にxyz
を追加して,次の行を表示します。
xyzabc xyzdef xyzghi
定義されたワードのすべてが,それぞれ string の値に置換されます。 次にその例を示します。
# Define macro MAC1 MAC1 = abc def ghi
.
.
.
# Evaluate MAC1 project: @ echo $(MAC1/*/xyz)
この記述ファイルを使用して
make
を実行した場合,make
は定義された各ワードを
xyz
と置換して,次の行を表示します。
xyz xyz xyz
アスタリスクを指定した場合,string
の値にアンパサンド ( &
) を使用することができます。
アンパサンドは置換される定義されたワードを示しており,そのワードは結果の中に挿入されます。
次にその例を示します。
# Define macro MAC1 MAC1 = abc def ghi
.
.
.
# Evaluate MAC1 project: @ echo $(MAC1/*/x&z)
この記述ファイルを使用して
make
を実行した場合,make
はアンパサンドに定義されたワードを挿入することによって各ワードを
x&z
に置換し,次の行を表示します。
xabcz xdefz xghiz
定義された各ワードに string の値が追加されます。 次にその例を示します。
# Define macro MAC1 MAC1 = abc def ghi
.
.
.
# Evaluate MAC1 project: @ echo $(MAC1/$/xyz)
この記述ファイルを使用して
make
を実行した場合,make
は定義された各ワードの後に
xyz
を追加して,次の行を表示します。
abcxyz defxyz ghixyz
形式 3
MACRO が定義されているかどうかにより,2 つの中からいずれかの置換を実行することができます。
[$(MACRO?string1:string2)
]
MACRO が定義されていた場合,定義された値のすべてを string1 と置換します。MACRO が定義されていない場合は,string2 を使用します。 次にその例を示します。
# Define macro MAC1 MAC1 = abc def ghi
.
.
.
# Evaluate MAC1 and MAC2. MAC2 is not defined. project: @ echo $(MAC1?uvw:xyz) @ echo $(MAC2?123:456)
この記述ファイルを使用して
make
を実行した場合,make
は
MAC1
の値を
uvw
に置換し,定義されていない
MAC2
を
456
に置換して,次の行を表示します。
uvw 456
MACRO
が定義されていない場合,形式 1 および 2 では空文字列が生成されます。
7.2.10.2 条件付きマクロ
マクロの値は,先在する条件に基づいて割り当てることができます。 このタイプのマクロを条件付きマクロと呼びます。 コマンド行で条件付きマクロを定義することはできません。 条件付きマクロ定義は,すべて記述ファイルに定義する必要があります。 条件付きマクロの構文は,次のとおりです。
[target:=MACRO = string
]
指定されたターゲットが
make
コマンドの現在のターゲットである場合には,条件付きマクロには,文字列の値が割り当てられます。
そうでない場合は,マクロの値は空になります。
次の記述ファイルでは,MAC1
に条件付き置換を使用しています。
# Define the conditional macro MAC1 target2:=MAC1 = xxx yyy xxxyyy
.
.
.
#list targets and command lines # target1:;@echo $(MAC1) target2:;@echo $(MAC1)
この記述ファイルを使用して
make
を実行した場合は,次のような結果になります。
% make target1 % make target2 xxx yyy xxxyyy
7.2.11 記述ファイルからの make ユーティリティの呼び出し
make
記述ファイル内のコマンド行の 1 つに
$(MAKE)
マクロを指定することによって,make
ユーティリティの呼び出しをネストすることができます。
このマクロが存在する場合,-n
オプションが設定された場合にも,make
は,別の
make
のコピーを実行します。-n
オプションについての詳細は,7.2.16 項を参照してください。
7.2.12 内部マクロ
make
ユーティリティには,記述ファイル内で使用できる組み込みマクロ定義があります。
これらのマクロは,記述ファイル内での変数の指定を補助するものです。make
ユーティリティは,マクロを表 7-1
に示された値に置換します。
表 7-1: make の内部マクロ
マクロ | 値 |
$@ |
現在のターゲット・ファイル名 |
$$@ |
従属行のターゲット名 |
$? |
ターゲットよりも新しく変更された従属ファイル名 |
$< |
新しいターゲット・ファイルがビルドされる原因となった古いファイルの名前 |
$* |
サフィックスなしの現在の従属ファイル名 |
上記の内部マクロは,実際に
make
が使用する際に,単一のファイル名に変更されます。
サフィックス
D
を使用すれば上記マクロのいずれかの解釈を変更し,ファイル名のディレクトリ部分だけを指定することができます。
たとえば,現在のターゲットが
/u/tom/bin/fred
である場合に,$(@D)
マクロは,名前の
/u/tom/bin
という部分だけを返します。
同様に,サフィックス
F
では,ファイル名の部分だけを返します。
たとえば,$(@F)
マクロに同じターゲットを与えた場合には,fred
を返します。$?
マクロを除くすべての内部マクロは,サフィックス
D
あるいは
F
をとることができます。
分散ファイル・システムで内部マクロを使用する場合には,その前に,make
が処理するファイルを含むすべてのノードで,システム・クロックが同じ日付と時間を示していることを確認する必要があります。
make
ユーティリティは,記述ファイルからコマンドを実行してターゲット・ファイルをビルドする場合にだけ,これらの記号を変更します。
次の項では,これらのマクロの詳細について説明します。
7.2.12.1 ターゲット・ファイル名内部マクロ
make
ユーティリティは,ターゲットをビルドするコマンド・シーケンスの中に出現するすべての
$@
マクロを,現在のターゲットのフルネームに置換します。
この置換は,コマンドを実行する前に行われます。
次にその例を示します。
/u/tom/bin/test: test.o cc test.o -o $@
この例では,/u/tom/bin/test
という名前の実行可能ファイルが作成されます。
7.2.12.2 ラベル名内部マクロ
$$@
マクロが記述ファイルの従属行のコロンの右側で使用された場合,make
はこの記号を従属行のコロンの左側にあるラベル名と置換します。
この名前は,ターゲット名や別のマクロ名であってもかまいません。
次にその例を示します。
cat: $$@.c
make
ユーティリティは,この行を次のように解釈します。
cat: cat.c
このマクロを使用すると,各ファイルが単一のソース・ファイルを持つファイルのグループを作成できます。 たとえば,システム・コマンドのディレクトリを保守するには,次のような記述ファイルを使用します。
# Define macro CMDS as a series of command names CMDS = cat dd echo date cc cmp comm ar ld chown # Each command depends on a .c file $(CMDS): $$@.c # Create the new command set by compiling the out of # date files ($?) to the current target file name ($@) cc -O $? -o $@
make
ユーティリティは,実行時に
$$(@F)
マクロを
$@
のファイルの部分に変更します。
たとえば,記述ファイルを別のディレクトリで使用しながら
usr/include
ディレクトリを保守する場合に,この記号を使用することができます。
その記述ファイルは,次に示されるようになります。
# Define directory name macro INCDIR INCDIR = /usr/include # Define a group of files in the directory # with the macro name INCLUDES INCLUDES = \ $(INCDIR)/stdio.h \ $(INCDIR)/pwd.h \ $(INCDIR)/dir.h \ $(INCDIR)/a.out.h # Each file in the list depends on a file # of the same name in the current directory $(INCLUDES): $$(@F) # Copy the younger files from the current # directory to /usr/include cp $? $@ # Set the target files to read only status chmod 0444 $@
この記述ファイルは,現在のディレクトリで対応するファイルが変更された場合に,/usr/include
ディレクトリでファイルを作成します。
7.2.12.3 younger ファイル内部マクロ
$?
マクロが記述ファイルのコマンド・シーケンスにある場合,make
は
$?
をターゲット・ファイルの最後の変更後に更新された従属ファイルのリストに置換します。
7.2.12.4 最初の旧ファイル内部マクロ
$<
マクロが記述ファイルのコマンド・シーケンスにある場合,make
は,$<
をファイルの作成を開始させたファイル名に置換します。
置換するファイル名は,当該ターゲット・ファイルに対して古くなった特定の従属ファイル,すなわち,make
が当該ターゲット・ファイルを再度作成する原因となったファイルの名前です。
これが,新ファイルの一覧を返す
$?
記号との違いです。
make
ユーティリティは,内部規則から,あるいは,.DEFAULT:
リストからコマンドを実行する場合に限り,この記号を置換します。$<
記号は,明示的に指定されたコマンド行には影響を与えません。
7.2.12.5 現在のファイル名プレフィックスのための内部マクロ
$*
マクロが記述ファイルのコマンド・シーケンスにある場合,make
は
$*
を現在
make
が使用してターゲット・ファイルをビルドしている従属ファイル名のサフィックスを除く部分に置換します。
たとえば,make
がターゲット
test.c
を作成している場合,$*
記号はファイル名
test
に相当します。
make
ユーティリティは,内部規則から,あるいは,.DEFAULT:
リストからコマンドを実行する場合に限り,この記号を置換します。$*
記号は,明示的に指定されたコマンド行には影響を与えません。
7.2.13 make による環境変数の使用
make
は,実行されるたびに現在の環境変数を読み取って,定義済みのマクロに追加します。
さらに,MAKEFLAGS
という新しいマクロを作成します。
MAKEFLAGS
マクロは,コマンド行に入力されたすべてのオプションの集合です。
コマンド行オプションおよび記述ファイルの割り当てによっても,MAKEFLAGS
マクロの値を変更することができます。make
が別の処理を開始する場合には,別の処理に対して
MAKEFLAGS
をエクスポートします。MAKEFLAGS
マクロの再帰的な
make
処理の影響については,7.2.16 項を参照してください。
make
ユーティリティは,次の順序でマクロ定義を割り当てます。
矛盾が発生する場合は上位の設定が優先します。
MAKEFLAGS
環境変数を読み取り,変数に指定されたオプションを設定する。
MAKEFLAGS
が存在しないか,あるいは値が空の場合,make
は内部
MAKEFLAGS
マクロを空文字列に設定します。
そうでない場合,make
は
MAKEFLAGS
の各文字が入力オプションであると見なします。make
ユーティリティは,-f
,-p
,および
-r
を除くこれらのオプションを使用して,動作条件を決定します。
コマンド行にある入力フラグを読み取り,設定する。
コマンド行で明示的に指定されたすべてのオプションが,MAKEFLAGS
環境変数によって設定に追加されます。
コマンド行からマクロ定義を読み取る。
これらの定義は,記述ファイル内の同じ名前の定義を変更します。
内部マクロ定義を読み取る。
MAKEFLAGS
マクロを含む環境変数を読み取る。
make
ユーティリティは,すべての環境変数をマクロ定義として扱い,コマンドを実行するために呼び出すシェルにそれらを渡します。
make
ユーティリティは,内部規則の集合を持ち,これを使用してターゲットをビルドする方法を決定します。-r
オプションを付けて
make
を呼び出すことによって,これらの規則を変更することができます。
この場合,記述ファイル内のターゲットのビルドに必要なすべての規則を提供する必要があります。
内部規則には,擬似ターゲット
.SUFFIXES:
を使用して定義されるファイル名のサフィックスのリストが含まれます。
また,内部規則には,あるサフィックスを持つファイルから別のサフィックスを持つファイルを
make
に作成させる規則も含まれます。make
の内部規則でサポートされる変換対象項目の一覧を参照するには,次のコマンドを実行してください。
% make -p | more
省略時の設定によるリストを変更しない場合,make
は次のサフィックスがあるものと解釈します。
サフィックス | ファイル・タイプ |
.o |
オブジェクト・ファイル |
.c |
C ソース・ファイル |
.e |
efl
ソース・ファイル |
.r |
Ratfor ソース・ファイル |
.f
あるいは
.F |
FORTRAN ソース・ファイル |
.s |
アセンブラ・ソース・ファイル |
.y |
yacc
C ソース文法 |
.yr |
yacc
Ratfor ソース文法 |
.ye |
yacc efl
ソース文法 |
.l |
lex
ソース文法 |
.out |
実行可能ファイル |
.p |
Pascal ソース・ファイル |
.sh |
Bourne シェル・スクリプト |
.csh |
C シェル・スクリプト |
.h |
C ヘッダ・ファイル |
1 つまたは複数のサフィックスをスペースで区切り,記述ファイルの
.SUFFIXES:
行に加えると,上記のリストにサフィックスを追加することができます。
たとえば,次の行の例では,サフィックス
.f77
および
.ksh
が既存のリストに追加されます。
.SUFFIXES: .f77 .ksh
make
のサフィックスの省略時のリストを消去するには,何も名前を指定しないで
.SUFFIXES:
行を挿入します。
1 行目に空のリストを,2 行目に新しいリストを入力すると,省略時のリストを完全に新しいものにすることができます。
.SUFFIXES: .SUFFIXES: .o .c .p .sh .ksh .csh
make
は,サフィックス・リストを左から右の順に調べるため,エントリの順序は重要です。
上記の例では,make
がオブジェクト・ファイルを,次に C ソース・ファイルを検索します。
make
ユーティリティは,リスト中にあり,次の 2 つの必要条件を満たす最初のエントリを使用します。
入出力のサフィックス要求と照合するエントリ
当該エントリに割り当てられた規則を持つエントリ
make
が認識するリストにサフィックスを追加する場合には,従属からターゲットをビルドする方法を説明する規則を提供する必要があります。
規則は従属行とそれに対応する一連のコマンドと似ています。
make
ユーティリティは,その規則が定義する 2 つのファイルのサフィックスから規則の名前を作成します。
たとえば,.r
ファイルを
.o
ファイルに変える規則の名前は,.r.o
です。例 7-2
は,標準の省略時の規則ファイルの一部です。
7.2.14.1 単一サフィックスの規則
make
ユーティリティには,コマンド・ファイルなどのサフィックスを持たないターゲットをビルドするための,単一サフィックスの規則もあります。make
ユーティリティには,次のサフィックスを持つソース・ファイルを,サフィックスを持たないオブジェクト・ファイルに変更する規則があります。
例 7-2: 省略時の規則ファイル
# Create a .o file from a .c # file with the cc program .c.o $(CC) $(CFLAGS) -c $< # Create a .o file from either a # .e , a .r , or a .f # file with the efl compiler $(EC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $< # Create a .o file from # a .s file with the assembler .s.o: $(AS) -o $@ $< .y.o: # Use yacc to create an intermediate file $(YACC) $(YFLAGS) $< # Use cc compiler $(CC) $(CFLAGS) -c y.tab.c # Erase the intermediate file rm y.tab.c # Move to target file mv y.tab.o $@ .y.c: # Use yacc to create an intermediate file $(YACC) $(YFLAGS) $< # Move to target file mv y.tab.c $@
サフィックス | ソース・ファイルのタイプ |
.c |
C 言語ソース・ファイルから |
.sh |
シェル・ファイルから |
たとえば,必要なすべてのファイルが現在のディレクトリにある場合に,cat
のようなプログラムを保守するには,次のコマンドを入力します。
% make cat
make
ユーティリティは,内部規則としてマクロ定義を使用します。
これらのマクロ定義を変更するには,コマンド行または記述ファイルに,それらのマクロの新しい定義を入力してください。make
ユーティリティは,コマンドおよび言語プロセッサに次のマクロ名を使用します。
コマンドまたは関数 | コマンド・マクロ | コマンド・オプションまたは他のマクロ |
アーカイブ・プログラム (ar ) |
AR | ARFLAGS |
アーカイブの目次作成 | RANLIB | |
アセンブラ | AS | ASFLAGS |
C コンパイラ | CC | CFLAGS |
C ライブラリ | LOADLIBS | |
RCS チェックアウト | CO | COFLAGS |
コピー・コマンド (cp ) |
CP | CPFLAGS |
efl
コンパイラ |
EC | EFLAGS |
リンカ・コマンド (ld ) |
LD | LDFLAGS |
lex
コマンド |
LEX | LFLAGS |
lint
コマンド |
LINT | LINTFLAGS |
make
コマンド |
MAKE | |
再帰的
make
呼び出しフラグ |
MAKEFLAGS | |
mv
コマンド |
MV | MVFLAGS |
pc
コマンド |
PC | PFLAGS |
f77
コンパイラ |
RC | FFLAGS |
Ratfor コンパイラ・フラグ | RFLAGS | |
rm
コマンド |
RM | RMFLAGS |
従属ファイルと関係するファイルの配置 | VPATH | |
yacc
コマンド |
YACC | YFLAGS |
yacc -e
コマンド |
YACCE | YFLAGS |
yacc -r
コマンド |
YACCR | YFLAGS |
たとえば,次のコマンドは,make
を実行して,既定の C 言語コンパイラを
newcc
プログラムに置換します。
% make CC=newcc
同様に,次のコマンドは,make
に C 言語コンパイラによって作成された最終的なオブジェクト・コードを最適化するように指示します。
% make "CFLAGS=-O"
make
が使用する内部規則を調べるには,Bourne シェルから次のコマンドを入力します。
$ make -fp -< /dev/null 2>/dev/null
出力は,標準出力に表示されます。
7.2.15 他のファイルのインクルード
記述ファイルの任意の行に最初のワードとして
include
を入力すると,現在の記述ファイルにファイルをインクルードすることができます。include
の後に空白またはタブを続けて,次に
make
が実行中にインクルードするファイル名を入力します。
次にその例を示します。
include /u/tom/temp /u/tom/sample
記述ファイルをテストするには,-n
コマンド・オプションで
make
を実行してください。
このオプションは,make
にコマンド行を実行しないでエコーだけするように指示します。make
が実行するプロセス全体がユーザに見えるように,アットマーク ( @
) で始まるコマンドもエコーされます。-n
オプションで実行中の場合でも,$(MAKE)
マクロは,その他のコマンドとは違い実際に実行されます。
記述ファイルに
$(MAKE)
マクロのインスタンスが含まれる場合,make
は
-n
を含む,コマンド行に入力したオプションのリストを
MAKEFLAGS
マクロに設定した状態で,make
の新しいコピーを呼び出します。make
の新しいコピーは,-n
オプションが設定されているため,新しいコピーを呼び出した
make
と同じ方法でコマンドの実行を無視します。make
コマンドを 1 度実行するだけで,make
を再帰的呼び出しする記述ファイルのセットをテストすることができます。
7.2.17 記述ファイル
例 7-3
は,make
ユーティリティを保守するための記述ファイルの例です。make
のソース・コードには,多くの C 言語ソース・ファイルおよび
yacc
文法ファイルが含まれます。yacc
についての詳細は,第 4 章を参照してください。
例 7-3: make ユーティリティの makefile
# Description file for the Make program # Macro def: send to be printed P = lpr # Macro def: source file names used FILES = Makefile version.c defs main.c doname.c misc.c files.c dosy.c gram.y lex.c gcos.c # Macro def: object file names used OBJECTS = version.o main.o doname.o \ misc.o files.o dosys.o gram.o # Macro def: lint program and flags LINT = lint -p # Macro def: C compiler flags CFLAGS = -O # make depends on the files specified # in the OBJECTS macro definition make: $(OBJECTS) # Build make with the cc program cc $(CFLAGS) $(OBJECTS) -o make # Show the file sizes size make # The object files depend on a file # named defs $(OBJECTS): defs # The file gram.o depends on lex.c # uses internal rules to build gram.o gram.o: lex.c # Clean up the intermediate files clean: rm *.o gram.c # Copy the newly created program # to /usr/bin and deletes the program # from the current directory install: cp make /usr/bin/make ; rm make # Empty file ''print'' depends on the # files included in the macro FILES print: $(FILES) # Print the recently changed files lpr $? # Change the date on the empty file, # print, to show the date of the last # printing touch print # Check the date of the old # file against the date # of the newly created file test: make -dp | grep -v TIME >1zap /usr/bin/make -dp | grep -v TIME >2zap diff 1zap 2zap rm 1zap 2zap # The program, lint, depends on the # files that are listed lint: dosys.c doname.c files.c main.c misc.c \ version.c gram.c # Run lint on the files listed # LINT is an internal macro $(LINT) dosys. doname.c files.c main.c \ misc.c version.c gram.c rm gram.c # Archive the files that build make arch: ar uv /sys/source/s2/make.a $(FILES)