c++ - programacion - ¿Por qué el indicador del enlazador de la biblioteca a veces tiene que ir al final usando GCC?
librerias estaticas y dinamicas c++ (2)
Estoy escribiendo un pequeño programa de C que usa librt. Estoy bastante sorprendido de que el programa no se compile si coloco el indicador de enlace al comienzo en lugar de al final:
Por el momento, para compilar el programa que hago:
gcc -o prog prog.c -lrt -std=gnu99
Si tuviera que hacer lo siguiente, no podrá encontrar las funciones en librt:
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 que obtendría al escribir make 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 he creado un Makefile que pone el enlace al final de la línea de gcc, sin embargo, estoy desconcertado por qué no funciona si el marcador de enlace está en el inicio.
Agradecería si alguien me puede explicar esto. Gracias.
A medida que el enlazador procesa cada módulo (ya sea una biblioteca o un archivo objeto), intenta resolver cada símbolo indefinido al tiempo que 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, seguido de las bibliotecas proporcionadas por la plataforma.
Espero que esto ayude.
De la documentación ld
(el enlazador GNU) ( http://sourceware.org/binutils/docs/ld/Options.html#Options ):
El vinculador buscará un archivo solo una vez, en la ubicación donde se especifica en la línea de comando. 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.
Por lo tanto, 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í.