Oracle® Solaris 11.2 リンカーとライブラリガイド

印刷ビューの終了

更新: 2014 年 7 月
 
 

未使用の依存関係の削除

明示的な共有オブジェクト依存関係は、コマンド行でパス名または (より一般的には) –l オプションを使用して定義されます。明示的な依存関係には、コンパイラドライバ (–lc など) によって提供された可能性があるものも含まれます。

暗黙の依存関係は、明示的な依存関係の依存関係です。暗黙の依存関係は、すべてのシンボル解決の封じ込めを完成させるため、リンク編集の一部として処理できます。このシンボルの封じ込めにより、構築中のオブジェクトが自己完結型であり、未参照のシンボルが残っていないことが保証されます。

すべての動的オブジェクトは、必要な依存関係を定義すべきです。この要件は、動的実行可能ファイルを構築するときはデフォルトで適用されますが、共有オブジェクトを構築するときには適用されません。共有オブジェクトを構築するときにこの要件を適用するには、–z defs オプションを使用します。

どの動的オブジェクトでも、必要としない依存関係を定義することは避けてください。実行時にこのような未使用の依存関係をロードすることは不要であり無駄です。

明示的な依存関係は、2 つの条件が真である場合に未使用と判定されます。

  • その依存関係によって提供される大域シンボルが、構築中のオブジェクトから参照されていません。

  • その依存関係は、暗黙の依存関係の要件を補いません。

未使用の依存関係は、–z guidance オプションを使用して診断します。これらの依存関係はリンク編集から削除してください。ただし、これらの項目の削除に問題がある場合は、–z discard-unused=dependencies オプションを使用すると、未使用の依存関係を構築中のオブジェクトから破棄できます。

残念ながら、必要とする一部の依存関係を定義していない共有オブジェクトが存在しています。これらの場合、開発者はしばしば、元の依存関係を正確に再構築するのではなく、失われた依存関係を実行可能ファイルや構築しているほかの共有オブジェクトに追加します。このような依存関係は、補完依存関係と呼ばれます。

たとえば、共有オブジェクト bar.so からシンボル bar() を参照する共有オブジェクト foo.so を考えてみます。ただし、foo.so には bar.so への依存関係が示されていません。foo.so を調べた結果、シンボル bar() が見つからないので必要な依存関係が欠如しているとわかります。

% ldd -r foo.so
     libc.so.1 =>     /lib/libc.so.1
     symbol not found: bar           (foo.so)

ここで、共有オブジェクト foo.so からシンボル foo() を参照する実行可能ファイルを作成する必要のあるアプリケーション開発者を考えてみます。foo.so への必要な依存関係を指定しますが、実行可能ファイルのリンク編集は失敗します。

% cc -Bdirect -o main main.c -L. -lfoo
Undefined                       first referenced
  symbol                             in file
  bar                                 ./libfoo.so
ld: fatal: symbol referencing errors

開発者は、bar.so への補完依存関係を追加して、この状況を強制的に修正します。

% cc -Bdirect -o main main.c -L. -lfoo -lbar

この修正によって、実行時に必要なすべて依存関係をロードするアプリケーションが作成され、問題は解決したように見えます。ただし、この結果は盤石ではありません。将来、bar.so からのシンボルを必要としない foo.so が配信されれば、このアプリケーションは理由もなく bar.so をロードすることになります。より適切な解決方法は、失われた依存関係 bar.so を追加して foo.so を修正するというものです。

補完依存関係の出現はガイダンスを通じて診断されます。

% cc -Bdirect -zguidance -o main main.c -L. -lfoo -lbar
ld: guidance: removal of compensating dependency recommended: libbar.so

補完依存関係はガイダンスを通じて診断されますが、–z discard-unused=dependencies から削除されません。依存関係は作成されているオブジェクトに関して使用されない場合もありますが、リンク編集のほかのコンポーネントで使用されます。この依存関係を削除すると、実行時に実行できないオブジェクトが作成されることになります。

補完依存関係は、計画的に –z defs オプションを使用してすべての動的オブジェクトを構築することで不要になります。

–z ignore および –z record オプションは、–z discard-unused=dependencies オプションと組み合わせて使用できる定位置オプションです。これらの定位置オプションは、対象となるオブジェクトを選択して、破棄機能をオンまたはオフにします。