Pregunta

Tengo un problema con mi compilador que me dice que hay una 'referencia indefinida a' una función que quiero usar en una biblioteca. Permítame compartir algo de información sobre el problema:

  • Estoy compilando de forma cruzada con gcc para C.
  • Estoy llamando a una función de biblioteca a la que se accede a través de un encabezado incluido que incluye otro encabezado, que contiene el prototipo.
  • He incluido el directorio de encabezados con -I y estoy seguro de que se está encontrando.
  • Primero estoy creando los archivos .o y luego los vinculo en un comando separado.

Mi idea es que podría ser el orden en el que incluyo los archivos de la biblioteca, pero no estoy seguro de cuál es la forma correcta de ordenarlos. Intenté incluir la carpeta de encabezados antes y después del archivo .o.

Algunas sugerencias serían excelentes, y quizás una explicación de cómo el enlazador hace su trabajo.

¡Gracias!


Respuesta a las respuestas

  • no hay un archivo de biblioteca .a, solo .h y .c en la biblioteca, por lo que -l no es apropiado
  • mi entendimiento de un archivo de biblioteca es que es solo una colección de archivos de encabezado y fuente, ¡¿pero tal vez es una colección de archivos .o creados desde la fuente ?!
  • no se está creando ningún archivo de objeto de biblioteca, tal vez debería haber ?? Sí, parece que no entiendo la diferencia entre las bibliotecas incluidas y las incluidas ... trabajaré en eso :-)

Gracias por todas las respuestas! Aprendí mucho sobre las bibliotecas. Me gustaría poner todas las respuestas como respuesta aceptada :-)

¿Fue útil?

Solución

Parece que no está compilando el archivo .c en la biblioteca para generar un archivo .o. El enlazador buscaría la implementación del prototipo en el archivo .o producido al compilar la biblioteca

¿El proceso de compilación compila el archivo .c de la biblioteca?

¿Por qué lo llamas " biblioteca " Si en realidad es solo el código fuente?

Otros consejos

Los encabezados proporcionan declaraciones de funciones y definiciones de funciones. Para permitir que el enlazador encuentre la implementación de la función (y deshacerse de la referencia no definida), debe solicitar al controlador del compilador (gcc) que vincule la biblioteca específica donde reside la función utilizando el indicador -l. Por ejemplo, -lm enlazará la biblioteca matemática. La página del manual de una función normalmente especifica qué biblioteca, si corresponde, debe especificarse para encontrar la función.

Si el enlazador no puede encontrar una biblioteca específica, puede agregar una ruta de búsqueda de biblioteca utilizando el interruptor -L (por ejemplo, -L / usr / local / lib). También puede afectar de forma permanente la ruta de la biblioteca a través de la variable de entorno LIBRARY_PATH.

Aquí hay algunos detalles adicionales para ayudarlo a depurar su problema. Por convención, los nombres de los archivos de biblioteca tienen el prefijo lib y (en su forma estática) tienen una extensión .a. Por lo tanto, la versión enlazada estáticamente de la biblioteca matemática predeterminada del sistema (la que se vincula con -lm) normalmente reside en /usr/lib/libm.a. Para ver qué símbolos define una biblioteca determinada, puede ejecutar nm --defined-only en el archivo de la biblioteca. En mi sistema, ejecutar el comando en libm.a me da un resultado como el siguiente.

e_atan2.o:
00000000 T atan2

e_asinf.o:
00000000 T asinf

e_asin.o:
00000000 T asin

Para ver la ruta de la biblioteca que utiliza su compilador y qué bibliotecas carga de forma predeterminada, puede invocar gcc con la opción -v. De nuevo en mi sistema, esto da el siguiente resultado.

GNU assembler version 2.15 [FreeBSD] 2004-05-23 (i386-obrien-freebsd) 
using BFD version 2.15 [FreeBSD] 2004-05-23
/usr/bin/ld -V -dynamic-linker /libexec/ld-elf.so.1 /usr/lib/crt1.o 
/usr/lib/crti.o /usr/lib/crtbegin.o -L/usr/lib /var/tmp//ccIxJczl.o -lgcc -lc 
-lgcc /usr/lib/crtend.o /usr/lib/crtn.o

Me temo que hayas mezclado los conceptos de biblioteca y encabezado. Supongamos que tiene una biblioteca libmylib.a que contiene la función myfunc () y un encabezado correspondiente mylib.h que define su prototipo. En su archivo fuente myapp.c , incluya el encabezado, ya sea directamente o incluyendo otro encabezado que lo incluya. Por ejemplo:

/* myapp.h
** Here I will include and define my stuff
*/
...
#include "mylib.h"
...

su archivo fuente se ve como:

/* myapp.c
** Here is my real code
*/
...
#include "myapp.h"
...
/* Here I can use the function */
myfunc(3,"XYZ");

Ahora puede compilarlo para obtener myapp.o :

gcc -c -I../mylib/includes myapp.c

Tenga en cuenta que el -I simplemente le dice a gcc dónde están los archivos de los encabezados, ¡no tienen nada que ver con la propia biblioteca!

Ahora puede vincular su aplicación con la biblioteca real:

gcc -o myapp -L../mylib/libs myapp.o -lmylib

Tenga en cuenta que el interruptor -L le dice a gcc dónde está la biblioteca, y el -l le dice que vincule su código con la biblioteca.

Si no realiza este último paso, puede encontrar el problema que describió.

Puede haber otros casos más complejos, pero según su pregunta, espero que esto sea suficiente para resolver su problema.

Publique su makefile y la función de biblioteca a la que está intentando llamar. Incluso los archivos make simples de gcc usualmente tienen una línea como esta:

LIBFLAGS =-lc -lpthread -lrt -lstdc++ -lShared -L../shared

En este caso, significa vincular la biblioteca estándar de C, entre otras

Supongo que debes agregar la ruta donde el enlazador puede encontrar la biblioteca. En gcc / ld puedes hacer esto con -L y bibliotecario con -l.

  

-Ldir, --library-path = dir

     

Buscar directorio directorio antes estándar   directorios de búsqueda (esta opción debe   precede a la opción -l que busca   ese directorio).

     

-larch, --library = archive

     

Incluir el archivo archivado en el archivo   Lista de archivos a enlazar.


  

Respuesta a las respuestas: no hay un archivo de biblioteca .a, solo .h y .c en la biblioteca, por lo que -l no es adecuado

¿Entonces es posible que primero tengas que crear la biblioteca?

gcc -c mylib.c -o mylib.o
ar  rcs libmylib.a      mylib.o

He encontrado este problema al crear un programa con una nueva versión de gcc. El problema se solucionó llamando a gcc con la opción -std = gnu89. Aparentemente esto se debió a declaraciones de funciones en línea. He encontrado esta solución en https://gcc.gnu.org/gcc-5/porting_to .html

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top