Y a-t-il un moyen (sous Linux) pour déterminer quelles bibliothèques dois-mêmes relier un programme C / C ++ contre? Je ne veux pas manquer une bibliothèque, même dans des situations où des symboles non définis ne seraient pas détectés au début du programme. En outre, je veux éviter les dépendances inutiles bien sûr. P>
J'ai formulé cette question en général, mais voici un exemple spécifique non séventiel: jusqu'à récemment, je pensais que je dois faire un lien contre libpython em> pour les modules Python développés avec Boost.python. Cependant, ce n'est pas vrai: écrivez un module avec Boost.python; Il pourrait même utiliser des fonctions de l'API Python C, non seulement Boost.python. La liaison contre libboost_python em> est suffisante! Ce n'est pas évident du tout - je ne l'ai pas trouvé documenté, au moins, et il existe des modules Boost.python autour duquel un lien inutilement contre libpython em>. En outre, cela est difficile à détecter depuis libboost_python.so em> ne liste pas libpphon em> comme une dépendance signalée par [ ajouté plus tard: strong> Ceci est indépendant de Boost.python. De plus, si l'API Python C de bas niveau est utilisée, un module Python peut être compilé et ne pas être lié contre libpython em>, et cela fonctionnera. Cependant, voir les commentaires et les réponses ci-dessous indiquant que l'on devrait être associé à libpython em> néanmoins.] P>
Ainsi, comment aurais-je pu découvert sur la liaison inutile systématiquement au lieu d'utiliser l'essai et l'erreur? Quelle est une bonne procédure générale, non seulement pour cet exemple? P>
[ ajouté plus tard: strong> Voici ce que j'ai appris des commentaires à ma question. Les faits ci-dessous ne m'avaient pas clairement clair lorsque j'ai posté cette question, alors je les épelles maintenant, au profit de ceux qui visitent cette discussion à l'avenir, et même si ces choses sont évidentes pour les commentateurs utiles. (Merci!) P>
Résolution des symboles fonctionne de manière transitive sous Linux (comme indiqué par les utilisateurs MVG et MILLIMOOSE). Supposons que le programme a em> doit résoudre les symboles de libb em> et libc em>. Supposons que a em> est lié contre libb em> et libb em> est lié contre libc em>. Ensuite, a em> peut être chargé et exécuté même s'il ne se réfère pas directement à libc em>. P>
Cependant, il est mauvais pratique de compter sur cette transittivité, car les commentateurs ont souligné. Dans le cas des modules Python écrites en C / C ++, cela signifie que l'on devrait être un lien contre libpython em>. Pour l'affaire Général, l'objectif doit pas em> d'identifier la liste minimale des bibliothèques requise pour la liaison et l'exécution, comme ma question orignale est insinuée, mais vraiment de fournir à la liaison avec les bibliothèques nécessaires pour que < em> tous les symboles em> peuvent être résolus directement em>. p>
Résumé de la réponse de Salgar, ces informations ne peuvent normalement être obtenues que de la documentation des bibliothèques utilisées. De plus, le drapeau de la liaison GCC ldd code>. (Je crois que la bibliothèque Python est chargée de manière dynamique dans ce cas.) P>
-WL, - selon les besoins code> est utile pour identifier les bibliothèques qui sont vraiment inutiles.] P>
3 Réponses :
Il n'y a aucun moyen de savoir par magie quelles bibliothèques à inclure, tout comme il n'y a aucun moyen de savoir par magie quels en-têtes à inclure. P>
Il pourrait y avoir 10 bibliothèques différentes, toutes qui ont des fonctions avec les mêmes noms, tout en faisant des choses complètement différentes. C'est à vous de décider lequel vous voulez utiliser. P>
Généralement, ce ne sera pas le cas, mais il sert un point de démonstration. P>
Habituellement, si vous utilisez une bibliothèque de boost ou une autre bibliothèque similaire, la documentation vous permettra de savoir quelle libérez-vous que vous devez relier. P>
Comme une personne ci-dessus indiquée ci-dessus, vous pouvez exclure et utiliser le drapeau - nécessaire, mais de nombreuses personnes ont des problèmes, comme vous êtes généralement lié à une bibliothèque, il est tiré au moment du démarrage et à toutes les variables mondiales. de cette bibliothèque sont initialisés. Que vous ayez besoin de ces variables globales ou non peut être une chose déroutante pour que le linkeur de travailler. P>
En bref cependant, la réponse serait généralement de lire la documentation. Ou pour compiler le code et voir les erreurs de liaison que vous obtenez, puis travaillez à partir de là pour déterminer quelles bibliothèques dont vous avez besoin. P>
Les initialisateurs globaux des bibliothèques statiques sont sujets à supprimer, il ne faut donc pas être intraitable avec le même problème et les mêmes bibliothèques dynamiques.
Il n'y a aucun / trivial / façons, mais vous pouvez en faire beaucoup plus facile à vous en utilisant un outil de gestion de construction comme CUMAKE ou AutoConf. P>
Lorsque vous construisez Boost, vous avez la possibilité de construire des versions statiques ou dynamiques des libs qui sont compilés. Cela fait un moment que je l'ai construit coup de pouce, mais si je me souviens bien construit les deux saveurs si vous faites juste la construction facile. p>
Ceci est couvert dans: p>
En ce qui concerne Boost.Python, l'option entre liaison bibliothèque statique ou dynamique est documenté ici: p>
- http: //www.boost. org / doc / libs / 1_53_0 / libs / python / doc / building.html # dénomination li> ul>
La bibliothèque dynamique est le plus sûr et le choix le plus polyvalent: p>
- Une seule copie du code de la bibliothèque est utilisée par tous les modules d'extension construits avec un toolset.3 donné La bibliothèque contient une conversion de type enregistrement. Du fait d'un registre est partagée entre tous les modules d'extension, instances d'une classe exposée à python dans une dynamiquement chargés module d'extension peut être transmis à des fonctions exposées dans un autre tel module. li> ul>
Il pourrait être approprié d'utiliser la bibliothèque Boost.Python de statique dans une des cas suivants: p>
Vous êtes extension python et les types exposés dans votre ne pas besoin de module d'extension chargé dynamiquement à utiliser par tout autre Boost.Python modules d'extension, et vous ne se soucient pas si la bibliothèque de base le code est dupliqué parmi eux. p> li>
Vous intégrez python dans votre application et soit: p>
Vous ciblez une variante Unix OS autre que Mac OS ou AIX, où les modules d'extension dynamiquement chargé peut « voir » l'Boost.Python des symboles de bibliothèque qui font partie de l'exécutable. p> li>
Ou, vous avez lié statiquement certains modules d'extension Boost.Python dans votre application et vous ne vous inquiétez pas si chargé dynamiquement Boost.Python modules d'extension sont capables d'utiliser les types exposés par les modules d'extension statiquement liées (et vice-versa). p> li> Ul> li> ul> blockQuote>
Alors, d'accord, cela n'explique pas comment vous savez quoi lien contre dans un sens générique. Juste qu'une situation spécifique. p>
Je pense que la confusion sur la façon dont Boost.Python travaux et les différentes expériences que les gens commentent en ce qui concerne reliant pourrait faire un peu plus de sens quand on regarde à travers cette lentille au moins. p>
Si ce n'est pas nécessaire, cela coûte un peu de temps pour comprendre cela, mais il le supprimera ensuite de la liste des dépendances, tout comme vous ne l'aviez pas passé.
@Ben: Je ne pense pas. Dans mon exemple, si je passe
-lpythonx.y code> comme indicateur de compilateur, alors libpytHonx.y.so i> apparaît dans la sortie code> ldd code>, Même si le module fonctionne bien sans la dépendance libpython i>.Essayez également une bibliothèque aléatoire (n'importe quoi à partir de votre répertoire
/ usr / lib code>). Si vous vous trouvez un lien contre celui-ci, il apparaîtra dans la sortie code> LDD code>, même si rien de celui-ci n'est utilisé.Hmm, doit être différent version de liaison se comporter différemment
Il suffit de lire la documentation ne fonctionne pas?
@BENVOIGT: Ce comportement nécessite généralement un drapeau de liaison:
-WL, - selon les besoins code>.Sur mon système (Gentoo), libboost_python dépend de libpython selon
ldd code>. Donc, cela tirerait dans le DEP au moment de la liaison. Je considérerais que c'est un style mauvais de compter sur ce type de dépendances transitives, cependant: si vous utilisez des trucs de LibpyptHon, il est plus propre de dépendre directement de cela. De cette façon, vous aurez nicice si par ex. Python change son abi et Boost a été mis à jour pour correspondre, mais votre application utilise toujours l'ancien et désormais invalide ABI.Généralement
Man Code> Les pages et autres documents vous permettent de connaître les bibliothèques dont vous avez besoin pour relier."Ecrire un module avec
boost.python code>; il pourrait même utiliser des fonctions de l'API Python C, non seulementboost.python code>. Liaison contrelibboost_python code> est suffisant!" - Il est bien sangleux n'est pas. Si vous utilisez des fonctions danslibpython code>, le lien entre il n'est pas nécessaire par définition. S'appuyant sur la transitivité des dépendances est juste laid et fragile.Pouvez-vous préciser ces "situations dans lesquelles des symboles non définis ne seraient pas détectés au début du programme"?
Le plan 9 avait un moyen élégant de traiter des dépendances en-tête / liaison. Malheureusement, cela ne retrouve pas son chemin vers Unix / Linux, le suivi de la dépendance est donc toujours le fardeau du programmeur.