2012-04-07 14 views
8

Tengo un programa c que llama a sin, cos y acos. Cuando compilo consigo los siguientes errores:GCC libm no funciona

/tmp/ccDfW98S.o: In function `zip_search': 
main.c:(.text+0xf30): undefined reference to `sin' 
main.c:(.text+0xf45): undefined reference to `sin' 
main.c:(.text+0xf66): undefined reference to `cos' 
main.c:(.text+0xf7b): undefined reference to `cos' 
main.c:(.text+0xf9c): undefined reference to `cos' 
main.c:(.text+0xfc6): undefined reference to `acos' 
collect2: ld returned 1 exit status 

Sé que esto es común cuando no se utiliza la bandera gcc -lm. YO ESTOY usando esta bandera. Estoy llamando a GCC de esta manera:

gcc -o zipcode-server -lm main.c 

Cuando compilo en una de mis computadoras esto funciona bien. La única diferencia que puedo pensar es que esto no funciona en x86_64 y la computadora en la que funciona es i686. Ambos son Ubuntu. El archivo libm.a está presente en la computadora en la que no está funcionando y no aparece ningún error que indique que no se puede encontrar. ¿Qué podría estar causando esto?

+0

¿Podría publicar la parte relevante de su código para que podamos ayudarlo con su problema? – krzysz00

+1

Solo por diversión, intente: 'gcc -o zipcode-server main.c -lm' –

Respuesta

18

Usted debe poner -lm después main.c

En general, si tiene varias bibliotecas, deben ser escritos en el orden de su uso. Por ejemplo, si la biblioteca A usa la biblioteca B, debe tener -lA -lB.

En su caso, el archivo objeto que es el resultado de la compilación de main.c utiliza la biblioteca m y por lo tanto -lm debe venir después.


Para los curiosos, esto es principalmente por razones de eficiencia. Con este esquema, el enlazador puede resolver símbolos actualmente desconocidos con cada biblioteca nueva vista en la lista de argumentos, y recogiendo nuevos símbolos desconocidos de esa biblioteca en el camino. Esto significa que el vinculador puede visitar las bibliotecas una por una y, por lo tanto, unir los símbolos desconocidos con una pequeña cantidad de símbolos proporcionados por cada biblioteca.

En el contraste, el vinculador podría cargar símbolos de todas las bibliotecas a la vez, y luego comenzar a combinar símbolos desconocidos. Sin embargo, en ese caso, el enlazador necesita tratar con un número mucho mayor de símbolos, aumentando tanto la huella de memoria como el tiempo de ejecución del enlazador.

Desde las bibliotecas siempre podían ser declaradas al enlazador en el orden correcto de sus dependencias , no hay razón para que el enlazador de elegir la forma ineficiente.

Bibliotecas normalmente tienen una relación unidireccional, en el sentido de que uno utiliza la otra. Las dependencias circulares entre bibliotecas son raras, si es que existen, pero aún se pueden usar con este modelo repitiendo ciertas bibliotecas para volver a inspeccionarlas.

+0

Wow. Eso fue todo, gracias. – Stewart

Cuestiones relacionadas