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.
¿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"):
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:
(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
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
Respuestas:
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
-static
obligará 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.
fuente
Si desea vincular, por ejemplo, libapplejuice estáticamente, pero no, por ejemplo, liborangejuice , puede vincular así:
Hay una advertencia: si se
liborangejuice
usalibapplejuice
, entonceslibapplejuice
también se vinculará dinámicamente.Tendrás que vincular
liborangejuice
estáticamente junto conlibapplejuice
para obtenerlibapplejuice
estática.Y no olvides guardar
-Wl,-Bdynamic
otra cosa, terminarás vinculando todo estático, incluidolibc
(lo cual no es algo bueno).fuente
gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L.
libB usa libA , está vinculado yldd
no muestra una referencia a libA . El ejecutable funciona bien. Probado con g ++ 4.7.3.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:
Esto vincula ese archivo de objeto con la biblioteca estática correspondiente y crea el ejecutable (llamado "main"):
O en un solo comando:
También podría ser una ruta absoluta o relativa:
fuente
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 siguientegcc
comando:(Por supuesto, tendrá que compilar
objectname.o
desdesourcename.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:
Espero que ayude.
fuente
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
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).
Recuerde, para iniciar el programa portátil debe ejecutar el binario ubicado en cde-package / nmap.cde
Atentamente
fuente
En gcc, esto no es compatible. De hecho, esto no es compatible con ningún compilador / enlazador existente que conozca.
fuente