Liaison dynamique des bibliothèques lors de la compilation du code


  • Français


  • Compiler des logiciels est quelque chose que les développeurs font beaucoup, et dans l’open source, certains utilisateurs choisissent même de le faire eux-mêmes. Le podcasteur Linux Dann Washko appelle le code source le “format de package universel” car il contient tous les composants nécessaires pour faire fonctionner une application sur n’importe quelle plate-forme. Bien sûr, tout le code source n’est pas écrit pour tous les systèmes, il n’est donc “universel” que dans le sous-ensemble de systèmes ciblés, mais le fait est que le code source est extrêmement flexible. Avec l’open source, vous pouvez décider comment le code est compilé et exécuté.

    Lorsque vous compilez du code, vous avez généralement affaire à plusieurs fichiers source. Les développeurs ont tendance à conserver différentes classes ou modules dans des fichiers séparés afin qu’ils puissent être maintenus séparément, et éventuellement même utilisés par différents projets. Mais lorsque vous compilez ces fichiers, beaucoup d’entre eux sont compilés en un seul exécutable.

    Cela se fait généralement en créant des bibliothèques partagées, puis en les reliant dynamiquement à partir de l’exécutable. Cela réduit la taille de l’exécutable en gardant les fonctions modulaires externes et garantit que les bibliothèques peuvent être mises à jour indépendamment des applications qui les utilisent.

    Programmation et développement

    Localisation d’un objet partagé lors de la compilation

    Lorsque vous compilez avec GCC, vous avez généralement besoin qu’une bibliothèque soit installée sur votre poste de travail pour que GCC puisse la localiser. Par défaut, GCC suppose que les bibliothèques se trouvent dans un chemin de bibliothèque système, tel que /lib64 et /usr/lib64. Cependant, si vous créez un lien vers une bibliothèque qui n’est pas encore installée ou si vous devez créer un lien vers une bibliothèque qui n’est pas installée à un emplacement standard, vous devez aider GCC à trouver les fichiers.

    Il existe deux options importantes pour trouver des bibliothèques dans GCC :

    • -L (L majuscule) ajoute un chemin de bibliothèque supplémentaire aux emplacements de recherche de GCC.
    • -l (minuscule L) définit le nom de la bibliothèque que vous souhaitez lier.

    Par exemple, supposons que vous ayez écrit une bibliothèque appelée libexample.soet vous souhaitez l’utiliser lors de la compilation de votre application demo.c. Tout d’abord, créez un fichier objet à partir de demo.c:

    $ gcc -I ./include -c src/demo.c

    La -I L’option ajoute un répertoire au chemin de recherche de GCC pour les fichiers d’en-tête. Dans cet exemple, je suppose que les fichiers d’en-tête personnalisés se trouvent dans un répertoire local appelé include. La -c L’option empêche GCC d’exécuter un éditeur de liens, car cette tâche consiste uniquement à créer un fichier objet. Et c’est exactement ce qui se passe :

    $ ls
    demo.o   include/   lib/    src/

    Vous pouvez maintenant utiliser le -L option pour définir un chemin pour votre bibliothèque, et compilez :

    $ gcc -L`pwd`/lib -o myDemo demo.o -lexample

    Remarquez que le -L l’option vient avant de la -l option. Ceci est significatif, car si -L n’a pas été ajouté au chemin de recherche de GCC avant que vous disiez à GCC de rechercher une bibliothèque autre que celle par défaut, GCC ne saura pas rechercher dans votre emplacement personnalisé. La compilation réussit comme prévu, mais il y a un problème lorsque vous essayez de l’exécuter :

    $ ./myDemo
    ./myDemo: error while loading shared libraries:
    libexample.so: cannot open shared object file:
    No such file or directory

    Dépannage avec ldd

    La ldd l’utilitaire imprime les dépendances d’objets partagés, et il peut être utile lors du dépannage de problèmes comme celui-ci :

    $ ldd ./myDemo
            linux-vdso.so.1 (0x00007ffe151df000)
            libexample.so => not found
            libc.so.6 => /lib64/libc.so.6 (0x00007f514b60a000)
            /lib64/ld-linux-x86-64.so.2 (0x00007f514b839000)

    Tu le savais déjà libexample n’a pas pu être localisé, mais le ldd la sortie affirme au moins ce que l’on attend d’un travail bibliothèque. Par exemple, libc.so.6 a été localisé, et ldd affiche son chemin complet.

    LD_LIBRARY_PATH

    La LD_LIBRARY_PATH La variable d’environnement définit le chemin d’accès aux bibliothèques. Si vous exécutez une application qui s’appuie sur une bibliothèque qui n’est pas installée dans un répertoire standard, vous pouvez ajouter au chemin de recherche de la bibliothèque du système à l’aide de LD_LIBRARY_PATH.

    Il existe plusieurs façons de définir des variables d’environnement, mais la plus flexible consiste à les placer avant d’exécuter une commande. regarde quel réglage LD_LIBRARY_PATH fait pour le ldd commande lorsqu’elle analyse un exécutable “cassé”:

    $ LD_LIBRARY_PATH=`pwd`/lib ldd ./
       linux-vdso.so.1 (0x00007ffe515bb000)
       libexample.so => /tmp/Demo/lib/libexample.so (0x0000...
       libc.so.6 => /lib64/libc.so.6 (0x00007eff037ee000)
       /lib64/ld-linux-x86-64.so.2 (0x00007eff03a22000)

    Cela s’applique tout aussi bien à votre commande personnalisée :

    $ LD_LIBRARY_PATH=`pwd`/lib myDemo
    hello world!

    Si vous déplacez le fichier de bibliothèque ou l’exécutable, cependant, il se casse à nouveau :

    $ mv lib/libexample.so ~/.local/lib64
    $ LD_LIBRARY_PATH=`pwd`/lib myDemo
    ./myDemo: error while loading shared libraries...

    Pour y remédier, vous devez ajuster le LD_LIBRARY_PATH pour correspondre au nouvel emplacement de la bibliothèque :

    $ LD_LIBRARY_PATH=~/.local/lib64 myDemo
    hello world!

    Quand utiliser LD_LIBRARY_PATH

    Dans la plupart des cas, LD_LIBRARY_PATH n’est pas une variable que vous devez définir. De par leur conception, les bibliothèques sont installées pour /usr/lib64 et ainsi les applications le recherchent naturellement pour leurs bibliothèques requises. Vous devrez peut-être utiliser LD_LIBRARY_PATH dans deux cas :

    • Vous compilez un logiciel qui doit être lié à une bibliothèque qui vient elle-même d’être compilée et qui n’a pas encore été installée. De bons systèmes de construction, tels que Autotools et CMake, peuvent aider à gérer cela.
    • Vous regroupez des logiciels conçus pour fonctionner à partir d’un seul répertoire, sans script d’installation ou avec un script d’installation qui place les bibliothèques dans des répertoires non standard. Plusieurs applications ont des versions qu’un utilisateur Linux peut télécharger, copier sur /opt, et exécuter avec “pas d’installation.” La LD_PATH_LIBRARY La variable est définie via des scripts wrapper, de sorte que l’utilisateur n’est souvent même pas conscient qu’elle a été définie.

    La compilation de logiciels vous offre une grande flexibilité dans la façon dont vous exécutez votre système. La LD_LIBRARY_PATH variables, ainsi que la -L et -l Les options GCC sont des composantes de cette flexibilité.

    Source

    Houssen Moshinaly

    Pour contacter personnellement le taulier :

    Laisser un commentaire

    Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

    Copy code