Les bibliothèques statiques C sont-elles mal vues? [fermé]


11

Il y a 2 arguments pour avoir des bibliothèques partagées:

  1. Il aide à réduire l'espace disque.
  2. Lorsqu'une bibliothèque partagée est mise à jour, tous les binaires qui en dépendent reçoivent la mise à jour.

Il y a principalement un inconvénient pour les bibliothèques partagées:

  • Ils (peuvent) introduire l'enfer de la dépendance.

Sur les ordinateurs de bureau, le 1er avantage ne tient plus vraiment. Le gaspillage d'espace disque n'est plus vraiment un problème de nos jours.

Avoir des binaires statiques nous permettrait d'obtenir de bien meilleurs gestionnaires de paquets - je veux dire, l'enfer de la dépendance serait une chose du passé. Ajouter un programme serait simplement ajouter un binaire; éventuellement un dossier pour le laisser gérer ses fichiers. Supprimer un programme reviendrait simplement à supprimer ce fichier. Dépendances? Disparu.

Le deuxième avantage est toujours valable, mais je pense que l'avantage des binaires statiques sur les ordinateurs de bureau l'emporte. Je veux dire, même de nouvelles langues comme Go compilent tous leurs binaires malgré les avantages des bibliothèques partagées, à cause de la commodité.


Étant donné que l'un des principaux avantages des bibliothèques partagées n'est plus un problème, les bibliothèques statiques C sont-elles toujours mal vues? Si oui, pourquoi?


4
La principale raison pour laquelle C est utilisé est précisément parce que vous ne travaillez pas sur des ordinateurs de bureau modernes.
Telastyn

18
@Telastyn Je suis désolé? La plupart des logiciels installés sur mes ordinateurs de bureau sont écrits en C.
Florian Margaine

6
Side bit - une lecture hors site sur le sujet - Dynamic Linking Considered Harmful

6
Un avantage des bibliothèques dynamiques est que les gens peuvent toujours mettre à jour les bibliothèques pour contourner les bogues, les failles de sécurité ou les problèmes matériels dans votre jeu source fermé de 15 ans qui a depuis longtemps cessé de recevoir des mises à jour. Une sorte de cas de niche, mais comme les bons jeux ne sont pas des produits de base, "il suffit d'utiliser un autre programme" n'aide pas vraiment. Il est également important de se conformer à LGPL sans avoir à ouvrir votre propre code.
Doval

4
Vous avez oublié deux autres avantages des bibliothèques partagées: 1) elles sont également partagées en mémoire, 2) tous les éditeurs de liens craignent mal, et lier un énorme binaire est très désagréable. La division d'un binaire en plusieurs entités plus petites rend l'ensemble du processus beaucoup plus tolérable.
SK-logic

Réponses:


9

La prémisse de votre question est erronée. Ce qui est mal vu, c'est de s'en tenir aux doctrinaires et aux absolus sans aucune compréhension de la base derrière eux (Cargo Cult Programming?).

La réponse SO liée est une étude intéressante dans ce même sujet - la question était de savoir pourquoi une compilation avec l'option -static ne fonctionnait pas, la réponse à laquelle vous étiez lié n'était rien de plus qu'une diatribe de ne pas utiliser de liaison statique. Si ne discute pas pourquoi son mauvais, et exige l'OP utilise la liaison dynamique. C'est malheureux, il est marqué comme la bonne réponse (la réponse suivante a deux fois plus de votes et est la bonne réponse à la question du PO) car bien que la bonne réponse soit là, elle est profondément cachée parmi une opinion dogmatique.

La vraie question est de savoir quels sont les avantages et les inconvénients de la liaison statique vs dynamique et quand serait-on préféré à l'autre.


2
La réponse de Basile ne vous dire précisément pourquoi il recommande d' utiliser des bibliothèques partagées: « Pourquoi voulez - vous lien statiquement votre application . Il est généralement une erreur (parce que vous ne profitent pas de mises à jour des bibliothèques dynamiques du système) commutateur de service de nom particulier les installations de libc veulent des bibliothèques dynamiques. " Ce n'est pas une" diatribe "juste parce que vous n'êtes pas d'accord avec cela.
Cody Gray

@Cody La réponse liée à a été modifiée depuis que je l'ai appelée une diatribe. La seule opinion que j'ai sur les liens statiques vs dynamiques est d'utiliser celle qui convient à vos besoins, et de comprendre les forces et les faiblesses du choix plutôt que de tomber dans la doctrine de la programmation culte du fret parce que "quelqu'un l'a dit".
mattnz

Oui, la partie "En particulier ..." a été ajoutée. Je ne sais pas comment cela affecte son statut de délire. Bien sûr, je ne préconise pas une programmation culte du fret. C'est juste que les partisans des liens statiques (d'après mon expérience) manquent ou sous-estiment souvent les problèmes de sécurité. La liaison statique peut être très appropriée pour les utilitaires ponctuels, ce qui rend l'application autonome et donc la distribution beaucoup plus facile. Mais toute application qui sera largement déployée ou utilisée pour la production devrait vraiment être liée à une bibliothèque partagée. Il n'y a pas de réels inconvénients: à ce niveau d'application, vous avez déjà besoin d'un processus de déploiement.
Cody Gray

1
Un bon exemple de lien statique approprié est celui où je travaille - de grands systèmes complexes et vitaux. Une fois qu'un module critique est testé et approuvé pour son fonctionnement, son comportement ne doit pas changer sans passer par «le processus». Cependant, aucune partie critique et non vitale du système (facturation et rapports) n'a besoin d'un contrôle moins robuste et utilise une liaison dynamique.
mattnz

7

Du point de vue du développeur, la liaison dynamique peut souvent accélérer considérablement votre boucle de compilation / lien / test.

Du point de vue de la gestion des packages, prenez par exemple libGL. J'ai environ une douzaine d'implémentations différentes disponibles dans mon gestionnaire de packages, certaines génériques et certaines ciblant des cartes graphiques spécifiques. S'il n'était pas lié dynamiquement, il devrait y avoir une douzaine de versions de chaque programme qui se relient à libGL, ou bien vous devriez concevoir une couche supplémentaire d'abstraction qui n'est pas aussi efficace qu'un appel de fonction.

Pensez à un problème de sécurité dans une bibliothèque populaire comme Qt. Avec la liaison dynamique, je peux simplement mettre à jour ce package, au lieu d'avoir à identifier, recompiler et déployer chaque package qui relie dans Qt.

La liaison statique peut présenter des avantages dans les applications de sources fermées déployées de manière indépendante, mais dans la gestion des packages open source, cela fait plus mal que cela n'aide.


2
C'est vrai (accélérant le développement), mais c'est vraiment frustrant de voir qu'il est en production. L'exemple canonique est Firefox. La quantité d'efforts d'ingénierie (sous la forme de hacks hideux) qui ont été consacrés à l'accélération de la résolution des symboles de liaison dynamique afin que Firefox se charge dans un délai raisonnable est complètement folle. Des performances bien meilleures auraient pu être obtenues avec des coûts d'ingénierie bien inférieurs s'ils étaient simplement disposés à lier statiquement tout leur code dans le projet (tout en continuant à lier dynamiquement les bibliothèques système et les plugins, si vous le souhaitez).
R .. GitHub STOP HELPING ICE

5

Les bibliothèques partagées sont fortement préférées par les responsables de la distribution Linux pour essentiellement votre raison n ° 2. Il est vraiment important pour eux que, par exemple, lorsque quelqu'un trouve un bogue de sécurité dans zlib , il n'ait pas à recompiler chacun des programmes qui utilisent zlib --- non seulement cela leur coûterait plus de cycles CPU pour faire le lors de la recompilation, tous ceux qui utilisent la distribution devraient alors télécharger à nouveau tous ces programmes. En attendant, au sein de l'ensemble des packages fournis par une distribution, l'enfer de dépendance n'est pas un problème, car tout est testé pour fonctionner avec cet ensemble de bibliothèques.

Si vous créez un logiciel tiers qui a besoin de bibliothèques qui ne sont pas dans votre distribution, la liaison statique de ces bibliothèques peut être moins compliquée que l'alternative, et c'est très bien.

L'autre chose importante à savoir est que GNU libcet GCC ont libstdc++tous deux des composants qui ne fonctionnent pas de manière fiable si la bibliothèque est liée statiquement. Le problème le plus courant est avec dlopen, car le module avec lequel vous chargez dlopenest lui-même lié dynamiquementlibc.so.6 . Cela signifie donc que vous avez maintenant deux copies de la bibliothèque C dans votre espace d'adressage, et l'hilarité s'ensuit quand ils ne s'entendent pas sur la copie de la mallocstructure de données interne (par exemple) qui fait autorité. Cela empire: tout un tas de fonctions qui ne semblent avoir rien à voir avec dlopen, comme gethostbynameet iconv, utiliserdlopenen interne (pour que leur comportement soit configurable à l'exécution). Heureusement, l'ABI pour libc et libstdc ++ est très stable, il est donc peu probable que vous rencontriez des problèmes pour les lier dynamiquement.


2

Je suis d'accord avec le dernier point de Mattnz: cette question est une question chargée. Il suppose que la liaison statique est mauvaise. Je peux penser à deux raisons pour lesquelles ce n'est pas le cas:

  • La liaison statique est sûre: si une bibliothèque partagée est mise à jour de sorte qu'une application utilise la nouvelle (peut-être que la nouvelle écrase l'ancienne ou que l'ancienne est supprimée), cela peut présenter un risque que la nouvelle version casse l'application. Il s'agit d'un changement de code qui sort du cadre d'une mise à jour officielle de l'application. Il n'a peut-être pas été testé. La liaison statique évite cela en ne partageant pas les bibliothèques en externe. Je considère que c'est un inconvénient pour les bibliothèques partagées en raison de ce risque. Que se passe-t-il si une nouvelle version d'une bibliothèque partagée introduit un nouveau bogue qui casse certaines applications plus anciennes?

  • La liaison statique garantit qu'une application est plus autonome. Bien que les bibliothèques partagées puissent être colocalisées avec l'exécutable principal, elles sont souvent déposées dans des emplacements partagés. Les applications liées statiquement sont plus faciles à garantir "portables" dans le sens de "ne nécessiter aucune modification des fichiers, répertoires ou paramètres appartenant au système d'exploitation" (pensez au répertoire Windows, au registre, / etc).


Merci d'avoir amélioré les avantages que je voulais mentionner. Cependant, si vous voyez la plupart des packages fournis par les distributions Linux par exemple, ils ne sont pas compilés statiquement. Il ne semble que la compilation statique est mal, au moins d'un point de vue extérieur.
Florian Margaine

1
Les bibliothèques dynamiques sur à peu près tous les systèmes d'exploitation de nos jours sont paginées par la demande. Seules les pages actuellement utilisées sont en mémoire. Si plusieurs applications utilisent la même fonctionnalité, elles partageront la mémoire et utiliseront moins que le boîtier de bibliothèque statique. Si plusieurs applications utilisent des fonctionnalités différentes dans la même bibliothèque, les deux ensembles de fonctionnalités seront paginés, ayant approximativement le même impact que l'approche statique.
Alan Shutko

@AlanShutko J'ai eu du mal à retaper cette partie de plusieurs façons à cause de ce que vous avez mentionné. Il n'y a aucune véritable garantie dans les deux cas, même si les systèmes d'exploitation modernes offrent en pratique l'efficacité des bibliothèques partagées avec le surcoût de l'électricité statique. Je modifierai à nouveau.

@Snowman Je pense que le point fondamental est que sur tout système d'exploitation réaliste qui fournit une liaison dynamique (je ne connais aucun système d'exploitation qui utilise la liaison dynamique mais ne demande pas de pagination), votre deuxième point ne tient pas la route: la mémoire n'est pas réellement utilisée sauf si la fonction est utilisée et que la mémoire utilisée par une bibliothèque dynamique peut être partagée entre différents programmes l'utilisant, ce qui rend l'utilisation de la mémoire pour la version dynamique plus efficace que moins. Vos première et troisième raisons sont valables, mais je supprimerais simplement la seconde: avec des hypothèses réalistes, c'est tout simplement faux.
Jules

@Jules Je suis d'accord, c'est un point qui était problématique et d'une validité douteuse dans les systèmes d'exploitation modernes. Je l'ai enlevé.

1

Les bibliothèques statiques et dynamiques ont chacune leurs propres utilisations. En examinant une seule application, nous obtenons une idée différente de ce qui est nécessaire et de ce qui ne l'est pas.

La liaison statique simplifie considérablement le déploiement d'applications. Ne pas avoir à détecter et gérer différentes versions. Il suffit de cuire et de déployer.

L'avantage évident des bibliothèques dynamiques est la possibilité d'appliquer des mises à jour de manière indépendante.

C'est l'une des raisons pour lesquelles je déteste maven et d'autres constructeurs de projets de liaison dynamique similaires pour java. Ils s'attendent à ce qu'une version de bibliothèque unique soit disponible pour une URL donnée pour toujours et à jamais. Ne pas comprendre le problème qui se produit en 10 ans lorsque personne ne peut compiler l'application car toutes les sources et tous les bocaux ont disparu.


Y a-t-il une raison particulière pour laquelle les programmes qui utilisent ne devraient pas être en FooLib1.8mesure d'inclure le code de cette bibliothèque dans leur package exécutable de manière standard, afin de permettre à un utilitaire FooLib1.9de mise à niveau livré avec de le mettre à niveau ou de le rétrograder? La façon dont le code était stocké dans Macintosh classique aurait rendu cela assez facile; Y a-t-il une raison pour que les systèmes d'aujourd'hui ne puissent pas le faire encore mieux?
supercat

@supercat vous voulez dire que chaque version d'une bibliothèque donnée serait disponible sur le système? Je ne suis pas sûr de comprendre la question. La question OP visait davantage les bibliothèques partagées à l'échelle du système que les bibliothèques statiques qui seraient regroupées.
beaucoup de chips

Mon point était que le fait d'avoir un package exécutable incluant toutes les bibliothèques dont il a besoin ne devrait pas avoir à exclure la possibilité de mettre à niveau les bibliothèques qu'il contient. Ainsi, je ne sais pas si je considérerais la possibilité de mettre à niveau les choses après le déploiement comme un avantage de ne pas regrouper une application avec ses bibliothèques.
supercat

Si la licence d'une bibliothèque donnée vous permet de la distribuer avec votre package, c'est toujours la manière préférée de le faire. Il réduit le nombre de dépendances externes. Puisque vous distribueriez tout, une mécanique de mise à niveau ou de correction fonctionnerait de la même manière avec statique ou dynamique. Patching généralement basé sur des deltas binaires. Il n'y aurait aucune différence.
beaucoup de chips
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.