2011-05-28 4 views
6

J'ai besoin de relier statiquement toutes mes bibliothèques, y compris libstdC++, libc, pthread etc. Il y a une bibliothèque omniorb que je veux lier dynamiquement.Comment lier statiquement toutes les bibliothèques à l'exception de quelques-unes utilisant g ++?

Actuellement, j'ai dynamiquement lié toutes les bibliothèques. ldd affiche les informations suivantes

linux-vdso.so.1 => (0x00007fff251ff000) 
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f291cc47000) 
libomniDynamic4.so.1 (0x00007f291c842000) 
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f291c536000) 
libm.so.6 => /lib64/libm.so.6 (0x00007f291c2e0000) 
libgomp.so.1 => /usr/lib64/libgomp.so.1 (0x00007f291c0d7000) 
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f291bebf000) 
libc.so.6 => /lib64/libc.so.6 (0x00007f291bb66000) 
/lib64/ld-linux-x86-64.so.2 (0x00007f291ce63000) 
librt.so.1 => /lib64/librt.so.1 (0x00007f291b95d000) 
libomniORB4.so.1 (0x00007f291b6aa000) 
libomnithread.so.3 (0x00007f291cf35000 

J'ai besoin ldd pour montrer libomniDynamic4.so.1 comme la bibliothèque seulement liée dynamiquement.

Comment puis-je y parvenir?

Répondre

-4

Lors de la liaison, utilisez -static avant de spécifier les bibliothèques que vous voulez lier statiquement, et utilisez -dynamic avant les bibliothèques que vous voulez lier dynamiquement. Vous devriez vous retrouver avec une ligne de commande qui ressemble à ceci:

g++ <other options here> -dynamic -lomniDynamic4 -static -lpthread -lm -lgomp <etc> 

Bien sûr, vous aurez besoin .a versions des bibliothèques que vous voulez lier statiquement (duh).

+6

Cette réponse est * complètement * fausse: -static désactive -dynamic et vice versa. Le dernier gagne. –

10

Vous essayez de créer un exécutable Linux qui s'exécute sur toutes les distributions? Bonne chance ... Mais je m'égare ...

Vous voulez regarder la sortie de drapeau -v pour g ++. Il montre les commandes de liens internes exécutées par g ++/ld. Plus précisément, vous voudrez inspecter la commande de liaison finale collect2 et tous ses arguments. Vous pouvez ensuite spécifier les chemins exacts vers les bibliothèques .a que vous voulez lier. Vous devrez également retrouver les bibliothèques statiques de tout. Mon libstdC++. A est en /usr/lib/gcc/x86_64-linux-gnu/4.4/libstdc++.a

rant on: Ma plus grande plainte à propos de Linux est l'état fracturé des exécutables. Pourquoi ne puis-je pas compiler un binaire sur une machine et le copier dans un autre et l'exécuter? Même le distros une version d'Ubuntu en dehors produira des fichiers binaires qui ne peuvent pas être exécutés sur l'autre en raison de libc/libstdC++ ABI incompatibilités

modifier # 1 Je voulais juste ajouter que The script on this page produces a .png of an executables .so dependencies. C'est très utile lors d'une tentative faire ce que vous décrivez. Sachez que ldd <exename> listera toutes les dépendances dans la chaîne, pas seulement les dépendances immédiates de l'exécutable. Donc même si votre exécutable ne dépendait que de omniorb.so, mais que omniorb.so dépendait de, libphread.so, la sortie de ldd le listerait. Recherchez la page de manuel de readelf pour rechercher uniquement les dépendances immédiates d'un fichier binaire.

Un autre élément à connaître. Si omniorb.so dépend de libstdC++, vous n'aurez pas d'autre choix que d'être dépendant de cette même lib. Sinon, les incompatibilités ABI vont casser RTTI entre votre code et le code d'omniorb.

+1

Frustrant, je n'ai pas suffisamment de rep pour commenter le post de n'importe qui. Mais j'aimerais demander à @EmployedRussian pourquoi les binaires "plutôt statiques" ne sont pas plus portables. Pourquoi le contraire est-il vrai? J'ai été capable de produire des binaires qui n'étaient pas capables de fonctionner sans la route "presque statique" ... –

+1

Vous avez maintenant le représentant nécessaire pour commenter partout. Veuillez utiliser votre pouvoir nouvellement acquis à bon escient. – sbi

6

J'ai besoin de ldd pour afficher libomniDynamic4.so.1 en tant que seule bibliothèque liée dynamiquement.

Ceci est impossible.

D'abord, ldd sera toujours montrent ld-linux-x86-64.so.2 pour tout (x86_64) binaire qui nécessite une liaison dynamique.Si vous utilisez la liaison dynamique (ce qui serait le cas avec libomniDynamic4.so.1), alors obtiendrez ld-linux-x86-64.so.2.

Deuxièmement, linux-vdso.so.1 est "injecté" dans votre processus par le noyau. Vous ne pouvez pas se débarrasser de cela non plus.

Ensuite, la question est pourquoi vous voulez minimiser l'utilisation des bibliothèques dynamiques. La raison la plus courante est généralement la croyance erronée selon laquelle les binaires «essentiellement statiques» sont plus portables et fonctionneront sur plus de systèmes. Sur Linux c'est le contraire de vrai.

Si en fait vous essayez d'obtenir un binaire portable, plusieurs méthodes existent. Le meilleur pour l'instant (selon mon expérience) a été d'utiliser apgcc.

+3

Pouvez-vous élaborer sur votre commentaire "* La raison la plus courante est généralement la croyance erronée que les binaires" essentiellement statiques "ne sont pas plus portables, et fonctionneront sur plus de systèmes.Sur Linux, c'est le contraire de la vérité." été capable de produire des binaires qui ne pouvaient pas fonctionner sur d'autres machines sans la route "la plupart du temps statique" ... –

Questions connexes