¿Cómo puedo vincular estáticamente solo algunas bibliotecas específicas a mi binario al vincularlo con GCC?
gcc ... -static ...
intenta vincular estáticamente todas las bibliotecas vinculadas, pero no tengo la versión estática de algunas de ellas (por ejemplo: libX11).
gcc
linker
static-libraries
peoro
fuente
fuente
Respuestas:
gcc -lsome_dynamic_lib code.c some_static_lib.a
fuente
code.c
archivo garantiza que los símbolos que contiene serán ignorados a menos que haya unamain()
función en uno de los archivos objeto de la biblioteca.También puedes usar la
ld
opción-Bdynamic
Todas las bibliotecas posteriores (incluidas las del sistema vinculadas por gcc automáticamente) se vincularán dinámicamente.
fuente
también puede usar:
-static-libgcc -static-libstdc++
banderas para bibliotecas gcctenga en cuenta que si
libs1.so
ylibs1.a
ambos existen, el vinculador seleccionarálibs1.so
si es antes-Wl,-Bstatic
o después-Wl,-Bdynamic
. No olvide pasar-L/libs1-library-location/
antes de llamar-ls1
.fuente
-static
en algún lugar del comando falla (supongo que intenta vincular más cosas de forma estática que solo las bibliotecas que quiero).-Wl,-Bstatic
y-Wl,-Bdynamic
es importante.Desde la página de manual de
ld
(esto no funciona con gcc), refiriéndose a la--static
opción:Una solución es poner sus dependencias dinámicas antes de la
--static
opción en la línea de comando.Otra posibilidad es no usar
--static
, sino proporcionar el nombre de archivo completo / ruta del archivo de objeto estático (es decir, no usar la opción -l) para vincular estáticamente una biblioteca específica. Ejemplo:Como puede ver en el ejemplo,
libX11
no está en la lista de bibliotecas vinculadas dinámicamente, ya que estaba vinculado estáticamente.Atención: un
.so
archivo siempre está vinculado de forma dinámica, incluso cuando se especifica con un nombre de archivo / ruta completa.fuente
ldd a.out
?ldd
genera las bibliotecas compartidas necesarias y libX11 no aparece en esa lista.El problema, según tengo entendido, es el siguiente. Tiene varias bibliotecas, algunas estáticas, otras dinámicas y otras tanto estáticas como dinámicas. El comportamiento predeterminado de gcc es vincular "principalmente dinámico". Es decir, gcc se vincula a bibliotecas dinámicas cuando es posible, pero por lo demás recurre a bibliotecas estáticas. Cuando usa la opción -static para gcc, el comportamiento es vincular solo bibliotecas estáticas y salir con un error si no se puede encontrar una biblioteca estática, incluso si hay una biblioteca dinámica adecuada.
Otra opción, que en varias ocasiones deseé que tuviera gcc , es lo que llamo -mostly-static y es esencialmente lo opuesto a -dynamic (el predeterminado). -mostly-static preferiría, si existiera, vincularse con bibliotecas estáticas, pero recurriría a bibliotecas dinámicas.
Esta opción no existe pero se puede emular con el siguiente algoritmo:
Construyendo la línea de comando del enlace sin incluir -static .
Repita las opciones de enlace dinámico.
Acumular rutas de biblioteca, es decir, aquellas opciones de la forma -L <lib_dir> en una variable <lib_path>
Para cada opción de enlace dinámico, es decir, aquellos de la forma -l <lib_name> , ejecute el comando gcc <lib_path> -print-file-name = lib <lib_name> .ay capture la salida.
Si el comando imprime algo diferente a lo que pasó, será la ruta completa a la biblioteca estática. Reemplace la opción de biblioteca dinámica con la ruta completa a la biblioteca estática.
Enjuague y repita hasta que haya procesado toda la línea de comando del enlace. Opcionalmente, el script también puede tomar una lista de nombres de bibliotecas para excluir de los enlaces estáticos.
El siguiente script bash parece funcionar:
Por ejemplo:
en mi sistema devuelve:
o con una exclusión:
Entonces obtengo:
fuente
También hay una
-l:libstatic1.a
variante (menos l dos puntos) de la opción -l en gcc que se puede usar para vincular la biblioteca estática (gracias a https://stackoverflow.com/a/20728782 ). ¿Está documentado? No en la documentación oficial de gcc (que tampoco es exacta para las bibliotecas compartidas): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlEl doc de binutils ld lo describe. La
-lname
opción buscarálibname.so
luego paralibname.a
agregar el prefijo lib y.so
(si está habilitado en este momento) o el.a
sufijo. Pero la-l:name
opción solo buscará exactamente el nombre especificado: https://sourceware.org/binutils/docs/ld/Options.htmlLa variante
-l:namespec
está documentada desde la versión 2.18 de binutils (2007): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlfuente
Algunos cargadores (enlazadores) proporcionan interruptores para activar y desactivar la carga dinámica. Si GCC se está ejecutando en un sistema de este tipo (Solaris y posiblemente otros), puede usar la opción correspondiente.
Si sabe qué bibliotecas desea vincular estáticamente, simplemente puede especificar el archivo de biblioteca estática en la línea de vínculo, por ruta completa.
fuente
de enlace dinámico y estático de la biblioteca dentro de una línea, usted debe poner librerías estáticas después de bibliotecas dinámicas y archivos de objetos, como este:
gcc -lssl main.o -lFooLib -o main
De lo contrario, no funcionará. me toma algún tiempo darme cuenta.
fuente