24 votos

g++: ¿En qué orden se debe estático y dinámico de las bibliotecas de estar vinculado?

Digamos que tenemos un ejecutable principal llamado "my_app" y utiliza varias otras bibliotecas: 3 bibliotecas están enlazados estáticamente, y otros 3 están vinculados dinámicamente. El orden en el que deben estar vinculados contra "my_app"?

Pero el orden en que estos deben estar vinculados?

Digamos que tenemos libSA (como en Estático A) que depende de la libSB, y libSC que depende de la libSB:

libSA -> libSB -> libSC

y tres bibliotecas dinámicas:libDA -> libDB -> libDC (libDA es la básica, libDC es el más alto)

el orden en que estos deben estar vinculados? el básico primero o el último?

g++ ... -g libSA libSB libSC -lDA -lDB -lDC -o my_app

parece que el actual orden, pero ¿es así? lo que si hay dependencias entre cualquier biblioteca dinámica a estática, o de la otra manera?

26voto

jpalecek Puntos 31928

En el caso estático, realmente no importa, porque en realidad no enlace de bibliotecas estáticas - todo lo que hacemos es pack de algunos objetos de los archivos juntos en un archivo. Todo lo que tienes que es compilar el objeto de archivos, y usted puede crear bibliotecas estáticas de inmediato.

La situación con la dinámica de las bibliotecas es más complicado, hay dos aspectos:

  1. Una biblioteca compartida que funciona exactamente de la misma manera como biblioteca estática (excepto el uso compartido de los segmentos, si están presentes), lo cual significa que usted sólo puede hacer lo mismo - just link de su biblioteca compartida tan pronto como usted tiene el objeto de archivos. Esto significa, por ejemplo, los símbolos de libDA aparecerá como indefinido en libDB

  2. Ud. puede especificar las bibliotecas de enlace para la línea de comandos cuando la vinculación de objetos compartidos. Esto tiene el mismo efecto que 1., pero, marcas libDB como en la necesidad de libDA.

La diferencia es que si uso el antiguo camino, usted tiene que especificar las tres bibliotecas (-lDA, -lDB, pma) en la línea de comandos cuando se enlaza el archivo ejecutable. Si usa la última, que acaba de especificar pma y que se tire a los demás de forma automática en el momento de enlazar. Tenga en cuenta que el enlace es justo antes de que el programa se ejecuta (lo que significa que usted puede obtener diferentes versiones de los símbolos, incluso de diferentes bibliotecas).

Todo esto se aplica a UNIX; la DLL de Windows funcionan de manera muy diferente.

Editar después de la aclaración de la pregunta:

La cita de la ld manual de información.

El vinculador de búsqueda de un archivo sólo una vez, en el lugar donde se especificado en la línea de comandos. Si el archivo define un símbolo de lo que fue indefinido en algún objeto que apareció antes de que el archivo en el de la línea de comandos, el vinculador se incluyen el archivo correspondiente(s) a partir de la archivo. Sin embargo, una undefined symbol en un objeto que aparece más adelante en el línea de comandos no se causa el vinculador para buscar en el archivo de nuevo.

Ver la ` - ("opción por un modo de forzar el vinculador de búsqueda de archivos múltiples veces.

Usted puede incluir en el mismo archivo de varias veces en la línea de comandos.

Este tipo de archivo de búsqueda es estándar de Unix enlazadores. Sin embargo, si usted está usando `ld' en AIX, tenga en cuenta que es diferente de la conducta de el AIX enlazador.

Lo que significa:

Cualquier biblioteca estática o un objeto que depende de la biblioteca debe ser colocado antes en la línea de comandos. Si las bibliotecas estáticas dependen unos de otros de forma circular, por ejemplo, puede. el uso de la -( opción de línea de comandos, o lugar de las bibliotecas en la línea de comandos de dos veces (-lDA -lDB -lDA). El orden de las bibliotecas dinámicas no importa.

24voto

Mr.Ree Puntos 5112

Este es el tipo de pregunta que se resuelven mejor por un ejemplo trivial. De verdad! Tomar de 2 minutos, el código de un ejemplo sencillo, y probarlo! Vas a aprender algo, y es más rápido que preguntar.

Por ejemplo, dado que los archivos:

a1.cc

#include <stdio.h>
void a1() { printf("a1\n"); }

a2.cc

#include <stdio.h>
extern void a1();
void a2() { printf("a2\n");  a1(); }

a3.cc

#include <stdio.h>
extern void a2();
void a3() { printf("a3\n"); a2(); }

aa.cc

extern void a3();
int main()
{
  a3();
}

Ejecutando:

g++ -Wall -g -c a1.cc
g++ -Wall -g -c a2.cc
g++ -Wall -g -c a3.cc
ar -r liba1.a a1.o
ar -r liba2.a a2.o
ar -r liba3.a a3.o
g++ -Wall -g aa.cc -o aa -la1 -la2 -la3 -L.

Muestra:

./liba3.a(a3.o)(.text+0x14): In function `a3()':
/tmp/z/a3.C:4: undefined reference to `a2()'

Considerando:

g++ -Wall -g -c a1.C
g++ -Wall -g -c a2.C
g++ -Wall -g -c a3.C
ar -r liba1.a a1.o
ar -r liba2.a a2.o
ar -r liba3.a a3.o
g++ -Wall -g aa.C -o aa -la3 -la2 -la1 -L.

Se realiza correctamente. (La -la3 -la2 -la1 parámetro se cambia el orden.)

PS:

nm --demangle liba*.a

liba1.a:
a1.o:
                 U __gxx_personality_v0
                 U printf
0000000000000000 T a1()

liba2.a:
a2.o:
                 U __gxx_personality_v0
                 U printf
                 U a1()
0000000000000000 T a2()

liba3.a:
a3.o:
                 U __gxx_personality_v0
                 U printf
                 U a2()
0000000000000000 T a3()

De hombre nm:

  • Si minúsculas, el símbolo es local; si en mayúsculas, el símbolo es global (externo).

  • "T", El símbolo está en el texto (código) de la sección.

  • La "U" El símbolo no está definido.

2voto

Fredrik Jansson Puntos 1614

He trabajado en un proyecto con un grupo de internos de las bibliotecas que, lamentablemente, dependía de cada uno de los otros (y esto empeoró a lo largo del tiempo). Terminamos en la "solución" a través de la creación de SCons para especificar todos los libs dos veces al momento de la vinculación:

g++ ... -la1 -la2 -la3 -la1 -la2 -la3 ...

0voto

Kosi2801 Puntos 9487

Las dependencias de la vinculación de una biblioteca o archivo ejecutable tiene que estar presente en el enlace de tiempo, por lo que no se puede vincular libXC antes de libXB está presente. No importa si estáticamente o dinámicamente.

Comience con la más básica, que no tiene (o en las afueras de su proyecto) dependencias.

0voto

Scottie T Puntos 4655

Es una buena práctica para mantener las bibliotecas independientes el uno del otro para evitar la orden de enlace de los problemas.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X