依存関係の場所に関するもう 1 つの問題は、バンドルされていない製品同士の依存関係を表現するモデルを、どのようにして確立するかです。
たとえば、バンドルされていない製品 XYZ は製品 ABC に対して依存関係を持つ場合があります。この依存関係を確立するには、ホストパッケージインストールスクリプトを使用します。このスクリプトは ABC 製品のインストール位置へのシンボリックリンクを生成します (次の図を参照)。
図 10-2 バンドルされていない製品の「相互依存関係」
XYZ 製品のバイナリおよび共有オブジェクトは、シンボリックリンクを使用して、ABC 製品との依存関係を表現できます。このリンクはその時点で、安定した参照点になります。アプリケーション xyz の場合、この「実行パス」は次のようになります。
$ cc -o xyz xyz.c '-R$ORIGIN/../lib:$ORIGIN/../ABC/lib' \
-L/opt/ABC/lib -lX -lA
$ elfdump -d xyz | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x1b5 libX.so.1
[1] NEEDED 0x1bf libA.so.1
....
[2] NEEDED 0x18f libc.so.1
[5] RUNPATH 0x1c9 $ORIGIN/../lib:$ORIGIN/../ABC/lib
libX.so.1 の依存関係でも同様に、この実行パスは次のようになります。
$ cc -o libX.so.1 -G -Kpic X.c '-R$ORIGIN:$ORIGIN/../ABC/lib' \
-L/opt/ABC/lib -lY -lC
$ elfdump -d libX.so.1 | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x96 libY.so.1
[1] NEEDED 0xa0 libC.so.1
[5] RUNPATH 0xaa $ORIGIN:$ORIGIN/../ABC/lib
次にこの製品が /usr/local/XYZ 内にインストールされた場合、インストール後のスクリプトによってシンボリックリンクを確立する必要があります。
$ ln -s ../ABC /usr/local/XYZ/ABC
ユーザーの PATH に /usr/local/XYZ/bin が追加されると、アプリケーション xyz の呼び出しによって、次のようにパス名検索でその依存関係が検索されます。
$ ldd -s xyz
....
find object=libX.so.1; required by xyz
search path=$ORIGIN/../lib:$ORIGIN/../ABC/lib (RUNPATH/RPATH from file xyz)
trying path=/usr/local/XYZ/lib/libX.so.1
libX.so.1 => /usr/local/XYZ/lib/libX.so.1
find object=libA.so.1; required by xyz
search path=$ORIGIN/../lib:$ORIGIN/../ABC/lib (RUNPATH/RPATH from file xyz)
trying path=/usr/local/XYZ/lib/libA.so.1
trying path=/usr/local/ABC/lib/libA.so.1
libA.so.1 => /usr/local/ABC/lib/libA.so.1
find object=libY.so.1; required by /usr/local/XYZ/lib/libX.so.1
search path=$ORIGIN:$ORIGIN/../ABC/lib \
(RUNPATH/RPATH from file /usr/local/XYZ/lib/libX.so.1)
trying path=/usr/local/XYZ/lib/libY.so.1
libY.so.1 => /usr/local/XYZ/lib/libY.so.1
find object=libC.so.1; required by /usr/local/XYZ/lib/libX.so.1
search path=$ORIGIN:$ORIGIN/../ABC/lib \
(RUNPATH/RPATH from file /usr/local/XYZ/lib/libX.so.1)
trying path=/usr/local/XYZ/lib/libC.so.1
trying path=/usr/local/ABC/lib/libC.so.1
libC.so.1 => /usr/local/ABC/lib/libC.so.1
find object=libB.so.1; required by /usr/local/ABC/lib/libA.so.1
search path=$ORIGIN (RUNPATH/RPATH from file /usr/local/ABC/lib/libA.so.1)
trying path=/usr/local/ABC/lib/libB.so.1
libB.so.1 => /usr/local/ABC/lib/libB.so.1