以上の問題を解決するには、ライブラリがあるディレクトリで make コマンドを入れ子にして実行し、(そのディレクトリにあるメークファイル中のターゲットエントリに従って) ライブラリを構築します。
デフォルトでは "make" という値に設定されている MAKE
マクロは、make コマンドの -n オプションを無効にします。つまり MAKE
マクロを参照しているコマンドは、-n オプションが指定されている場合でも実行されます。ただし MAKE
マクロは make コマンドを呼び出すためにのみ使用され、このマクロによって呼び出された make は、特殊マクロ MAKEFLAGS
から -n オプションを継承します。入れ子 (階層構造) になった make はそれぞれ MAKEFLAGS
マクロによって -n オプションが指定されていることを認識していきます。このため、-n オプションを使用することで、入れ子になった make の動作を実際に実行せずに確認することができます。
# 他のディレクトリに生成されるターゲット用の最初のエントリ ../lib/libpkg.a: cd ../lib ; $(MAKE) libpkg.a
ライブラリは、現在のディレクトリからの相対パス名で指定します。プロジェクトが新しいルートディレクトリまたはマシンに移動された場合に、新しいルートディレクトリに対するディレクトリ構造がそのまま同じであれば、すべてのターゲットエントリが正しいファイルを示します。
入れ子にした make のコマンド行では、定義済みマクロ MAKE
の場合と同様に、動的マクロの修飾子の F および D が便利です。処理されるターゲットがパス名で指定されている場合は、$(@F) はファイル名部分、$(@D) はディレクトリ部分をそれぞれ示します。ターゲット名に / という文字が含まれていない場合は、$(@D) の値としてドット (.) が値として割り当てられます。
ターゲットエントリは、次のように書き換えることができます。
# 2 番目のエントリ ../lib/libpkg.a: cd $(@D); $(MAKE) $(@F)
このターゲットには依存関係がないため、../lib/libpkg.a という名前のファイルがないときにだけこのターゲットが実行されます。ファイルが .PRECIOUS により保護されたライブラリアーカイブである場合は、../lib/libpkg.a ファイルがないということはほとんどありません。make はそのファイルの依存関係を認識する必要はないため、認識しません。ファイルを構築するかどうか、およびその構築方法は、入れ子にした呼び出しによって決定されます。
つまり、ファイルシステム内にファイルがあっても、そのファイルが最新でない場合もあります。したがって、ファイルがあるかどうかに関わらず、そのファイルを規則が空白の (および既存のファイルがない) 他のターゲットに依存させることによって、入れ子にした make コマンドを強制的に実行する必要があります。
表 4-15 入れ子にした make コマンド用のターゲットエントリ
# 入れ子にした make コマンド用 # ターゲットエントリ ../lib/libpkg.a: FORCE cd $(@D); $(MAKE) $(@F) FORCE: |
この方法により、make は、正しいディレクトリ ../lib に変更し、そのディレクトリにあるメークファイルに記述された命令に従って、必要であれば libpkg.a を構築します。入れ子にした make の実行結果は次のようになります。
$ make ../lib/libpkg.a cd ../lib; make libpkg.a make libpkg.a `libpkg.a' is up to date.
以下のメークファイルは、入れ子にした make コマンドを使用して、プログラムが依存するユーザー定義のライブラリを処理します。
表 4-16 ユーザー定義のライブラリを使用した C プログラム用のメークファイル
../lib/libpkg.a が最新である場合は、このメークファイルを使用する make の実行結果は以下のようになります。
$ make cc -O -c main.c cc -O -c data.c cd ../lib; make libpkg.a `libpkg.a' is up to date. cc -O -o functions main.o data.o ../lib/libpkg.a -lcurses -l termlib
MAKEFLAGS
マクロ
MAKE
マクロと同様に、MAKEFLAGS
も特殊マクロです。
MAKEFLAGS
をメークファイル中に定義しないでください。
MAKEFLAGS
には、make コマンド用のフラグ (1 文字のオプション) が含まれています。他の FLAGS マクロとは異なり、MAKEFLAGS
の値は、フラグの冒頭に付いている - (ハイフン) を除いて連結したものになります。たとえば、eiknp という文字列は、MAKEFLAGS
の値として認識されますが、-f x.mk や macro=value は値として認識されません。
MAKEFLAGS
という環境変数が設定されている場合は、make は、コマンド行で指定されたフラグと、MAKEFLAGS
に含まれるフラグを組み合わせて実行されます。
MAKEFLAGS
の値は、環境変数で設定されているかどうかに関係なく常にエクスポートされ、MAKEFLAGS
に含まれるオプションは、($(MAKE)、make、/usr/bin/make のうちどれによって呼び出されたかに関係なく) 入れ子にした make コマンドに渡されます。これにより、親の make が呼び出された際のオプションが、入れ子にした make コマンドに渡されます。