gcc gcc4

GCC 4.5 vs 4.4 vinculación con dependencias



gcc4 (1)

Parece que ha habido cambios en la forma en que se DT_NEEDED bibliotecas DT_NEEDED durante la vinculación por ld . Aquí está la parte relevante del man ld actual man ld :

Con --copy-dt-needed-entries las bibliotecas dinámicas mencionadas en la línea de comando se buscarán recursivamente, siguiendo sus etiquetas DT_NEEDED a otras bibliotecas, para resolver los símbolos requeridos por el binario de salida. Sin embargo, con la configuración predeterminada, la búsqueda de las bibliotecas dinámicas que la siguen se detendrá con la biblioteca dinámica en sí misma. No se atravesarán enlaces DT_NEEDED para resolver símbolos.

(parte de la --copy-dt-needed-entries ).

En algún momento entre GCC 4.4 y GCC 4.5 (aparentemente, vea alguna referencia aquí - no se puede encontrar nada realmente autorizado), el valor predeterminado cambió de la búsqueda recursiva a ninguna búsqueda recursiva (como está viendo con los GCC más nuevos).

En cualquier caso, puede (y debe) repararlo especificando liba en su paso de enlace final:

$CC c.c -L. -lb -la -Wl,-rpath-link .

Puede verificar que la configuración de este enlazador es (al menos parte de) el problema al ejecutar con sus compiladores más nuevos y esta línea de comando:

$CC c.c -L. -Wl,--copy-dt-needed-entries -lb -Wl,--no-copy-dt-needed-entries / -Wl,-rpath-link .

Estoy observando una diferencia cuando trato de hacer la misma operación en GCC 4.4 y GCC 4.5. Debido a que el código con el que estoy haciendo esto es de propiedad, no puedo proporcionarlo, pero estoy observando un error similar con este sencillo caso de prueba.

Lo que básicamente trato de hacer es tener una biblioteca compartida (libb) que dependa de otra biblioteca compartida (liba). Al cargar libb, supongo que liba también debe cargarse, aunque libb no necesariamente usa los símbolos en liba.

Lo que estoy observando es cuando compilo con GCC 4.4, observo que la liba está cargada, pero si compilo con GCC 4.5, libb no se carga.

Tengo un pequeño caso de prueba que consta de dos archivos, ac y bc. El contenido de los archivos:

//a.c int a(){ return 0; } //b.c int b(){ return 0; } //c.c #include <stdio.h> int a(); int b(); int main() { printf("%d/n", a()+b()); return 0; } //test.sh $CC -o liba.so a.c -shared $CC -o libb.so b.c -shared -L. -la -Wl,-rpath-link . $CC c.c -L. -lb -Wl,-rpath-link . LD_LIBRARY_PATH=. ./a.out

Este es mi resultado con diferentes versiones de GCC

$ CC=gcc-4.4 ./test.sh 1 $ CC=gcc-4.5 ./test.sh /tmp/cceJhAqy.o: In function `main'': c.c:(.text+0xf): undefined reference to `a'' collect2: ld returned 1 exit status ./test.sh: line 4: ./a.out: No such file or directory $ CC=gcc-4.6 ./test.sh /tmp/ccoovR0x.o: In function `main'': c.c:(.text+0xf): undefined reference to `a'' collect2: ld returned 1 exit status ./test.sh: line 4: ./a.out: No such file or directory $

¿Alguien puede explicar lo que está pasando? Otra información adicional es que ldd en libb.so muestra liba.so en GCC 4.4 pero no en GCC 4.5.

EDITAR

Cambié test.sh a lo siguiente:

$CC -shared -o liba.so a.c $CC -L. -Wl,--no-as-needed -Wl,--copy-dt-needed-entries -la -shared -o libb.so b.c -Wl,-rpath-link . $CC -L. c.c -lb -Wl,-rpath-link . LD_LIBRARY_PATH=. ./a.out

Esto dio el siguiente resultado con GCC 4.5:

/usr/bin/ld: /tmp/cc5IJ8Ks.o: undefined reference to symbol ''a'' /usr/bin/ld: note: ''a'' is defined in DSO ./liba.so so try adding it to the linker command line ./liba.so: could not read symbols: Invalid operation collect2: ld returned 1 exit status ./test.sh: line 4: ./a.out: No such file or directory