Enlace estático de la función de biblioteca compartida en gcc


138

¿Cómo puedo vincular una función de biblioteca compartida estáticamente en gcc?


14
¿Qué quieres decir con estáticamente vinculado? ¿Desea que su ejecutable se distribuya sin requerir el .so?
Emiliano el

Respuestas:


108

Referirse a:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

Necesita la versión estática de la biblioteca para vincularla.

Una biblioteca compartida es en realidad un ejecutable en un formato especial con puntos de entrada especificados (y se incluyen algunos problemas de direccionamiento fijo). No tiene toda la información necesaria para vincular estáticamente.

No puede vincular estáticamente una biblioteca compartida (o vincular dinámicamente una estática).

El indicador -staticobligará al vinculador a usar bibliotecas estáticas (.a) en lugar de compartidas (.so). Pero las bibliotecas estáticas no siempre se instalan de manera predeterminada, por lo que es posible que deba instalar la biblioteca estática usted mismo.

Otro enfoque posible es usar statifier o Ermine . Ambas herramientas toman como entrada un ejecutable vinculado dinámicamente y como salida crean un ejecutable autónomo con todas las bibliotecas compartidas incrustadas.


11
¿Qué información tiene la biblioteca estática, para que pueda vincularse estáticamente, que la biblioteca dinámica no tiene?
kbolino

75

Si desea vincular, por ejemplo, libapplejuice estáticamente, pero no, por ejemplo, liborangejuice , puede vincular así:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

Hay una advertencia: si se liborangejuiceusa libapplejuice, entonceslibapplejuice también se vinculará dinámicamente.

Tendrás que vincular liborangejuiceestáticamente junto con libapplejuicepara obtener libapplejuiceestática.

Y no olvides guardar -Wl,-Bdynamicotra cosa, terminarás vinculando todo estático, incluido libc(lo cual no es algo bueno).


2
¿No hay una manera de decirle a gcc directamente qué vincular estáticamente, y no evitarlo y hablar con el vinculador?
Elazar Leibovich

1
@ElazarLeibovich no puedes obtener una combinación de estática y dinámica de esa manera.
Haozhun

@EugeneBujak: La advertencia no se aplica en mi sistema. Ejemplo: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB usa libA , está vinculado y lddno muestra una referencia a libA . El ejecutable funciona bien. Probado con g ++ 4.7.3.
radix

Una dependencia indirecta (anidada), estática, de una dependencia directa y dinámica no se vincula dinámicamente.
Vinny

Considere lo siguiente: binA depende de libB.so, que depende de libC.a Como ya han dicho otros, los .so son ejecutables, por lo que cuando un objeto compartido está vinculado, el enlazador procesa cualquier dependiente de biblioteca estática de la misma manera que si se estaba vinculando un ejecutable: los únicos símbolos extraídos de la biblioteca estática .a son los referenciados (y no resueltos) por .so. Esto significa que si binA hace referencia a un símbolo en libC.a, no referenciado en ningún lugar de libB.so, incluso si binA se vincula a libB.so, ese símbolo estará indefinido (a menos que -Wl, - se use el archivo completo al vincular libB.so).
Vinny

18

Si tiene el archivo .a de su biblioteca compartida (.so), simplemente puede incluirlo con su ruta completa como si fuera un archivo objeto, como este:

Esto genera main.o simplemente compilando:

gcc -c main.c

Esto vincula ese archivo de objeto con la biblioteca estática correspondiente y crea el ejecutable (llamado "main"):

gcc main.o mylibrary.a -o main

O en un solo comando:

gcc main.c mylibrary.a -o main

También podría ser una ruta absoluta o relativa:

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

Sí, sé que esta es una pregunta de hace 8 años, pero me dijeron que era posible vincular estáticamente contra una biblioteca de objetos compartidos y este fue literalmente el éxito principal cuando busqué más información al respecto.

Para demostrar realmente que no es posible vincular estáticamente una biblioteca de objetos compartidos con ld( gcc'linker'), a diferencia de un grupo de personas que insisten en que no es posible, use el siguiente gcccomando:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Por supuesto, tendrá que compilar objectname.odesde sourcename.c, y probablemente también debería crear su propia biblioteca de objetos compartidos. Si lo hace, use -Wl,--library-path,.para que ld pueda encontrar su biblioteca en el directorio local).

El error real que recibe es:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Espero que ayude.


10

Un poco tarde pero ... Encontré un enlace que guardé hace un par de años y pensé que podría ser útil para ustedes:

CDE: cree automáticamente aplicaciones portátiles de Linux

http://www.pgbovine.net/cde.html

  • Solo descarga el programa
  • Ejecute el paso binario como argumento del nombre del binario que desea convertir en portátil, por ejemplo: nmap

    ./cde_2011-08-15_64bit nmap

El programa leerá todas las librerías vinculadas a nmap y sus dependencias y las guardará en una carpeta llamada cde-package / (en el mismo directorio que usted).

  • Finalmente, puede comprimir la carpeta e implementar el binario portátil en cualquier sistema.

Recuerde, para iniciar el programa portátil debe ejecutar el binario ubicado en cde-package / nmap.cde

Atentamente


2
Si bien no proporciona exactamente la respuesta a la pregunta, es una solución notable al problema.
razong

El enlace parece estar muerto ahora.
sinan hace

0

En gcc, esto no es compatible. De hecho, esto no es compatible con ningún compilador / enlazador existente que conozca.


44
¿Podría explicar cómo un compilador existente no admite la vinculación estática?
jww

55
@noloader, enlace estático de biblioteca dinámica?
nothrow
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.