¿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.afuente
code.carchivo 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
ldopción-BdynamicTodas 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.soylibs1.aambos existen, el vinculador seleccionarálibs1.sosi es antes-Wl,-Bstatico después-Wl,-Bdynamic. No olvide pasar-L/libs1-library-location/antes de llamar-ls1.fuente
-staticen algún lugar del comando falla (supongo que intenta vincular más cosas de forma estática que solo las bibliotecas que quiero).-Wl,-Bstaticy-Wl,-Bdynamices importante.Desde la página de manual de
ld(esto no funciona con gcc), refiriéndose a la--staticopción:Una solución es poner sus dependencias dinámicas antes de la
--staticopció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,
libX11no está en la lista de bibliotecas vinculadas dinámicamente, ya que estaba vinculado estáticamente.Atención: un
.soarchivo siempre está vinculado de forma dinámica, incluso cuando se especifica con un nombre de archivo / ruta completa.fuente
ldd a.out?lddgenera 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.avariante (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
-lnameopción buscarálibname.soluego paralibname.aagregar el prefijo lib y.so(si está habilitado en este momento) o el.asufijo. Pero la-l:nameopción solo buscará exactamente el nombre especificado: https://sourceware.org/binutils/docs/ld/Options.htmlLa variante
-l:namespecestá 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 mainDe lo contrario, no funcionará. me toma algún tiempo darme cuenta.
fuente