2012-05-14 16 views
5

gccのリンク順についていくつか質問があります。 GCCの人間は、デフォルトで繰り返し検索することなく、左から右へリンカーの検索シンボルを言う。ここに私のテストです:結果からGCCリンカーの検索順序に関するいくつかの質問

main.cの

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
     printf("HELLO WROLD\n"); 
     return 0; 
} 

printf.c

#include <stdio.h> 
#include <stdlib.h> 

int printf(const char *fmt, ...) 
{ 
     write(1, "AAA\n", 4); 
} 

[[email protected] testcode]# gcc -c -fno-builtin-printf *.c 
[[email protected] testcode]# gcc -o test main.o printf.o 
[[email protected] testcode]# ./test 
AAA 
[[email protected] testcode]# gcc -o test printf.o main.o 
[[email protected] testcode]# ./test 
AAA 


[[email protected] testcode]# ar rcs libprintf.a printf.o 
[[email protected] testcode]# gcc -o test libprintf.a main.o 
[[email protected] testcode]# ./test 
HELLO WROLD 
[[email protected] testcode]# gcc -o test main.o libprintf.a 
[[email protected] testcode]# ./test 
AAA 


[[email protected] testcode]# gcc -shared -o libprintf.so printf.o 
[[email protected] testcode]# gcc -o test libprintf.so main.o 
[[email protected] testcode]# export LD_LIBRARY_PATH=. 
[[email protected] testcode]# ./test 
AAA 
[[email protected] testcode]# gcc -o test main.o libprintf.so 
[[email protected] testcode]# ./test 
AAA 

、我々は.oのとの.o、.oのとの順序を見ることができるの.so差をつけないと、.oと.aの順序だけが効果を持ちます。しかし、それはgccのマニュアルページとは矛盾しています。なぜ?

+0

私は-vを使用しましたが、それでも私は理由を理解していません。これについて詳しく説明できますか? – D3Hunter

+0

-nodefaultlibsは使用できません。たとえば、_startのようなcrtの一部の関数が存在する必要があります。 – D3Hunter

+0

私はTL; DR-ed前に推測します。どのようにして 'それ'がgccのamnページと矛盾していると思いますか? – sehe

答えて

8

gccは実際にオブジェクトファイルを左から右に処理します。あなたが持っているとき

gcc -o test libprintf.a main.o 

最初のオブジェクトファイルはlibprintf.aです。この時点で出力オブジェクトには未解決のシンボルはありませんので、libprintf.aからのものは何も使用/必要ありません。次に、main.oが処理され、リンカーはprintfが未解決であるという事実を書き留めて、未解決のprintfシンボルを解決できる暗黙のライブラリを処理します。in main.o

gcc -o test main.o libprintf.a 

処理する最初のオブジェクトファイルは、次に処理するには、リンカが解決することができ、そこからlibprintf.aある未解決のシンボルprintfが注目されるmain.o、されています。あなたが持っている同様に

printflibcが最終的に処理されるとき、printfが既に解決されているので、printfのインスタンスはlibcには使用されません。

.oファイルとリンク:

gcc -o test main.o printf.o 

それは、コマンドラインの最後に指定し、そうprintfシンボルが最初から解決されたかのようlibcライブラリが再び処理される(左からそれを定義するオブジェクトファイルです。

libprintf.soの両方の場合、libcのライブラリは、コマンドラインの最後に指定されたものとして扱われます。静的ライブラリの場合と異なる点は、ライブラリの左から右への順番がランタイム動的シンボルの検索順序を決定することです。この順番は暗黙的なlibc.soの前にlibprintf.soであるため、printfのバージョンはlibprintf.soになります。

gcc -o test libprintf.so main.o 
gcc -o test main.o libprintf.so 

追加実験として、あなたは試みることができる:

gcc -o test main.o -lc libprintf.so 

これはprintfのバージョンを表示する必要がありlibc.so代わりのlibprintf.soから使用されて-lcが左から右の順にlibprintf.so前に来るので。

+0

なぜ、.oと.o、.oと.soは動作しないのですか? – D3Hunter

+0

これらのケースの説明を追加するために編集...最初の応答では無視して申し訳ありません。 –

関連する問題