46

Estoy intentando usar la biblioteca libtommath. Estoy usando NetBeans IDE para mi proyecto en Ubuntu Linux. He descargado y construido la biblioteca, he hecho una 'instalación' para poner el archivo .a resultante en/usr/lib/y los archivos .h en/usr/includeIntentando incluir una biblioteca, pero sigo recibiendo 'referencia no definida' a los mensajes

Parece que está buscando los archivos apropiadamente (dado que ya no recibo esos errores, lo cual hice antes de instalar en los directorios/usr).

Sin embargo, cuando se crea un sencillo principal de hacer una llamada a mp_init (que está en la biblioteca), me sale el siguiente error cuando intento hacer mi proyecto:

mkdir -p build/Debug/GNU-Linux-x86 
rm -f build/Debug/GNU-Linux-x86/main.o.d 
gcc -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.c 
mkdir -p dist/Debug/GNU-Linux-x86 
gcc -o dist/Debug/GNU-Linux-x86/cproj1 build/Debug/GNU-Linux-x86/main.o 
build/Debug/GNU-Linux-x86/main.o: In function 'main': 
/home/[[myusername]]/NetBeansProjects/CProj1/main.c:18: undefined reference to `mp_init' 
collect2: ld returned 1 exit status 
make[2]: *** [dist/Debug/GNU-Linux-x86/cproj1] Error 1 

Por lo tanto, parece que el enlazador no puede encontrar la función dentro de la biblioteca, sin embargo, está ahí, así que no sé qué podría estar causando esto.

Obtengo el mismo error si escribo el comando gcc directamente y omito el archivo MAKE, también me aseguré de que la biblioteca estática también se haya compilado con GCC.

editar para agregar:

puedo obtener estos mismos errores si no hago la compilación directa y añadir la biblioteca con -l o -L:

$ gcc -l /usr/lib/libtommath.a main.c 
/usr/bin/ld: cannot find -l/usr/lib/libtommath.a 
collect2: ld returned 1 exit status 

$ gcc -llibtommath.a main.c 
/usr/bin/ld: cannot find -llibtommath.a 
collect2: ld returned 1 exit status 

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main': 
main.c:(.text+0x18): undefined reference to `mp_init' 
collect2: ld returned 1 exit status 

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main': 
main.c:(.text+0x18): undefined reference to `mp_init' 
collect2: ld returned 1 exit status 

Estoy muy oxidado en esta materia, por lo No estoy seguro de estar usando el comando correcto aquí, en los ejemplos -L ¿se encuentran las bibliotecas? Si no se encuentra la biblioteca, ¿cómo diablos la obtengo para encontrar la biblioteca? Está en/usr/lib, lo he intentado con el archivo .a en el directorio actual, etc. ¿Hay alguna variable de entorno que deba establecer? Si es así, cómo, etc.

He intentado con una biblioteca completamente diferente (GMP) y tuve el EXACTAMENTE el mismo problema. Esto tiene que ser algún tipo de problema de entorno Ubuntu? Alguien tiene alguna idea de cómo solucionar esto?

Respuesta

113

El truco aquí es poner la biblioteca DESPUÉS del módulo que está compilando. El problema es una cosa de referencia. El enlazador resuelve las referencias en orden, por lo que cuando la biblioteca ANTES de compilar el módulo, el vinculador se confunde y no cree que se necesiten las funciones de la biblioteca. Al colocar la biblioteca DESPUÉS del módulo, el vinculador resuelve las referencias a la biblioteca en el módulo.

+7

+1 ¡Oh, gracias! Sé que el orden de resolución de enlaces tiene mucho sentido, ¡pero realmente ayuda a recordar estos hechos! – scraimer

+1

Esto funcionó para mí. Mi antiguo archivo MAKE solía funcionar, pero ahora parece que el compilador se está volviendo demasiado listo para su propio bien :) –

+2

¡Gracias, este fue un GRAN recordatorio! –

35

Sí, es necesario agregar bibliotecas después de los archivos de origen/objetos. Este comando va a resolver el problema:

gcc -static -L/usr/lib -I/usr/lib main.c -ltommath 
+1

+1 para escribir la forma correcta de enlazar con 'libtommath.a' – scraimer

+0

Guau, esto es bastante complicado. Gracias por señalar eso. – lolski

4

Si los archivos de origen .c se convierten .cpp (como como en parsec), entonces el externo tiene que ser seguido por "C", como en

extern "C" void foo(); 
Cuestiones relacionadas