実行可能ファイルのコンパイル時に共有ライブラリの存在が必要なのはなぜですか?私の推論は、共有ライブラリは実行可能ファイルに含まれておらず、実行時にロードされるため、コンパイル時に必要になることは想定されていないということです。または私は何かが欠けていますか?
_#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にあり、実行時に動的にロードされるため、必要ありません。共有ライブラリの名前以外に必要なものはありますか?
Cには翻訳単位の個別のコンパイルの概念があるため、コンパイルの時点では何も必要ありません。しかし、すべての異なるソースがコンパイルされたら、すべてをリンクする時が来ました。共有ライブラリの概念は標準には存在しませんが、今では一般的なものになっているため、commonリンカーがどのように進行するかを次に示します。
これにより、実行可能ファイルが生成されます。次に、ロード時に、ダイナミックローダーは必要なすべてのダイナミックモジュールを認識し、実際の実行可能ファイルとともにメモリにロードし(まだ存在しない場合)、(仮想)メモリマップを構築します。
gcc -o main main.c -L. -lfoo
このコマンドは(少なくとも)2つのステップを実行します:compile main.c
をオブジェクトファイルにリンクし、すべてのリソースを実行可能ファイルmain
にリンクします。表示されるエラーは、最後のステップであるリンカーからのものです。
リンカは、最終的な実行可能マシンコードを生成する責任があります。共有オブジェクトライブラリが必要なのは、それをロードして、そこで使用される関数を実行するマシンコードを生成する必要があるためです。