156 votes

Lien statique d'une fonction de bibliothèque partagée dans gcc

Comment lier statiquement une fonction de bibliothèque partagée dans gcc ?

18 votes

Qu'entendez-vous par liaison statique ? Voulez-vous que votre exécutable soit distribué sans avoir besoin du .so ?

125voto

arsane Points 6500

Se référer à :

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

Vous avez besoin de la version statique de la bibliothèque pour la lier.

Une bibliothèque partagée est en fait un exécutable dans un format spécial avec des points d'entrée spécifiés (et quelques problèmes d'adressage collants inclus). Elle ne possède pas toutes les informations nécessaires pour liaison statique.

Vous ne pouvez pas lier statiquement une bibliothèque partagée (ou lier dynamiquement une bibliothèque statique).

Le drapeau -static forcera l'éditeur de liens à utiliser les bibliothèques statiques (.a) au lieu des bibliothèques partagées (.so). Mais les bibliothèques statiques ne sont pas toujours installées par défaut, et vous devrez peut-être les installer vous-même.

Une autre approche possible consiste à utiliser statifier o Hermine . Les deux outils prennent en entrée un exécutable lié dynamiquement et créent en sortie un exécutable autonome avec toutes les bibliothèques partagées intégrées.

26 votes

Quelles informations la bibliothèque statique possède-t-elle, pour pouvoir être liée statiquement, que la bibliothèque dynamique n'a pas ?

0 votes

Les deux liens sont cassés...

82voto

Eugene Bujak Points 819

Si vous voulez faire un lien, dites, libapplejuice statiquement, mais pas, disons, liborangejuice vous pouvez faire un lien comme ceci :

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

Il y a un avertissement si liborangejuice utilise libapplejuice entonces libapplejuice seront également liés dynamiquement.

Vous devrez relier liborangejuice statiquement à côté de libapplejuice pour obtenir libapplejuice statique.

Et n'oubliez pas de garder -Wl,-Bdynamic sinon vous finirez par lier tout ce qui est statique, y compris libc (ce qui n'est pas une bonne chose à faire).

2 votes

N'y a-t-il pas un moyen de dire directement à gcc ce qu'il faut lier statiquement, et de ne pas le contourner et parler avec l'éditeur de liens ?

1 votes

@ElazarLeibovich vous ne pouvez pas obtenir une combinaison de statique et dynamique de cette façon.

0 votes

@EugeneBujak : Le site avertissement ne s'applique pas sur mon système. Exemple : gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB utilise libA il est lié et ldd ne montre pas de référence à libA . L'exécutable fonctionne bien. Testé avec g++ 4.7.3.

24voto

Ian Moote Points 370

Oui, je sais que c'est une question vieille de 8 ans, mais on m'a dit qu'il était possible d'établir un lien statique avec une bibliothèque d'objets partagés et c'était littéralement le premier résultat lorsque j'ai cherché plus d'informations à ce sujet.

Afin de démontrer que la liaison statique d'une bibliothèque d'objets partagés n'est pas possible avec le logiciel ld ( gcc ) -- par opposition à un groupe de personnes qui insistent sur le fait que ce n'est pas possible -- utilisez ce qui suit gcc commandement :

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

(Bien sûr, vous devrez compiler objectname.o de sourcename.c et vous devriez probablement créer votre propre bibliothèque d'objets partagés. Si vous le faites, utilisez -Wl,--library-path,. pour que ld puisse trouver votre bibliothèque dans le répertoire local).

L'erreur réelle que vous recevez est la suivante :

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

J'espère que cela vous aidera.

21voto

NeoEGM Points 71

Si vous avez le fichier .a de votre bibliothèque partagée (.so), vous pouvez simplement l'inclure avec son chemin complet comme s'il s'agissait d'un fichier objet, comme ceci :

Cela génère main.o en compilant simplement :

gcc -c main.c

Cela lie ce fichier objet avec la bibliothèque statique correspondante et crée l'exécutable (nommé "main") :

gcc main.o mylibrary.a -o main

Ou en une seule commande :

gcc main.c mylibrary.a -o main

Il peut également s'agir d'un chemin absolu ou relatif :

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

11voto

Francis Points 405

Un peu tard mais ... J'ai trouvé un lien que j'avais sauvegardé il y a quelques années et j'ai pensé qu'il pourrait vous être utile :

CDE : Créer automatiquement des applications Linux portables

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

  • Il suffit de télécharger le programme
  • Exécuter le binaire en passant comme argument le nom du binaire que vous voulez rendre portable, par exemple : nmap

    ./cde_2011-08-15_64bit nmap

Le programme lira toutes les librairies liées à nmap et ses dépendances et les sauvegardera toutes dans un dossier appelé cde-package/ (dans le même répertoire que vous).

  • Enfin, vous pouvez compresser le dossier et déployer le binaire portable dans n'importe quel système.

N'oubliez pas que pour lancer le programme portable, vous devez exécuter le binaire situé dans le dossier de l'utilisateur. cde-package/nmap.cde

Meilleures salutations

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X