通常、バンドルされていない製品は、固有の場所にインストールされるように設計されています。この製品は、バイナリ、共有オブジェクト、および関連構成ファイルからなります。たとえば、バンドルされていない製品 ABC は、次の配置をとる場合があります。
図 10-1 バンドルされていない製品の相互依存関係
製品が、/opt の元にインストールされるように設計されていると想定します。通常、PATH に /opt/ABC/bin を追加して、製品のバイナリの位置を特定します。各バイナリは、バイナリ内に直接記録された「実行パス」を使用して、その依存する相手を探します。アプリケーション abc の場合、この「実行パス」は次のようになります。
$ cc -o abc abc.c -R/opt/ABC/lib -L/opt/ABC/lib -lA
$ elfdump -d abc | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x1b5 libA.so.1
....
[4] RUNPATH 0x1bf /opt/ABC/lib
libA.so.1 の依存関係でも同様に、実行パスは次のようになります。
$ cc -o libA.so.1 -G -Kpic A.c -R/opt/ABC/lib -L/opt/ABC/lib -lB
$ elfdump -d libA.so.1 | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x96 libB.so.1
[4] RUNPATH 0xa0 /opt/ABC/lib
この依存関係の表現は、製品が推奨されているデフォルト以外のディレクトリにインストールされるまで正常に作動します。
動的トークン $ORIGIN は、オブジェクトが存在するディレクトリに展開されます。このトークンは、フィルタ、「実行パス」、または依存関係の定義に利用できます。この機構を使用すると、バンドルされていないアプリケーションを再定義して、$ORIGIN との相対位置で依存対象の位置を示すことができます。
$ cc -o abc abc.c '-R$ORIGIN/../lib' -L/opt/ABC/lib -lA
$ elfdump -d abc | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x1b5 libA.so.1
....
[4] RUNPATH 0x1bf $ORIGIN/../lib
$ORIGIN との関係で libA.so.1 の依存関係を定義することもできます。
$ cc -o libA.so.1 -G -Kpic A.c '-R$ORIGIN' -L/opt/ABC/lib -lB
$ elfdump -d lib/libA.so.1 | egrep 'NEEDED|RUNPATH'
[0] NEEDED 0x96 libB.so.1
[4] RUNPATH 0xa0 $ORIGIN
次に、この製品が /usr/local/ABC 内にインストールされ、またユーザーの PATH に /usr/local/ABC/bin が追加された場合、アプリケーション abc を呼び出すと、次のようにパス名検索でその依存関係を検索することになります。
$ ldd -s abc
....
find object=libA.so.1; required by abc
search path=$ORIGIN/../lib (RUNPATH/RPATH from file abc)
trying path=/usr/local/ABC/lib/libA.so.1
libA.so.1 => /usr/local/ABC/lib/libA.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