GCCリンクライブラリのピット:動的在庫があるのに動的ライブラリが定義されていない関数を求める
3254 ワード
背景
GCCではリンクライブラリが指定されていますが、コンパイル時にダイナミックライブラリ関数が定義されていないことを求められます.
テストで発生したエラーメッセージは次のとおりです.
[GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c
/tmp/ccysQZI3.o: ‘main’ :
test.c:(.text+0x1a): ‘func_lib’
collect2: error: ld returned 1 exit status
テスト用の動的ライブラリ
libmylib.so
には定義関数func_lib
がある[GMPY@13:55 tmp]$cat mylib.c
#include
int func_lib(void)
{
printf("In share library
");
return 0;
}
[GMPY@13:56 tmp]$gcc -fPIC -shared mylib.c -o libmylib.so
GCCのリンクピット
ここでの「ピット」とは、GCCの仕組みに慣れていない子供靴にとって、理解できない予想外の効果が現れることを意味します
gccでコンパイルする場合は、
-L
でリンクライブラリの位置を指定し、-l
で指定できます.man gcc
クエリーで、次の説明を見つけました.-llibrary
-l library
... ## ,
It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in the order they are specified.
Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o.
If bar.o refers to functions in z, those functions may not be loaded.
...
ええと、この話はどういう意味ですか.
-l
リンクライブラリがソースコードの前にあると、ライブラリにリンクできません!!次の2つのコマンドの違いのように、
:gcc -o test -L. -lmylib test.c
:gcc -o test -L. test.c -lmylib
実行時のパラメータの位置が要求されるなんて、酔ってしまいます
GCCのリンク手順
@firstrose提供の原理説明リンクに感謝します
GCCは
-l
をどのように理解していますか?A library is a collection (an archive) of object files. When you add a library using the -l option,
the linker does not unconditionally take all object files from the library. It only takes those object
files that are currently needed, i.e. files that resolve some currently unresolved (pending) symbols.
After that, the linker completely forgets about that library.
The list of pending symbols is continuously maintained by the linker as the linker processes input
object files, one after another from left to right. As it processes each object file, some symbols get
resolved and removed from the list, other newly discovered unresolved symbols get added to the list.
So, if you included some library by using -l, the linker uses that library to resolve as many currently
pending symbols as it can, and then completely forgets about that library. If it later suddenly
discovers that it now needs some additional object file(s) from that library, the linker will not "return"
to that library to retrieve those additional object files. It is already too late.
どういう意味ですか.つまり、GCCリンクは次の手順でファイルをリンクします.
GCCリンクの「始末が悪い」だけに、
-l
のライブラリを検索した後、このライブラリを捨ててしまい、後で使う必要がある場合、自然と見つからなくなりますGCCは、以前にリンクされたライブラリを検索するために振り返ることはありません.
このようなリンクステップから、次のような特性があると推測します.
GCCリンクライブラリは、最初に指定したライブラリで定義されていないすべての関数、変数を「貪欲に一致」するため、
2つのライブラリに同じ関数、変数の定義がある場合でも、最初に見つかったライブラリの定義のみが使用されます.
転載先:https://www.cnblogs.com/gmpy/p/11089572.html