プログラミングユーティリティ

大規模なライブラリを分割して管理する

大規模なライブラリは、複数の補助ライブラリに分割し、完全なパッケージを構築する際に make を使用して 1 つに結合すると、管理が簡単になる場合があります。ar を使用してライブラリを直接結合することはできませんが、以下の例に示すように、まず各補助ライブラリのメンバーファイルを取り出し、次に別の手順でそれらのファイルをアーカイブにまとめることができます。

$ ar xv libx.a 
x - x1.o 
x - x2.o 
x - x3.o 
$ ar xv liby.a 
x - y1.o 
x - y2.o 
$ ar rv libz.a *.o 
a - x1.o 
a - x2.o 
a - x3.o 
a - y1.o 
a - y2.o 
ar: creating libz.a

補助ライブラリは、そのライブラリを構築する (オブジェクト) ファイルとともに、そのディレクトリにあるメークファイルを使用して管理します。完成ライブラリ用のメークファイルは、各補助ライブラリアーカイブへのシンボリックリンクを作成し、アーカイブの内容を一時的なサブディレクトリに展開し、生成されたファイルをアーカイブして完全なパッケージを作成します。

次の例は、補助ライブラリを更新し、展開したファイルを保存する一時ディレクトリを作成して、補助ライブラリを展開します。一時ディレクトリでは、ワイルドカード * (シェル) を使用して、照合したファイルのリストを生成します。通常は、ファイル名にワイルドカードは使用しない方がよいですが、この例ではターゲットが構築されるたびに新しいディレクトリが作成されるため、使用が可能です。これによって、実行中make により展開されたファイルだけが一時ディレクトリに含まれます。


注 -

通常は、メークファイル中でシェルファイル名にワイルドカードを使用することは避けてください。使用する場合は、必要なファイルを一時サブディレクトリに移動することによって対称外のファイルを除外するような処理手順にしてください。


この例は、ディレクトリの命名規約を使用しています。ディレクトリ名は、そのディレクトリにあるライブラリのベース名から決定されます。たとえば、補助ライブラリの名前が libx.a の場合は、その補助ライブラリがあるディレクトリの名前は libx になります。

この例は、動的なマクロ参照での接尾辞置換を使用して、各サブディレクトリのディレクトリ名を取り出します。各ライブラリを順次取り出すためのループとしてシェルを使用します。また、ライブラリからパッケージを作成する際に、シェルコマンド置換を使用して、オブジェクトファイルを正しいリンク順に並び替えます (lordertsort を利用します)。最後に、一時ディレクトリおよびその内容を削除します。

# サブディレクトリで生成されたライブラリをまとめる Makefile

CFLAGS= -O 

.KEEP_STATE:
.PRECIOUS:  libz.a

all: lib.a 

libz.a: libx.a liby.a 
        	-rm -rf tmp 
        	-mkdir tmp 
        	set -x ; for i in libx.a liby.a ; ¥ 
              		do ( cd tmp ; ar x ../$$i ) ; done 
        	( cd tmp ; rm -f *_*_.SYMDEF ; ar cr ../$@ `lorder * | tsort` ) 
        	-rm -rf tmp libx.a liby.a 

libx.a liby.a: FORCE 
        	-cd $(@:.a=) ; $(MAKE) $@ 
        	-ln -s $(@:.a=)/$@ $@ 
FORCE: 

説明を簡潔にするため、この例では他の形式のプログラムと、cleaninstalltest ターゲットはサポートしていません (ソースファイルがサブディレクトリにあるため、適用できません)。

インデントされた行にある rm -f *_*_.SYMDEF というコマンドは、補助ライブラリのシンボルテーブル (補助ライブラリに対して ar を実行すると生成されます) がこの完成ライブラリ libz.a にアーカイブされないようにします。

入れ子にした make コマンドは現在のライブラリを処理する前に補助ライブラリを構築するため、現在のディレクトリにある補助ライブラリとオブジェクトファイルの両方から構築されるライブラリ用にこのメークファイルを拡張できます。オブジェクトファイルのリストを、ライブラリの依存関係リストに追加する必要があります。また、そのオブジェクトファイルを、補助ライブラリから展開したオブジェクトファイルと照合するための一時サブディレクトリにコピーするためのコマンドを追加する必要があります。

# サブディレクトリで生成されたライブラリと、オブジェクトをまとめる Makefile

CFLAGS= -O 

.KEEP_STATE:
.PRECIOUS:  libz.

OBJECTS= map.o calc.o draw.o

all: libz.a 

libz.a: libx.a liby.a $(OBJECTS) 
         	-rm -rf tmp 
         	-mkdir tmp 
         	-cp $(OBJECTS) tmp 
          set -x ; for i in libx.a liby.a ; ¥ 
              		do ( cd tmp ; ar x ../$$i ) ; done 
         	( cd tmp ; rm -f *_*_.SYMDEF ; ar cr ../$@ ¥
                `lorder * | tsort` ) 
          -rm -rf tmp lix.a liby.a 

libx.a liby.a: FORCE 
         	-cd $(@:.a=) ; $(MAKE) $@ 
         	-ln -s $(@:.a=)/$@ $@ 
FORCE: