2012-05-14 15 views
5

Tengo algunas preguntas sobre el orden de enlace gcc. El hombre de GCC dice los símbolos de búsqueda del enlazador de izquierda a derecha sin repetir la búsqueda por defecto. Aquí está mi prueba:algunas preguntas sobre el orden de búsqueda del enlazador 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 

A partir del resultado, podemos ver el orden de .oy .o, .oy .so no importa, solo el orden de .o y .a tiene el efecto. Pero eso no es coherente con la página del manual de gcc. ¿Entonces por qué?

+0

He usado -v, pero aún no entiendo por qué. ¿Puedes explicar esto en detalle? – D3Hunter

+0

No puedo usar -nodefaultlibs, para algunas funciones en crt como _start debería existir. – D3Hunter

+0

Supongo que soy TL; DR-ed antes. ¿De qué manera crees que 'esto' es inconsistente con la página de gcc amn? – sehe

Respuesta

8

gcc procesa los archivos de objetos de izquierda a derecha. Cuando se tiene

gcc -o test libprintf.a main.o 

La primera gcc fichero objeto que ve es libprintf.a. No hay símbolos no resueltos para el objeto de salida en este punto, por lo que no se usa ni se necesita nada de libprintf.a. A continuación, se procesa main.o, el vinculador toma nota del hecho de que printf no está resuelto, y luego procede a procesar las bibliotecas implícitas donde es capaz de resolver el printf símbolo que no se resolvió in main.o.

Del mismo modo, cuando se tiene:

gcc -o test main.o libprintf.a 

El primer archivo de objeto a procesar se main.o, donde se observa el símbolo sin resolver printf, el siguiente en ser procesada es libprintf.a de la que el enlazador es capaz de resolver printf. Cuando libc se procesa finalmente, printf ya está resuelto, por lo que no se utiliza la instancia de printf en libc.

Cuando se enlaza con archivos .o:

gcc -o test main.o printf.o 

La biblioteca libc se trata de nuevo como si se especificó al final de la línea de comandos, por lo que el símbolo printf se resuelve desde el primero (de izquierda a -right) archivo objeto que lo define.

Para las dos cajas libprintf.so, la biblioteca libc se trata de nuevo como si se hubiera especificado al final de la línea de comando. Lo que es diferente del caso de biblioteca estática es que el ordenamiento de izquierda a derecha de las bibliotecas *.so determina el orden de búsqueda de símbolos dinámicos en tiempo de ejecución. Dado que esta orden tiene libprintf.so antes del implícito libc.so, se utiliza la versión de printf en libprintf.so.

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

Como un experimento adicional, usted podría intentar:

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

Esto debería mostrar la versión de printf se pueda utilizar desde libc.so en lugar de libprintf.so porque -lc viene antes libprintf.so en orden de izquierda a derecha.

+0

Entonces, ¿por qué .o y .o, .o y .so no funcionan? – D3Hunter

+0

Editado para agregar explicaciones para estos casos ... perdón por descuidar aquellos en la respuesta inicial. –

Cuestiones relacionadas