Rechercher

2.3. Utilisation de bibliothèques avec GCC

download PDF

Ce chapitre décrit l'utilisation des bibliothèques dans le code.

2.3.1. Conventions de dénomination des bibliothèques

Une convention spéciale sur les noms de fichiers est utilisée pour les bibliothèques : une bibliothèque connue sous le nom de foo est censée exister sous la forme d'un fichier libfoo.so ou libfoo.a. Cette convention est automatiquement comprise par les options d'entrée de GCC, mais pas par les options de sortie :

  • Lors de l'établissement d'un lien avec la bibliothèque, celle-ci ne peut être spécifiée que par son nom foo avec l'option -l, comme suit -lfoo:

    $ gcc ... -lfoo...
  • Lors de la création de la bibliothèque, le nom complet du fichier libfoo.so ou libfoo.a doit être spécifié.

2.3.2. Liaison statique et dynamique

Les développeurs ont le choix d'utiliser la liaison statique ou dynamique lorsqu'ils construisent des applications avec des langages entièrement compilés. Il est important de comprendre les différences entre l'enchaînement statique et l'enchaînement dynamique, en particulier dans le contexte de l'utilisation des langages C et C sur Red Hat Enterprise Linux. En résumé, Red Hat déconseille l'utilisation de l'édition statique de liens dans les applications pour Red Hat Enterprise Linux.

Comparaison de la liaison statique et de la liaison dynamique

L'enchaînement statique intègre les bibliothèques dans le fichier exécutable résultant. L'enchaînement dynamique conserve ces bibliothèques dans des fichiers distincts.

La liaison dynamique et la liaison statique peuvent être comparées de plusieurs façons :

Utilisation des ressources

L'établissement de liens statiques donne lieu à des fichiers exécutables plus volumineux qui contiennent plus de code. Ce code supplémentaire provenant des bibliothèques ne peut pas être partagé entre plusieurs programmes sur le système, ce qui augmente l'utilisation du système de fichiers et de la mémoire au moment de l'exécution. Plusieurs processus exécutant le même programme lié statiquement partageront toujours le code.

D'autre part, les applications statiques nécessitent moins de relocalisations pendant l'exécution, ce qui réduit le temps de démarrage, et requièrent moins de mémoire privée de taille d'ensemble résident (RSS). Le code généré pour l'enchaînement statique peut être plus efficace que pour l'enchaînement dynamique en raison de la surcharge introduite par le code indépendant de la position (PIC).

Sécurité
Les bibliothèques liées dynamiquement qui assurent la compatibilité ABI peuvent être mises à jour sans modifier les fichiers exécutables qui dépendent de ces bibliothèques. Ceci est particulièrement important pour les bibliothèques fournies par Red Hat dans le cadre de Red Hat Enterprise Linux, où Red Hat fournit des mises à jour de sécurité. L'établissement de liens statiques avec de telles bibliothèques est fortement déconseillé.
Compatibilité

La liaison statique semble fournir des fichiers exécutables indépendants des versions des bibliothèques fournies par le système d'exploitation. Cependant, la plupart des bibliothèques dépendent d'autres bibliothèques. Avec l'édition de liens statiques, cette dépendance devient inflexible et, par conséquent, la compatibilité ascendante et descendante est perdue. L'enchaînement statique est garanti pour fonctionner uniquement sur le système où le fichier exécutable a été construit.

Avertissement

Les applications liant statiquement les bibliothèques de la bibliothèque GNU C (glibc) nécessitent toujours que glibc soit présent sur le système en tant que bibliothèque dynamique. En outre, la variante de la bibliothèque dynamique glibc disponible au moment de l'exécution de l'application doit être une version bitwise identique à celle présente lors de l'édition de liens de l'application. Par conséquent, l'établissement de liens statiques n'est garanti que sur le système où le fichier exécutable a été créé.

Couverture de soutien
La plupart des bibliothèques statiques fournies par Red Hat se trouvent dans le canal CodeReady Linux Builder et ne sont pas prises en charge par Red Hat.
Fonctionnalité

Certaines bibliothèques, notamment la bibliothèque GNU C (glibc), offrent des fonctionnalités réduites lorsqu'elles sont liées de manière statique.

Par exemple, lorsqu'il est lié statiquement, le site glibc ne prend pas en charge les threads et toute forme d'appel à la fonction dlopen() dans le même programme.

En raison de ces inconvénients, l'établissement de liens statiques doit être évité à tout prix, en particulier pour les applications entières et les bibliothèques glibc et libstdc .

Cas de la liaison statique

La création de liens statiques peut être un choix raisonnable dans certains cas, par exemple :

  • Utilisation d'une bibliothèque qui n'est pas activée pour la liaison dynamique.
  • Une liaison entièrement statique peut être nécessaire pour exécuter un code dans un environnement ou un conteneur chroot vide. Cependant, l'établissement de liens statiques à l'aide du paquetage glibc-static n'est pas pris en charge par Red Hat.

2.3.4. Utilisation d'une bibliothèque avec GCC

Une bibliothèque est un ensemble de codes qui peuvent être réutilisés dans votre programme. Une bibliothèque C ou C se compose de deux parties :

  • Le code de la bibliothèque
  • Fichiers d'en-tête

Compiler un code qui utilise une bibliothèque

Les fichiers d'en-tête décrivent l'interface de la bibliothèque : les fonctions et les variables disponibles dans la bibliothèque. Les informations contenues dans les fichiers d'en-tête sont nécessaires à la compilation du code.

Généralement, les fichiers d'en-tête d'une bibliothèque sont placés dans un répertoire différent de celui du code de votre application. Pour indiquer à GCC où se trouvent les fichiers d'en-tête, utilisez l'option -I:

$ gcc ... -Iinclude_path...

Remplacez include_path par le chemin d'accès au répertoire du fichier d'en-tête.

L'option -I peut être utilisée plusieurs fois pour ajouter plusieurs répertoires contenant des fichiers d'en-tête. Lors de la recherche d'un fichier d'en-tête, ces répertoires sont parcourus dans l'ordre de leur apparition dans les options -I.

Lier un code qui utilise une bibliothèque

Lors de la liaison du fichier exécutable, le code objet de votre application et le code binaire de la bibliothèque doivent être disponibles. Le code des bibliothèques statiques et dynamiques se présente sous différentes formes :

  • Les bibliothèques statiques sont disponibles sous forme de fichiers d'archive. Elles contiennent un groupe de fichiers objets. Le fichier d'archive a une extension de nom de fichier .a.
  • Les bibliothèques dynamiques sont disponibles sous forme d'objets partagés. Elles constituent une forme de fichier exécutable. Un objet partagé a une extension de nom de fichier .so.

Pour indiquer à GCC où se trouvent les archives ou les fichiers d'objets partagés d'une bibliothèque, utilisez l'option -L:

$ gcc ... -Llibrary_path -lfoo...

Remplacez library_path par le chemin d'accès au répertoire de la bibliothèque.

L'option -L peut être utilisée plusieurs fois pour ajouter plusieurs répertoires. Lors de la recherche d'une bibliothèque, ces répertoires sont parcourus dans l'ordre des options -L.

L'ordre des options est important : GCC ne peut pas établir un lien avec une bibliothèque foo s'il ne connaît pas le répertoire contenant cette bibliothèque. Par conséquent, utilisez les options -L pour spécifier les répertoires de bibliothèques avant d'utiliser les options -l pour l'édition de liens avec les bibliothèques.

Compiler et lier le code qui utilise une bibliothèque en une seule étape

Lorsque la situation permet de compiler et de lier le code en une seule commande gcc, utilisez les options pour les deux situations mentionnées ci-dessus en une seule fois.

Ressources supplémentaires

2.3.5. Utilisation d'une bibliothèque statique avec GCC

Les bibliothèques statiques sont disponibles sous forme d'archives contenant des fichiers objets. Après l'établissement d'un lien, elles font partie du fichier exécutable résultant.

Note

Red Hat déconseille l'utilisation de liens statiques pour des raisons de sécurité. Voir Section 2.3.2, « Liaison statique et dynamique ». N'utilisez l'édition de liens statiques qu'en cas de nécessité, en particulier pour les bibliothèques fournies par Red Hat.

Conditions préalables

  • GCC doit être installé sur votre système.
  • Vous devez comprendre ce que sont les liens statiques et dynamiques.
  • Vous disposez d'un ensemble de fichiers source ou objet formant un programme valide, nécessitant une bibliothèque statique foo et aucune autre bibliothèque.
  • La bibliothèque foo est disponible sous la forme d'un fichier libfoo.a, et aucun fichier libfoo.so n'est fourni pour la liaison dynamique.
Note

La plupart des bibliothèques qui font partie de Red Hat Enterprise Linux ne sont prises en charge que pour l'édition de liens dynamiques. Les étapes ci-dessous ne fonctionnent que pour les bibliothèques qui sont not activées pour l'édition de liens dynamiques.

Procédure

Pour lier un programme à partir des fichiers source et objet, ajouter une bibliothèque statiquement liée foo, qui se trouve dans le fichier libfoo.a:

  1. Allez dans le répertoire contenant votre code.
  2. Compiler les fichiers sources du programme avec les en-têtes de la bibliothèque foo:

    $ gcc ... -Iheader_path -c ...

    Remplacez header_path par un chemin vers un répertoire contenant les fichiers d'en-tête de la bibliothèque foo.

  3. Lier le programme à la bibliothèque foo:

    $ gcc ... -Llibrary_path -lfoo...

    Remplacez library_path par un chemin d'accès à un répertoire contenant le fichier libfoo.a.

  4. Pour exécuter le programme ultérieurement, il suffit de

    $ ./program
Avertissement

L'option -static de GCC relative à l'édition statique de liens interdit toute édition dynamique de liens. Utilisez plutôt les options -Wl,-Bstatic et -Wl,-Bdynamic pour contrôler plus précisément le comportement de l'éditeur de liens. Voir Section 2.3.7, « Utiliser des bibliothèques statiques et dynamiques avec GCC ».

2.3.6. Utilisation d'une bibliothèque dynamique avec GCC

Les bibliothèques dynamiques sont disponibles sous forme de fichiers exécutables autonomes, nécessaires à la fois au moment de l'établissement des liens et au moment de l'exécution. Elles restent indépendantes du fichier exécutable de votre application.

Conditions préalables

  • GCC doit être installé sur le système.
  • Ensemble de fichiers source ou objet formant un programme valide, nécessitant une bibliothèque dynamique foo et aucune autre bibliothèque.
  • La bibliothèque foo doit être disponible sous la forme d'un fichier libfoo.so.

Lier un programme à une bibliothèque dynamique

Pour lier un programme à une bibliothèque dynamique foo:

$ gcc ... -Llibrary_path -lfoo...

Lorsqu'un programme est lié à une bibliothèque dynamique, le programme résultant doit toujours charger la bibliothèque au moment de l'exécution. Il existe deux options pour localiser la bibliothèque :

  • Utilisation d'une valeur rpath stockée dans le fichier exécutable lui-même
  • Utilisation de la variable LD_LIBRARY_PATH au moment de l'exécution

Utilisation d'une valeur rpath stockée dans le fichier exécutable

La valeur rpath est une valeur spéciale enregistrée dans un fichier exécutable lorsqu'il est lié. Plus tard, lorsque le programme sera chargé à partir de son fichier exécutable, l'éditeur de liens utilisera la valeur rpath pour localiser les fichiers de la bibliothèque.

Lors de l'établissement d'un lien avec GCC, le chemin library_path est enregistré sous rpath:

$ gcc ... -Llibrary_path -lfoo -Wl,-rpath=library_path...

Le chemin library_path doit pointer vers un répertoire contenant le fichier libfoo.so.

Important

N'ajoutez pas d'espace après la virgule dans l'option -Wl,-rpath=.

Pour exécuter le programme ultérieurement :

$ ./program

Utilisation de la variable d'environnement LD_LIBRARY_PATH

Si le fichier exécutable du programme ne contient pas rpath, l'éditeur de liens utilisera la variable d'environnement LD_LIBRARY_PATH. La valeur de cette variable doit être modifiée pour chaque programme. Cette valeur doit représenter le chemin où se trouvent les objets de la bibliothèque partagée.

Pour exécuter le programme sans rpath, avec les bibliothèques présentes dans le chemin library_path:

$ export LD_LIBRARY_PATH=library_path:$LD_LIBRARY_PATH
$ ./program

L'omission de la valeur rpath offre une certaine souplesse, mais nécessite la définition de la variable LD_LIBRARY_PATH à chaque fois que le programme doit être exécuté.

Placer la bibliothèque dans les répertoires par défaut

La configuration de l'éditeur de liens d'exécution spécifie un certain nombre de répertoires comme emplacement par défaut des fichiers de bibliothèque dynamique. Pour utiliser ce comportement par défaut, copiez votre bibliothèque dans le répertoire approprié.

Une description complète du comportement de l'éditeur de liens dynamiques n'entre pas dans le cadre de ce document. Pour plus d'informations, voir les ressources suivantes :

  • Pages de manuel Linux pour l'éditeur de liens dynamiques :

    $ man ld.so
  • Contenu du fichier de configuration /etc/ld.so.conf:

    $ cat /etc/ld.so.conf
  • Rapport des bibliothèques reconnues par l'éditeur de liens dynamiques sans configuration supplémentaire, qui inclut les répertoires :

    $ ldconfig -v

2.3.7. Utiliser des bibliothèques statiques et dynamiques avec GCC

Il est parfois nécessaire de lier certaines bibliothèques de manière statique et d'autres de manière dynamique. Cette situation pose quelques problèmes.

Conditions préalables

  • Comprendre les liens statiques et dynamiques

Introduction

gcc reconnaît les bibliothèques dynamiques et statiques. Lorsque l'option -lfoo est rencontrée, gcc tentera d'abord de localiser un objet partagé (un fichier .so ) contenant une version liée dynamiquement de la bibliothèque foo, puis cherchera le fichier d'archive (.a) contenant une version statique de la bibliothèque. Ainsi, les situations suivantes peuvent résulter de cette recherche :

  • Seul l'objet partagé est trouvé et gcc s'y réfère de manière dynamique.
  • Seule l'archive est trouvée, et gcc s'y réfère de manière statique.
  • L'objet partagé et l'archive sont tous deux trouvés et, par défaut, gcc sélectionne la liaison dynamique avec l'objet partagé.
  • Aucun objet partagé ni archive n'est trouvé et la liaison échoue.

En raison de ces règles, la meilleure façon de sélectionner la version statique ou dynamique d'une bibliothèque pour l'édition de liens est de n'avoir que la version trouvée par gcc. Ceci peut être contrôlé dans une certaine mesure en utilisant ou en supprimant les répertoires contenant les versions des bibliothèques, lors de la spécification des options -Lpath options.

En outre, comme l'enchaînement dynamique est la valeur par défaut, la seule situation où l'enchaînement doit être explicitement spécifié est celle où une bibliothèque dont les deux versions sont présentes doit être liée de manière statique. Il existe deux solutions possibles :

  • Spécification des bibliothèques statiques par chemin d'accès au lieu de l'option -l
  • Utilisation de l'option -Wl pour passer des options à l'éditeur de liens

Spécifier les bibliothèques statiques par fichier

Habituellement, gcc est chargé d'établir un lien avec la bibliothèque foo à l'aide de l'option -lfoo . Cependant, il est possible de spécifier le chemin complet du fichier libfoo.a contenant la bibliothèque :

$ gcc ... path/to/libfoo.a ...

D'après l'extension du fichier .a, gcc comprendra qu'il s'agit d'une bibliothèque à lier au programme. Cependant, spécifier le chemin complet du fichier de la bibliothèque est une méthode moins souple.

Utilisation de l'option -Wl

L'option gcc -Wl est une option spéciale permettant de passer des options à l'éditeur de liens sous-jacent. La syntaxe de cette option diffère de celle des autres options gcc. L'option -Wl est suivie d'une liste d'options de l'éditeur de liens séparée par des virgules, alors que les autres options gcc nécessitent une liste d'options séparées par des espaces.

L'éditeur de liens ld utilisé par gcc propose les options -Bstatic et -Bdynamic pour spécifier si les bibliothèques suivant cette option doivent être liées statiquement ou dynamiquement, respectivement. Après avoir transmis -Bstatic et une bibliothèque à l'éditeur de liens, le comportement de liaison dynamique par défaut doit être rétabli manuellement pour que les bibliothèques suivantes soient liées dynamiquement avec l'option -Bdynamic.

Pour lier un programme, liez la bibliothèque first de manière statique (libfirst.a) et second de manière dynamique (libsecond.so) :

$ gcc ... -Wl,-Bstatic -lfirst -Wl,-Bdynamic -lsecond...
Note

gcc peut être configuré pour utiliser d'autres linkers que celui par défaut ld.

Ressources supplémentaires

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.