2010-07-29 7 views
26

Antes de hoy siempre creí que el orden en que los objetos y las bibliotecas pasaban a g ++ durante la etapa de vinculación no era importante. Entonces, hoy, traté de vincular desde código C++ a código c. Envolví todos los encabezados C en un bloque "C" externo pero el enlazador aún tenía dificultades para encontrar símbolos que yo sabía que estaban en los archivos del objeto C.g ++ vinculando la dependencia de orden al vincular el código c con el código C++

Perplejo, creé un ejemplo relativamente simple para aislar el error de enlace, pero para mi sorpresa, el ejemplo más simple se vinculó sin ningún problema.

Después de un poco de prueba y error, encontré que al emular el patrón de vinculación utilizado en el ejemplo simple, pude obtener el código principal para vincular OK. El patrón fue código objeto primero, segundo objeto archivos por ejemplo:

g++ -o serverCpp serverCpp.o algoC.o libcrypto.a

¿Alguien puede arrojar algo de luz sobre por qué esto podría ser tan ?. Nunca he visto este problema al vincular el código ordinario de C++.

+0

Para más detalles, consulte: http://stackoverflow.com/questions/1095298/gcc-c-linker-errors-undefined-reference -to-vtable-for-xxx-undefined-referen/1095321 # 1095321 –

Respuesta

35

El orden en que se especifican los archivos de objeto y las bibliotecas es MUY importante en GCC, si no lo ha mordido antes de tener una vida encantadora. El vinculador busca símbolos en el orden en que aparecen, por lo que si tiene un archivo fuente que contiene una llamada a una función de biblioteca, debe colocarlo antes de la biblioteca o el vinculador no sabrá que tiene que resolverlo. El uso complejo de las bibliotecas puede significar que tiene que especificar la biblioteca más de una vez, lo cual es un verdadero problema para hacer las cosas bien.

+0

Créanme, no he :-), ¿hay alguna documentación sobre esta propiedad? –

+0

Aquí vamos: http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html –

+0

Yo, también, siempre he encontrado que el orden de los enlaces es crítico; puede ser difícil determinar por qué se producen errores de enlace, también, hasta que adivine que el orden es incorrecto ... –

6

Una biblioteca estática es una colección de archivos de objetos agrupados en un archivo. Al vincularse con él, el vinculador solo elige los objetos que necesita para resolver cualquier símbolo actualmente indefinido. Como los objetos están vinculados en orden dado en la línea de comando, los objetos de la biblioteca solo se incluirán si la biblioteca aparece después de todos los objetos que dependen de ella.

Por lo tanto, el orden del enlace es muy importante; si va a utilizar bibliotecas estáticas, debe tener cuidado de realizar un seguimiento de las dependencias y no introducir dependencias cíclicas entre las bibliotecas.

+0

Las dependencias cíclicas son correctas; simplemente significa que necesita tener una línea de enlace como "'ao bo ao'". – caf

+1

@caf: si los objetos adicionales de la segunda inclusión de 'a' dependen de objetos en' b' que aún no se han incluido, entonces eso no es suficiente; necesitarás agregar 'b' nuevamente al final. Que a su vez podría introducir más dependencias en 'a'. Entonces las dependencias cíclicas no están realmente "OK", es raro que sean lo suficientemente patológicas como para necesitar más de una repetición. –

17

La orden de la biblioteca pasar a gcc/g ++ realmente importa. Si A depende de B, A debe figurar primero en la lista. La razón es que optimiza los símbolos que no están referenciados, por lo que si primero ve la biblioteca B, y nadie la ha referenciado en ese punto, entonces no vinculará nada en absoluto.

0

Puede utilizar archivos --start grupos --end-grupo y escribir las bibliotecas dependientes 2 en lugar de archivos

gcc main.o -L. -Wl, - grupo de inicio -lobj_A -lobj_b -Wl, - grupo-final

Cuestiones relacionadas