2012-01-25 18 views
8

He estado intentando construir algún código que use funciones matemáticas (por ejemplo, pow).Comportamiento extraño de gcc y math.h?

math.h se incluye, y la bandera -lm se utiliza durante la compilación.

Cuando la compilación se llama así (-lm bandera en el comienzo de la orden), que fracasaron, diciendo que hay una referencia indefinida a pow:

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder 
main.o: In function `get_sn_motif_id': 
main.c:(.text+0x28d): undefined reference to `pow' 

Y cuando la bandera -lm se pone al fin del comando, funciona!

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm 

¿Es esto normal?

+0

Oops. No noté que esta es una vieja pregunta. – AnT

Respuesta

18

Sí, es normal. Para muchos vinculadores, importa el orden en el que se especifican los archivos objeto y las bibliotecas.

Para citar "An Introduction to GCC - for the GNU compilers gcc and g++":

El comportamiento tradicional de enlazadores es la búsqueda de funciones externas de izquierda a derecha en las bibliotecas especificadas en la línea de comandos. Esto significa que una biblioteca que contiene la definición de una función debe aparecer después de cualquier archivo fuente o archivo de objeto que lo use. Esto incluye las bibliotecas especificadas con la opción de atajo -l, como se muestra en el siguiente comando:

$ gcc -Wall calc.c -lm -o calc (correct order)

Este comportamiento es común, pero es de ninguna manera universal. En caso de duda, lo mejor es consultar el manual de su enlazador. Por ejemplo, en mi sistema Ubuntu man ld establece que:

-l namespec 
    --library=namespec 

     ... 

     The linker will search an archive only once, at the location where 
     it is specified on the command line. If the archive defines a 
     symbol which was undefined in some object which appeared before the 
     archive on the command line, the linker will include the 
     appropriate file(s) from the archive. However, an undefined symbol 
     in an object appearing later on the command line will not cause the 
     linker to search the archive again. 

En otras palabras, este enlazador se comporta de la forma descrita en el libro gcc.

+0

Aunque debería mencionarse que esto no solía aplicarse a las bibliotecas compartidas (al menos con gcc), podían aparecer en cualquier lugar de la línea de comandos. Entonces la gente hizo eso.Sin embargo, recientemente eso ha cambiado, ahora gcc aplica el indicador '--as-needed' al enlazador en muchas plataformas, por lo que el efecto es el mismo para las bibliotecas compartidas también. – nos

4

Como se mencionó en An Introduction to GCC - for the GNU compilers gcc and g++

El comportamiento tradicional de enlazadores es la búsqueda de funciones externas de izquierda a derecha en las bibliotecas especificadas en la línea de comandos. Esto significa que una biblioteca que contiene la definición de una función debe aparecer después de cualquier archivo fuente o archivo de objeto que lo use.

Creo que está viendo el mismo comportamiento.

Obsérvese que también afirma además,

La mayoría de los enlazadores modernas buscar todas las bibliotecas, sin importar el orden, pero lo mejor es seguir la convención de las bibliotecas que ordenan de izquierda a derecha.