Vinculación parcialmente estática y parcialmente dinámica en GCC
compilation static-linking (1)
Lo siguiente funcionó para mí
ln -s `gcc -print-file-name=libc.a`
gcc -static-libgcc -L. -lc test.c
Entonces ldd a.out
da:
not a dynamic executable
Editar:
El OP quiere vincular una biblioteca de forma dinámica y otra estáticamente. Él tiene el ejemplo de vincular libc
estáticamente y libm
dinámicamente. Ese caso particular que no he podido lograr. Sin embargo, es posible lo contrario, es decir, vincular libc
dinámicamente y libm
estáticamente.
ln -s `gcc -print-file-name=libm.a`
gcc test.c -L. -lm
luego ldd a.out
da
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x41960000)
/lib/ld-linux.so.2 (0x4193d000)
Tenga en cuenta que la orden del enlace es importante.eg gcc -L. -lm test.c
gcc -L. -lm test.c
no funciona.
Esto funciona con otras bibliotecas también. Por ejemplo gomp
gcc -fopenmp test.c
ldd muestra libgomp.so.1
. Podemos vincularlo estáticamente de esta manera
ln -s `gcc -print-file-name=libgomp.a`
gcc -L. -fopenmp test.c
Ahora ldd a.out
no muestra libgomp.so.1
. Pero en este caso pthreads
todavía está vinculado dinámicamente. Para vincular pthreads estáticamente, se requiere que libc
esté vinculado de forma estática .
Estoy intentando compilar un programa C muy simple (tan simple como hello world) usando enlaces dinámicos y estáticos con GCC. Quiero saber cómo hacerlo en general, por lo que mi ejemplo de prueba mínima es simplemente tratar de vincular libc como estática y libm dinámicamente.
Me he encontrado al menos con las siguientes preguntas sobre el mismo tema:
GCC: enlace estático solo algunas bibliotecas
Enlace estático de la función de biblioteca compartida en gcc
Algunas de las respuestas que contiene sugieren cosas como usar -Wl, -Bstatic y -Wl, -Bdinámica para especificar qué bibliotecas son respectivamente estáticas y dinámicas. También se sugiere, entre otros, simplemente especificar la ruta completa de la biblioteca estática para enlazar.
He intentado varias de estas sugerencias y variantes de las mismas. No entiendo el mensaje de error que me da. Sé lo que es PIE, pero no veo cómo se relaciona con lo que intento hacer.
Aquí hay algunos intentos fallidos:
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp'' with pointer equality in `/usr/lib64/libc.a(strcmp.o)'' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp'' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)'' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
Compilar solo sin argumentos, y con -estático funciona bien, pero necesito una compilación estática parcial :
$ gcc test.c -lm
$ gcc -static test.c -lm
Sin embargo, lo siguiente también falla:
$ gcc test.c /usr/lib64/libc.a /usr/lib64/libm.a
Me he encontrado con un error similar en esta publicación:
C ++ biblioteca compartida estáticamente enlazada
Sin embargo, las respuestas no parecen aplicarse a mi problema.
El programa que intento compilar es simplemente (como test.c):
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i = 0;
for(i = 0; i < 65535; i++) {
printf("%f/n", sinf(i));
printf("%f/n", cosf(i));
printf("%f/n", tanf(i));
printf("%f/n", sqrtf(i));
}
return 0;
}
EDITAR: tenga en cuenta que el programa debe ser lo suficientemente complejo como para requerir realmente libm, de lo contrario los intentos de vinculación pueden dar falsos positivos si realmente no se necesita libm. En mi ejemplo original de test.c, utilicé únicamente sinf () a un valor constante, lo que hizo que el compilador optimizara por completo la llamada a sinf ().
Estoy usando:
$ gcc --version
gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3