Comment puis-je lier statiquement la bibliothèque standard de mon programme c++?
J'utilise Code::Blocks IDE(v13.12) avec GNU GCC Compiler.
- Je veux l'éditeur de liens pour lier des versions statiques des requis bibliothèques d'exécution pour mes programmes,comment puis-je faire cela?
- Je sais déjà que ma taille de l'exécutable va augmenter,voulez-vous me dire d'autres inconvénients?
- Qu'en faisant cela, dans Visual C++ Express?
Et pourquoi voulez-vous à liaison statique?
avoir un seul fichier exécutable est une raison commune.
pourquoi ne vous considérez que c'est une mauvaise pratique? Il y a des raisons pour et contre, bien sûr, mais pas au point où vous devez exclure une approche valable.
Performance sage, il est mauvais? Au niveau des performances, une liaison statique doit être rapide!
Si une bibliothèque dynamique était déjà chargé en mémoire par un autre programme, le temps de chargement serait presque zéro pour le nouveau programme
avoir un seul fichier exécutable est une raison commune.
pourquoi ne vous considérez que c'est une mauvaise pratique? Il y a des raisons pour et contre, bien sûr, mais pas au point où vous devez exclure une approche valable.
Performance sage, il est mauvais? Au niveau des performances, une liaison statique doit être rapide!
Si une bibliothèque dynamique était déjà chargé en mémoire par un autre programme, le temps de chargement serait presque zéro pour le nouveau programme
OriginalL'auteur AmRCPP | 2014-09-29
Vous devez vous connecter pour publier un commentaire.
Puisque personne d'autre n'a encore de réponse, je vais essayer. Malheureusement, je ne sais pas que Code::Blocks IDE donc, ma réponse ne sera que partielle.
1 Comment Créer un Exécutable Lié Statiquement avec GCC
Ce n'est pas IDE spécifique, mais détient pour GCC (et beaucoup d'autres compilateurs) en général. Supposons que vous disposez d'une simple “hello, world” programme de
main.cpp
(sans dépendances externes à l'exception de la bibliothèque standard, et la bibliothèque d'exécution). Vous auriez compiler et lier statiquement par:Compiler
main.cpp
àmain.o
(le nom du fichier de sortie est implicite):La
-c
dit GCC pour s'arrêter après l'étape de compilation (pas exécuter l'éditeur de liens). Le-Wall
tourne sur la plupart des messages de diagnostic. Si les programmeurs débutants qui voudraient l'utiliser plus souvent et de payer plus d'attention à elle, de nombreuses questions sur ce site n'aurait pas été demandé. 😉Lien
main.o
(pu dresser une liste de plus d'un fichier objet) de manière statique en tirant dans la norme et la bibliothèque d'exécution et de mettre le fichier exécutable dans le fichiermain
:Sans l'aide de la
-o main
commutateur, GCC aurait mis l'exécutable final dans le bien-nommé fichiera.out
(qui, une fois finit par se tenait pour “assemblée de sortie”).Surtout au début, je recommande fortement de faire de telles choses “à la main”, qu'il va les aider à obtenir une meilleure compréhension de l'outil de génération de la chaîne.
Comme une question de fait, les deux commandes ci-dessus pourrait avoir été combinées en une seule:
Raisonnables à l'IDE doit avoir des options pour la spécification d'un tel compilateur /linker drapeaux.
2 avantages et les Inconvénients de la Liaison Statique
Raisons pour liaison statique:
Vous avez un fichier unique qui peut être copiée sur une machine avec un compatible architecture et système d'exploitation et il suffit de travail, quelle que soit la version de ce que la bibliothèque est installée.
Vous pouvez exécuter le programme dans un environnement où les bibliothèques partagées ne sont pas disponibles. Par exemple, en mettant statiquement CGI exécutable dans un
chroot()
prison pourrait aider à réduire la surface d'attaque sur un serveur web.Depuis pas de liaison dynamique est nécessaire, le démarrage du programme pourrait être plus rapide. (Je suis sûr qu'il y a des situations où c'est l'inverse, surtout si la bibliothèque partagée est déjà chargé pour un autre processus.)
Depuis l'éditeur de liens peut coder en dur des adresses de fonction, les appels de fonction pourrait être plus rapide.
Sur les systèmes qui ont plus d'une version d'une bibliothèque commune (LAPACK, par exemple) installé, la liaison statique peut aider à faire en sorte qu'une version spécifique est toujours utilisé sans se soucier de réglage de la
LD_LIBRARY_PATH
correctement. Évidemment, c'est aussi un inconvénient car maintenant vous ne peut pas sélectionnez la bibliothèque de plus, sans recompilation. Si vous avez toujours voulu la même version, pourquoi vous avez installé plus d'un en premier lieu?Raisons contre liaison statique:
Comme vous l'avez déjà mentionné, la taille de l'exécutable peut croître de façon spectaculaire. Cela dépend bien sûr fortement sur les bibliothèques que vous lien.
Le système d'exploitation peut être assez intelligent pour charger le texte de la section d'une bibliothèque partagée dans la RAM qu'une seule fois si plusieurs processus ont besoin de la bibliothèque en même temps. En reliant de manière statique, vous annuler cet avantage et le système peut manquer de mémoire plus rapidement.
Votre programme n'a plus de bénéfices à partir de la bibliothèque de mises à niveau. Au lieu de simplement remplacer une bibliothèque partagée avec une (on l'espère ABI compatible) version plus récente, un administrateur système devrez recompiler et réinstaller chaque programme qui l'utilise. C'est le plus grave inconvénient, à mon avis.
Considérer par exemple la bibliothèque OpenSSL. Lorsque le bug Heartbleed a été découverte et fixe au début de cette année, les administrateurs système peuvent installer une version patchée de OpenSSL et redémarrez tous les services de résoudre le problème en une journée dès que le patch a été. C'est, si leurs services ont été le liant de façon dynamique à l'encontre de OpenSSL. Pour ceux qui ont été liés statiquement, il aurait pris des semaines jusqu'à ce que le dernier a été fixé et je suis assez sûr qu'il y en est encore propriétaire “tout en un” logiciel dans la nature qui n'a pas vu un correctif jusqu'à nos jours.
Vos utilisateurs ne peuvent pas remplacer une bibliothèque partagée à la volée. Par exemple, le
torsocks
script (et associé de la bibliothèque) permet aux utilisateurs de remplacer (via le réglageLD_PRELOAD
de façon appropriée) le système de mise en réseau de la bibliothèque par les routes de leur trafic via le réseau Tor. Et cela fonctionne même pour les programmes dont les développeurs n'a même jamais pensé à cette possibilité. (Si c'est sécurisé et une bonne idée est l'objet d'un autre débat.) Une autre commune de cas d'utilisation est de débogage ou de “durcissement” des applications en remplaçantmalloc
et la comme avec les versions spécialisées.À mon avis, les inconvénients de la liaison statique l'emportent sur les avantages, mais dans tous les cas très particuliers. Comme une règle du pouce: lier dynamiquement si vous le pouvez et statiquement si vous avez à.
Un Additif
Comme Alf a souligné (voir les commentaires), il y a un spécial GCC avec l'option de manière sélective lien dans la norme C++ de la bibliothèque de manière statique, mais pas de lien de l'ensemble du programme de manière statique. À partir de la Manuel de GCC:
-static
est assez pour un programme c++? ou est-il une autre option pour la norme c++ de la bibliothèque de la mise en œuvre?Pas tout à fait sûr de ce que tu veux dire.
echo 'int main() {}' > main.cpp && gcc main.cpp -static && ldd a.out
montre qu'il n'existe pas de liens dynamiques. (Comparer sans l'aide de-static
.) Sinon, essayezsu --command="chroot $PWD ./a.out"
avec un simple “hello, world” du programme (dans un répertoire vide) lié avec et sans-static
. Est-ce cela que vous voulez dire?une simple demande. je me souvenais vaguement des option(s) pour le c++ de la bibliothèque standard de mise en œuvre. il s'avère qu'elle a été
-static-libstdc++
, qui permet de lier de manière statique, sans établir de lien de base de la bibliothèque d'exécution de manière statique. docs à (gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/...).C'est bon à savoir; je n'avais aucune idée. D'autre part, je n'ai pas rencontré un cas d'utilisation où j'aurais voulu lier statiquement dans la norme, mais pas le moteur d'exécution et d'autres bibliothèques. Mais qui sait ce que l'avenir nous appeler pour.
Je voudrais ajouter un autre avantage : la liaison statique peut (souvent) de réduire la taille totale de l'exécutable et de la bibliothèque, comme la non-utilisation des fonctions de la bibliothèque ne sera pas inclus. Si vous voulez réduire la taille de l'installateur et de la nécessité d'expédier la bibliothèque avec elle, c'est quelque chose que vous voudrez peut-être.
OriginalL'auteur 5gon12eder
Dans Visual C++, l'option /MT ne un lien statique et /MD en option ne un lien dynamique. (voir http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx)
Je vous recommande d'utiliser /MD et la redistribution de la runtime C++, qui est disponible gratuitement partir de Microsoft. Une fois que le C++ runtime est installé, que n'importe quel programme nécessitant le temps de continuer à travailler. Vous avez besoin de passer la bonne option pour indiquer au compilateur qui moteur d'exécution à utiliser. Il y a une bonne explication ici, Dois-je compiler avec /MD ou /MT?
Sur Linux, je vous recommande la redistribution de libstdc++ au lieu d'un lien statique. Si leur système de libstdc++ fonctionne, j'avais permettre à l'utilisateur de l'utiliser. Les bibliothèques système, tels que libpthread et libgcc faut juste utiliser la valeur par défaut du système. Cela nécessite de compiler le programme sur un système avec des symboles compatible avec toutes les versions de linux que vous distribuez.
Sur Mac OS X, qu'une redistribution de l'application avec la liaison dynamique de libstdc++. Toute personne utilisant la même version de l'OS devrait être en mesure d'utiliser votre programme.
OriginalL'auteur Juan