c gcc compilation static-linking

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