![コンパイル段階でライブラリの場所をリンクしてもプログラムを実行する前にLD_LIBRARY_PATHを設定する必要があるのはなぜですか? [コピー]](https://linux33.com/image/127967/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E6%AE%B5%E9%9A%8E%E3%81%A7%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E5%A0%B4%E6%89%80%E3%82%92%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%97%E3%81%A6%E3%82%82%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B%E5%89%8D%E3%81%ABLD_LIBRARY_PATH%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B%E5%BF%85%E8%A6%81%E3%81%8C%E3%81%82%E3%82%8B%E3%81%AE%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F%20%5B%E3%82%B3%E3%83%94%E3%83%BC%5D.png)
私はコンパイルされたモデルを使用していますmake
。このモデルには、Makefile
同様のフラグを使用してソースコードを依存ライブラリに関連付けるフラグがあります-L/lib1 -L/lib2
。ただし、モデルを実行しようとすると、環境変数も確認しないと失敗します。
export LD_LIBRARY_PATH=/lib1:/lib2
そしてまったく同じライブラリを指します。これは私に重複しているようです。
ここで何が起こっているのでしょうか?コンパイル前と実行前にライブラリの場所を指定する必要があるのはなぜですか?
これはおそらく愚かな質問です。私はマシンコードをコンパイルする経験がほとんどなく、通常スクリプト言語を使用します。
答え1
誰もが口語でコンパイルを使用してソースコードを実行可能ファイルに変換しますが、技術的にはかなり長いパイプラインの1つのステップです。
- 入力ファイルはプリプロセッサを介して実行され、単一の翻訳単位を生成します。
- プリプロセッサの出力はアセンブリにコンパイルされます。
- アセンブラはそれを入力として受け取り、オブジェクトファイルを出力します。
- リンカはオブジェクトファイルを一緒にリンクして実行ファイルを生成します。
[厳密に言えば、これらのステップを分離する必要はなく、現代のコンパイラは効率のためにしばしばそれらを組み合わせます。 ]
私たちが興味を持っているのは、コードを標準のシステムライブラリと組み合わせるリンクステップです。リンカは、静的ライブラリのオブジェクトを実行可能ファイルに直接コピーします。ただし、共有ライブラリの場合は、ライブラリへの参照のみを提供します。
共有ライブラリには多くの利点があります。プログラムを再コンパイルせずに更新することができ、プログラムが共通のコードを共有できるため、メモリの使用量が少なくなります。また、コードが実行可能ファイルにないという明らかな欠点もあります。
ソリューションは、実行時にすべての共有ライブラリ参照を解決する動的ローダです。ローダーは自動的に実行されます。これを行うためのガイドラインは、リンカが実行可能ファイルに含めることです。もちろん、ローダーがこれらのライブラリを見つけることができると仮定します。
システムライブラリは標準ディレクトリにあるので簡単です。そうでない場合、ローダーはLD_LIBRARY_PATHを検索します。リンカが実行可能ファイルにパスを入力しないのはなぜですか?なぜなら、ライブラリを移動または変更できないからです。
実際、ライブラリはシステム検索パスの外にあるため、実際に実行可能ファイルを移動することもできません。ライブラリが ~luke/lib にある場合にのみ実行される場合、joe がファイルを読み取れないと joe に与えることはできません。新しい職場を救えば、ジョーは迷惑になる。
参考までに、他のさまざまな方法で吸収されます。コンパイル時にのみライブラリの場所などを指定できる場合、デバッグは永遠の悪夢になります。