2012-02-23 20 views
16

Estoy escribiendo un pequeño programa en C que usa librt. Estoy bastante sorprendido de que el programa no compilará si coloco la bandera de enlace al comienzo en lugar de al final:¿Por qué el indicador del vinculador de la biblioteca a veces tiene que ir al final usando GCC?

Por el momento, para compilar el programa que hago:

gcc -o prog prog.c -lrt -std=gnu99

Si tuviera que hacer lo siguiente, no será capaz de encontrar las funciones en librtad:

gcc -std=gnu99 -lrt -o prog prog.c

Sin embargo, esto funciona con otras bibliotecas. Encontré el problema cuando intento usar un simple Makefile. hacer prog.c realmente compilado sin agrado primero (usando el indicador -c) y luego hizo el enlace.

Este es el Makefile:

CC = gcc 

CFLAGS = -std=gnu99 

LIBS= -lrt 

LDFLAGS := -lrt 


prog: prog.o 

     $(CC) -o prog prog.c -lrt -std=gnu99 

La salida me gustaría tener al escribir cometer sería:

gcc -std=gnu99 -c -o prog.o prog.c 
gcc -lrt prog.o -o prog 
prog.o: In function `main': 
prog.c:(.text+0xe6): undefined reference to `clock_gettime' 
prog.c:(.text+0x2fc): undefined reference to `clock_gettime' 
collect2: ld returned 1 exit status 
make: *** [buff] Error 1 

ahora han elaborado un Makefile que pone el enlace al final de la gcc línea, sin embargo, estoy desconcertado por qué no funciona si la bandera de enlace está en el inicio.

Agradecería que alguien pudiera explicarme esto. Gracias.

+1

No estoy al 100% en esto, pero creo que el enlazador podría estar buscando librt y decidiendo que no necesita nada, así que simplemente deséchelo. ¿Es librt una biblioteca estática? – spencercw

+0

Consulte las respuestas a esta pregunta para obtener una explicación de por qué el enlace estático depende de la orden: http: //stackoverflow.com/questions/45135/linker-order-gcc –

+2

Puede estar relacionado con la opción * del enlazador * según sea necesario. por defecto. Podría intentar 'gcc -std = gnu99 -Wl, -no-as-needed -lrt -o prog prog.c' –

Respuesta

19

A medida que el enlazador procesa cada módulo (ya sea una biblioteca o un archivo de objeto), intenta resolver cada símbolo indefinido mientras agrega potencialmente a su lista de símbolos indefinidos. Cuando llega a la lista de módulos, ya sea que ha resuelto todos los símbolos indefinidos y es exitoso o informa símbolos indefinidos.

En su caso, cuando procesaba librt, no tenía símbolos indefinidos. El proceso de procesamiento resultó en clock_gettime como un símbolo indefinido. gcc no volverá y buscará en librt los símbolos indefinidos.

Por esa razón, siempre debe tener su código primero, seguido de sus bibliotecas, seguidas de las bibliotecas proporcionadas por la plataforma.

Espero que esto ayude.

+1

Nota secundaria: el orden de los archivos de objeto no son importantes; un archivo de objeto que hace referencia a un símbolo en otro archivo de objeto no necesariamente tiene que aparecer en la línea de comando. Lo cual tiene sentido, por supuesto, si considera que todos los símbolos de un archivo objeto se incluyen en la imagen final, incluso si todavía no hay referencia indefinida a ellos, y así se agrega a la lista de símbolos definidos, por lo que una referencia posterior en otro archivo objeto no conducirá a un símbolo indefinido. – eriktous

+0

@eriktous Gracias por la corrección. – Lou

11

De la documentación ld (el enlazador de GNU) (http://sourceware.org/binutils/docs/ld/Options.html#Options):

El enlazador buscará un archivo sólo una vez, en el lugar en el que se especifica en la línea de comandos. Si el archivo define un símbolo que no estaba definido en algún objeto que apareció antes del archivo en la línea de comando, el vinculador incluirá los archivos correspondientes del archivo. Sin embargo, un símbolo indefinido en un objeto que aparece más adelante en la línea de comando no hará que el vinculador busque nuevamente en el archivo.

Si especifica la biblioteca demasiado pronto, el vinculador la escaneará, pero no encontrará nada de interés. Luego, el enlazador pasa al archivo de objeto producido por el compilador y encuentra referencias que deben ser resueltas, pero ya ha escaneado la biblioteca y no se molestará en volver a buscar allí.

Cuestiones relacionadas