2012-05-14 15 views
5

Ho alcune domande sull'ordine di gcc link. GCC man dice che i simboli di ricerca del linker vanno da sinistra a destra senza ripetere la ricerca di default. Qui è la mia prova:alcune domande sull'ordine di ricerca del linker 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 

Dal risultato, possiamo vedere l'ordine di .o e .o, .o e .so non fa differenza, solo l'ordine di .o e .a ha l'effetto. Ma questo è incoerente con la pagina man di gcc. Allora perché?

+0

Ho usato -v, ma ancora non capisco perché. Puoi spiegarlo in dettaglio? – D3Hunter

+0

Non posso usare -nodefaultlibs, per alcune funzioni in crt come _start dovrebbero esistere. – D3Hunter

+0

Suppongo che TL, DR-ed prima. In che modo pensi che "it" sia incoerente con la pagina gcc amn? – sehe

risposta

8

gcc elabora effettivamente i file oggetto da sinistra a destra. Quando si dispone di

gcc -o test libprintf.a main.o 

Il primo gcc file oggetto vede è libprintf.a. Non ci sono simboli non risolti per l'oggetto di output a questo punto, quindi nulla viene utilizzato/necessario da libprintf.a. Successivamente, viene elaborato main.o, il linker prende nota del fatto che printf non è risolto e quindi procede all'elaborazione delle librerie implicite in cui è in grado di risolvere il simbolo printf non risolto in main.o.

Allo stesso modo, quando si dispone di:

gcc -o test main.o libprintf.a 

Il primo file oggetto da lavorare main.o, in cui si nota il simbolo non risolto printf, il prossimo da lavorare libprintf.a da cui il linker è in grado di risolvere printf. Quando viene elaborato il numero libc, printf è già stato risolto, quindi non viene utilizzata l'istanza di printf in libc.

Quando si collega con i file .o:

gcc -o test main.o printf.o 

La biblioteca libc è ancora trattato come se è stato specificato alla fine della riga di comando, in modo che il simbolo printf viene risolto dal primo (da sinistra a -right) file oggetto che lo definisce.

Per entrambi i casi libprintf.so, la libreria libc viene nuovamente trattata come se fosse stata specificata alla fine della riga di comando. Ciò che è diverso dal caso di libreria statica è che l'ordinamento da sinistra a destra delle librerie *.so determina l'ordine di ricerca dei simboli dinamici di runtime. Poiché questo ordine ha libprintf.so prima dell'implicito libc.so, viene utilizzata la versione di printf in libprintf.so.

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

Come un ulteriore esperimento, si potrebbe provare:

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

Questo dovrebbe mostrare la versione di printf essere utilizzato da libc.so invece di libprintf.so perché -lc viene prima di libprintf.so in ordine da sinistra a destra.

+0

Quindi perché .o e .o, .o e .so non funzionano? – D3Hunter

+0

Modificato per aggiungere spiegazioni per questi casi ... mi dispiace per aver trascurato quelli nella risposta iniziale. –

Problemi correlati