Lier une bibliothèque partagée à une bibliothèque statique: la bibliothèque statique doit-elle être compilée différemment que si une application la liait?

Au moins sur Linux et Solaris, les bibliothèques statiques ne sont en réalité qu’un tas de fichiers .o compilés jetés dans un seul fichier volumineux. Lors de la compilation d’une bibliothèque statique, l’indicateur –fpic est généralement omis, le code généré dépend donc de la position.

Supposons maintenant que ma bibliothèque statique est B. Je l’ai construite et j’ai obtenu le fichier .a résultant, qui n’est en réalité qu’un aperçu de tous les fichiers .o dépendants de la position. Maintenant, j’ai une bibliothèque partagée que j’aimerais construire, A, et je veux qu’elle lie statiquement B. Lorsque je construis A, naturellement, j’utilise le drapeau -fpic pour rendre la position du code généré indépendante. Mais si je fais la liaison avec B, est-ce que je ne mélange pas des fichiers object dépendants de la position et indépendants de la position?

Je reçois beaucoup d’erreurs de déplacement de texte, sauf si je spécifie également -mimpure-text, et je pense que c’est peut-être la cause. Il semble que lorsque je comstack une bibliothèque, j’ai vraiment besoin de la comstackr 3 fois, une version partagée, une version statique et une version statique qui puisse être utilisée par des bibliothèques partagées. Ai-je raison? Je pourrais simplement continuer à utiliser -mimpure-text, mais la page de manuel g ++ indique que si vous le faites, l’object ne sera pas partagé (il est difficile de savoir si tout est non partagé ou si les parties sont liées statiquement, ce que quelqu’un sait?) .

    Vous n’êtes pas obligé d’utiliser le code PIC dans les objects partagés (comme vous l’avez découvert, vous pouvez utiliser l’option -mimpure-text pour autoriser cela).

    Cela dit, le code non-PIC dans les objects partagés est plus lourd. Avec le code PIC, les pages de texte en mémoire ne sont que des mappages directs en mémoire des pages de texte sur le disque. Cela signifie que si plusieurs processus utilisent l’object partagé, ils peuvent partager la page de mémoire.

    Mais si vous n’avez pas de code PIC, lorsque l’éditeur de liens au moment de l’exécution charge l’object partagé, il doit appliquer des corrections aux pages de texte. Cela signifie que chaque processus qui utilise l’object partagé aura sa propre version unique de toute page de texte comportant une correction (même si l’object partagé est chargé à la même adresse que celle utilisée pour la copie sur écriture, notez simplement que la page a été copiée. modifié et non qu’il ait été modifié de la même manière).

    Pour moi, la question importante est de savoir si vous allez avoir simultanément plusieurs processus qui chargent chacun l’object partagé. Si vous le faites, cela vaut vraiment la peine de s’assurer que tout le code au sein du SO est un PIC.

    Mais si ce n’est pas le cas et que l’object partagé n’est chargé que dans un seul processus, ce n’est pas aussi critique.

    À l’étape des liens, je procède comme suit pour la version de la bibliothèque d’objects partagés d’une bibliothèque statique: g ++ -shared -o libshared.so -Wl, – archive entière -fPIC -lstatic -Wl, – pas d’archive complète. Comme –whole-archive lie tous les objects d’une (liste de) bibliothèques statiques (de la forme libstatic.a), je crois que précéder (list) avec -fPIC est tout ce que l’OP doit faire.

    En guise d’approche alternative, expédiez deux bibliothèques: la bibliothèque partagée et la statique avec laquelle vous créez un lien. Ils doivent être liés correctement dans l’exécutable final.