web-dev-qa-db-ja.com

コンパイル時に共有ライブラリが必要なのはなぜですか

実行可能ファイルのコンパイル時に共有ライブラリの存在が必要なのはなぜですか?私の推論は、共有ライブラリは実行可能ファイルに含まれておらず、実行時にロードされるため、コンパイル時に必要になることは想定されていないということです。または私は何かが欠けていますか?

_#include<stdio.h>
int addNumbers(int, int); //prototype should be enough, no? 
int main(int argc, char* argv[]){
  int sum = addNumbers(1,2);
  printf("sum is %d\n", sum);
  return 0;
}
_

現在のディレクトリに_libfoo.so_がありましたが、名前を_libfar.so_に変更して、コンパイル時に共有ライブラリが必要であるか、コンパイルされないことを確認しました。

_gcc -o main main.c -L. -lfoo_はmain.c:(.text+0x28): undefiend reference to 'addNumber'を与えます

共有ライブラリの名前だけで十分だと思います。共有ライブラリ自体はLD_LIBRARY_PATHにあり、実行時に動的にロードされるため、必要ありません。共有ライブラリの名前以外に必要なものはありますか?

12
Gab是好人

Cには翻訳単位の個別のコンパイルの概念があるため、コンパイルの時点では何も必要ありません。しかし、すべての異なるソースがコンパイルされたら、すべてをリンクする時が来ました。共有ライブラリの概念は標準には存在しませんが、今では一般的なものになっているため、commonリンカーがどのように進行するかを次に示します。

  • コンパイルされたすべてのモジュールで、定義された、または宣言されただけの外部リンケージを持つ識別子を探します
  • ライブラリ(静的および動的の両方)で、すでに使用され、定義されていない識別子を探します。次に、静的ライブラリからのモジュールをリンクし、動的ライブラリからの参照を格納します。しかし、少なくともUnixライクでは、共有ライブラリにアクセスして、潜在的に必要な(宣言され、定義されていない)識別子を取得して、それらがすでに定義されているか、静的または動的な他のリンクライブラリで見つかることを確認する必要があります。

これにより、実行可能ファイルが生成されます。次に、ロード時に、ダイナミックローダーは必要なすべてのダイナミックモジュールを認識し、実際の実行可能ファイルとともにメモリにロードし(まだ存在しない場合)、(仮想)メモリマップを構築します。

6
Serge Ballesta
gcc -o main main.c -L. -lfoo

このコマンドは(少なくとも)2つのステップを実行します:compile main.cをオブジェクトファイルにリンクし、すべてのリソースを実行可能ファイルmainにリンクします。表示されるエラーは、最後のステップであるリンカーからのものです。

リンカは、最終的な実行可能マシンコードを生成する責任があります。共有オブジェクトライブラリが必要なのは、それをロードして、そこで使用される関数を実行するマシンコードを生成する必要があるためです。

0
Code-Apprentice