2009-04-07 43 views

Respuesta

85

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

se necesita la versión estática de la biblioteca de enlace.

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

No se puede vincular estáticamente biblioteca compartida (o dinámicamente enlace estático)

Bandera -static obligará enlazador a utilizar la biblioteca estática (.a) en lugar de compartir (.so) Pero. Las bibliotecas estáticas no siempre están instaladas por defecto. Entonces, si necesita un enlace estático, debe instalar bibliotecas estáticas.

Otro enfoque posible es el uso statifier o Ermine. Ambas herramientas toman como entrada ejecutable enlazado dinámicamente y como salida crean ejecutable autocontenido con todas las bibliotecas compartidas embebidos.

+6

Buen truco con el estatificador o Ermine. – jww

+2

1+ para '' Flag -static forzará al enlazador a usar la biblioteca estática (.a) en lugar de shared (.so) '' – tod

0

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

+4

¿Podría explicar cómo los enlaces estáticos no son compatibles con ningún compilador existente? – jww

+3

@noloader, enlace estático de la biblioteca dinámica? – nothrow

70

Si desea enlazar, por ejemplo, libapplejuice estáticamente, pero no, por ejemplo, liborangejuice, puede vincular de esta manera:

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

Hay una advertencia - si liborangejuice utiliza libapplejuice, a continuación, libapplejuice se vinculará dinámicamente también.

Tendrás que vincular liborangejuice estáticamente junto con libapplejuice para obtener libapplejuice estática.

Y no se olvide de mantener -Wl,-Bdynamic de lo contrario terminará vinculando todo estático, incluido libc (que no es una buena cosa que hacer).

+2

¿No hay una manera de decirle directamente a gcc qué eslabar estáticamente y no pasarlo por alto? y hablar con el enlazador? –

+1

@ElazarLeibovich no se puede obtener una combinación de estática y dinámica de esa manera. – Haozhun

+0

@EugeneBujak: El _caveat_ no se aplica en mi sistema. Ejemplo: 'gcc -o main main.cc -Wl, -rpath =. -Wl, -Bdynamic -lB -Wl, -Bstatic -lA -Wl, -Bdinámica -L. _libB_ usa _libA_, vincula y 'ldd' no muestra una referencia a _libA_. El ejecutable funciona bien. Probado con g ++ 4.7.3. – radix

18

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

Esto genera principal.o con sólo la compilación:

gcc -c main.c 

Estos links que objetan el archivo de la biblioteca estática correspondiente y crea el ejecutable (nombrado "principal"):

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 
5

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

CDE: Creación automática de aplicaciones Linux portátiles

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

  • Sólo tienes que descargar el programa
  • Ejecutar el paso binaria como argumento el nombre del binario que desea hacer portátil, por ejemplo: nmap

    nmap ./cde_2011-08-15_64bit

El programa leerá todas las bibliotecas vinculadas a nmap y sus dependencias y que evitará todos ellos en una carpeta llamada CDE-paquete/ (en el mismo directorio que usted).

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

Recuerde, para poner en marcha el programa portátil que tiene que exec con el binario situado en CDE-paquete/nmap.cde

Saludos

+0

Aunque no proporciona exactamente la respuesta a la pregunta, es una solución notable al problema. – razong

2

Sí, sé que esto es un 8 año- una vieja pregunta, pero me dijeron que era posible establecer un enlace estático con una biblioteca de objetos compartidos y este fue literalmente el mejor éxito cuando busqué más información al respecto.

Para demostrar que en realidad estática vincular una biblioteca de objetos compartidos no es posible con ld (enlazador gcc 's) - en lugar de sólo un grupo de personas que insisten en que no es posible - utilizar el gcc siguiente comando:

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

(por supuesto, usted tiene que compilar objectname.o de sourcename.c, y probablemente debería hacer su propia biblioteca de objetos compartidos también. Si no, utiliza -Wl,--library-path,. modo que ld puede 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.

Cuestiones relacionadas