En informatique, une bibliothèque logicielle est une collection de routines, qui peuvent être déjà compilées et prêtes à être utilisées par des programmes[1],[2]. Les bibliothèques sont enregistrées dans des fichiers semblables, voire identiques aux fichiers de programmes[3], sous la forme d'une collection de fichiers de code objet rassemblés[2] accompagnée d'un index permettant de retrouver facilement chaque routine[3]. Le mot « librairie » est souvent utilisé à tort pour désigner une bibliothèque logicielle. Il s'agit d'un anglicisme fautif dû au faux-ami library.
Les bibliothèques sont apparues dans les années 1950, et sont devenues un sujet incontournable de programmation. Elles sont utilisées pour réaliser des interfaces de programmation, des framework, des plugins ainsi que des langages de programmation. Les routines contenues dans les bibliothèques sont typiquement en rapport avec des opérations fréquentes en programmation : manipulation des interfaces utilisateur, manipulation des bases de données ou calculs mathématiques[2].
Les bibliothèques sont manipulées par l'éditeur de lien et le système d'exploitation. Les manipulations sont différentes suivant que la bibliothèque est statique ou partagée. Les emplacements et les noms des bibliothèques varient selon les systèmes d'exploitation.
Utilisation
En informatique, une routine est un ensemble d'instructions qui prend en charge une certaine opération et produit un résultat[4]. Les bibliothèques sont apparues dans les années 1950, sous la forme d'un magasin contenant des lots de cartes perforées ou des rouleaux de bande magnétique sur lesquels étaient enregistrées des routines[3]. Les programmeurs pouvaient choisir les bandes magnétiques à utiliser dans leurs programmes[3].
Les bibliothèques sont utilisées pour mettre en œuvre des interfaces de programmation[5] ainsi que des frameworks et des plugins et peuvent être incorporées dans les langages de programmation.
Une interface de programmation (abr. API pour Application Programming Interface) est un ensemble documenté et standardisé de routines par lesquelles un logiciel offre des services à d'autres logiciels. Les routines sont mises à disposition, compilées et emballées sous la forme d'une bibliothèque logicielle. La documentation spécifie comment le logiciel consommateur peut interagir avec le logiciel fournisseur en utilisant les routines[5]. Les interfaces de programmation sont un sujet incontournable de la programmation contemporaine et un logiciel se sert typiquement de nombreuses interfaces de programmation[5].
Les frameworks sont des collections de classes (lots de routines) semi-finies qui, utilisées ensemble, forment le squelette d'un programme. Ils permettent la construction d'un programme par assemblage et dérivation de composants[6]. Les frameworks se distinguent des interfaces de programmation par le fait que les interfaces de programmation comportent des routines qu'un programme va utiliser, tandis que les framework sont des bibliothèques qui utiliseront les routines du programme[7].
Les plugins sont des bibliothèques logicielles qu'une application recherche en vue d'étendre ses fonctionnalités. Cette technique est utilisée par exemple par les navigateurs web pour prendre en charge l'affichage d'animations ou de vidéos[5].
Programmer et exploiter des bibliothèques fait partie des utilisations ordinaires des langages de programmation généralistes. Si dans les premiers langages de programmation les fonctionnalités étaient délimitées par le lexique du langage, les langages de programmation récents ont un lexique très réduit et beaucoup de fonctionnalités sont apportées par des bibliothèques standard qui accompagnent le langage de programmation[8]. Par exemple la bibliothèque standard du C contient une collection normalisée de routines permettant de manipuler des fichiers, d'écrire des textes, d'utiliser la mémoire, ou de faire des calculs[5].
La technique
Les bibliothèques sont manipulées de manière différente par l'éditeur de liens et le système d'exploitation selon qu'elles soient statiques ou partagées. La manipulation se sert de la table de symboles créée par le compilateur.
- bibliothèque statique
- Une bibliothèque est dite statique si elle est destinée à être copiée dans les programmes qui l'utilisent lors de la construction de ces derniers[1].
- bibliothèque partagée
- Une bibliothèque est dite partagée si elle est destinée à être associée aux programmes au moment où ils sont exécutés. Avec une telle bibliothèque, la même copie de la bibliothèque peut être utilisée par plusieurs programmes[1].
- éditeur de liens
- L'éditeur de liens est le programme qui combine différents fichiers de code objet, parmi lesquels des bibliothèques, pour en faire un programme exécutable[9].
- table de symboles
- Une table de symboles est une structure manipulée par les compilateurs et les éditeurs de liens, qui contient les noms d'éléments du programme (routines, variables, constantes), ainsi que leur adresses, c'est-à-dire leur emplacement dans le programme[9]. La table de symboles produite par le compilateur est utilisée ensuite par l'éditeur de liens pour déterminer l'emplacement des routines qui se trouvent dans les bibliothèques[9].
- routine bouchon (anglais stub)
- Une routine bouchon est une routine f'() ajoutée automatiquement à un programme qui ne fait rien d'autre que d'utiliser une routine f() d'une bibliothèque partagée[9].
Résolution de noms
Pour qu'un programme utilise une routine, il est nécessaire que la provenance de la routine soit connue. La provenance est déterminée conjointement par le compilateur, l'éditeur de liens et le système d'exploitation, dans un processus de résolution qui recherche dans les bibliothèques. Le processus diffère selon qu'il s'agit de bibliothèques statiques ou partagées.
Tout d'abord, lors de la traduction d'un fichier de code source en code objet par un compilateur, celui-ci ajoute à la table de symboles les noms des routines utilisées dans ce fichier source ainsi que leur adresse[9]. L'adresse est laissée vide si la routine n'a pas été trouvée dans le fichier de code source[9]. Puis l'éditeur de liens recherchera alors à quoi correspond chaque routine dont l'adresse est laissée vide par le compilateur[1].
Si la routine provient d'une bibliothèque dite statique, l'éditeur de liens copie l'intégralité de la bibliothèque dans le programme[1]. Le fichier de bibliothèque n'est alors plus nécessaire à l'exécution du programme[1]. La bibliothèque est ainsi copiée dans chaque programme qui l'utilise[1].
Si la routine provient d'une bibliothèque partagée alors l'éditeur de liens ne la copie pas dans le programme, au lieu de cela le système d'exploitation placera la bibliothèque en mémoire en même temps que le programme, c'est-à-dire immédiatement avant son exécution[1]. Une seule copie de la bibliothèque est enregistrée dans l'ordinateur[1]. Lorsque plusieurs programmes utilisant cette bibliothèque se trouvent en mémoire, ils utilisent tous la même copie de la bibliothèque, ce qui permet d'économiser de la place par rapport à une bibliothèque statique[1].
L'utilisation de bibliothèques partagées présente cependant certains risques. Le principal risque est qu'une bibliothèque utilisée par un programme ne peut pas être trouvée au moment où le programme en a besoin, entraînant l'échec du programme[1]. Il arrive également parfois que l'interface de programmation de la bibliothèque qui a été trouvée ne corresponde pas à celle dont le programme a besoin, entraînant un crash de ce dernier[1].
Il est parfois nécessaire de recalculer l'adresse de chaque routine après l'avoir ajoutée au programme[9] ou de créer des routines de bouchon.
Avec une bibliothèque statique, le recalcul des adresses est effectué par l'éditeur de liens immédiatement après la compilation. Tandis qu'avec une bibliothèque partagée il est effectué lors du chargement du programme en mémoire, immédiatement avant son exécution[10]. Le position independent code (abr. PIC) est un code objet produit par certains compilateurs, qui ne nécessite pas de recalcul de ces adresses par l'éditeur de liens. Ce type de code est souvent utilisé pour les bibliothèques[9].
Lors de la création d'une routine bouchon, l'éditeur de liens ajoute ensuite une entrée dans la table de symboles du programme pour informer que l'adresse de la routine référencée doit être recalculée avant l'exécution du programme[9].
En pratique
Programmer des bibliothèques fait partie des utilisations ordinaires des langages de programmation généralistes. Si dans les premiers langages de programmation les fonctionnalités étaient délimitées par le lexique du langage, les langages de programmation récents ont un lexique très réduit et beaucoup de fonctionnalités sont apportées par des bibliothèques standard qui accompagnent le langage de programmation[8].
Lorsqu'un ou plusieurs programmes utilisent une bibliothèque dynamique, une seule copie du code et des ressources de cette bibliothèque est chargée en mémoire. La même routine peut potentiellement être exécutée simultanément par plusieurs programmes et les variables globales peuvent potentiellement être modifiées simultanément[11]. Deux qualités recherchées des routines des bibliothèques sont d'être thread-safe et/ou réentrantes.
- réentrant signifie que la routine continue de donner des résultats corrects quand elle est exécutée plusieurs fois simultanément.
- thread-safe signifie que la routine continue de donner des résultats corrects quand elle est exécutée simultanément par plusieurs threads.
L'utilisation simultanée par plusieurs programmes d'une routine qui n'est pas thread-safe ni réentrante peut entrainer des pannes par situation de compétition (anglais race condition)[12].
Les noms des fichiers de bibliothèque partagées se terminent par .so sur Unix, .dylib sur Mac OS X et .dll sur Windows[5], et les emplacements conventionnels des bibliothèques diffèrent selon la plateforme.
Sur les systèmes d'exploitation Unix les bibliothèques sont en principe enregistrées dans les répertoires /lib ou /usr/lib. Une variable d'environnement LD_LIBRARY_PATH permet d'indiquer d'autres répertoires à prendre en compte par l'éditeur de liens. Le nom de chaque bibliothèque comporte les lettres lib et se termine par .a (bibliothèque statique) ou .so (bibliothèque partagée)[2]. Les bibliothèques statiques utilisent le format des fichiers d'archive[3]. Ce format, théoriquement destiné à stocker une collection de fichiers quelconques, est utilisé exclusivement pour les fichiers de bibliothèque[3].
Sur les systèmes d'exploitation Windows, les bibliothèques statiques ont un format semblable au format d'archive des systèmes Unix, mais avec un index de construction différente[3]. Les noms des bibliothèques statiques se terminent par .lib tandis que les noms des bibliothèques dynamiques se terminent par .dll. Une bibliothèque statique peut également être une collection de bouchons relatifs à une bibliothèques dynamique. Les noms des bibliothèques dynamiques peuvent également se terminer par .ocx, .drv ou .cpl[5]. Les emplacements standard des bibliothèques sont les répertoires \Windows, ou \Windows\System, ainsi que le répertoire où se trouve l'application qui utilise la bibliothèque. Une variable d'environnement permet d'indiquer au système d'exploitation d'autres répertoires éventuels[13].
Sur les systèmes d'exploitation Mac OS X les bibliothèques sont distribuées sous forme de framework: un répertoire dans lequel se trouve la/les bibliothèques ainsi que la documentation et les headers (description des routines dans un langage de programmation). La plupart des bibliothèques logicielles de Mac OS X (Cocoa, Carbon…) sont distribuées sous cette forme[5]. Les bibliothèques sous forme de framework sont enregistrées dans le répertoire /System/Library/Frameworks, et les pilotes sont enregistrés dans le répertoire /System/Library/Extensions[14].
Notes et références
- (en) Brian Ward, How Linux works : what every superuser should know, San Francisco, No Starch Press, , 347 p. (ISBN 978-1-59327-088-9 et 978-1-593-27035-3, OCLC 62890298, présentation en ligne)
- (en) Neil Matthew et Richard Stones, Beginning Linux Programming, Somerset, Wiley, , 678 p. (ISBN 978-1-118-05861-9, OCLC 927494019, lire en ligne)
- (en) John R Levine, Linkers and loaders, San Francisco, Morgan Kaufmann, , 256 p. (ISBN 978-1-55860-496-4, OCLC 42413382, www.worldcat.org/title/linkers-and-loaders/oclc/42413382/viewport)
- (en) John Shapley Gray, Interprocess communications in Linux, Upper Saddle River, NJ, Prentice Hall PTR, , 600 p. (ISBN 978-0-13-046042-4, OCLC 50693452, présentation en ligne)
- (en) Martin Reddy, API design for C, Boston, Morgan Kaufmann, , 441 p. (ISBN 978-0-12-385004-1, OCLC 704559821, présentation en ligne)
- (en) Stephen D. Huston, James CE Johnson et Umar Syyid (préf. Douglas C. Schmidt), The ACE Programmer's Guide : Practical Design Patterns for Network and Systems Programming, Boston, Addison-Wesley, , 506 p. (ISBN 978-0-201-69971-5, OCLC 81301680, présentation en ligne)
- (en) Richard Harrison, Symbian OS C++ for mobile phone, vol. 3 : Application development for Symbian OS v9, Chichester, West Sussex, England, Wiley, , 834 p. (ISBN 978-0-470-06658-4, OCLC 174031161, présentation en ligne)
- (en) David A Watt et William Findlay, Programming language design concepts, Chichester, West Sussex, England Hoboken, NJ, John Wiley, , 473 p. (ISBN 978-0-470-02047-0 et 978-0-470-85320-7, OCLC 55747931, lire en ligne)
- (en) Santanu Chattopadhyay, System software, New Delhi, Prentice Hall of India, , 195 p. (ISBN 978-81-203-3051-1, OCLC 762151072, lire en ligne)
- (en) K.V. Shibu, Introduction to embedded systems, New Delhi Singapore, Tata McGraw-Hill Education, , 716 p. (ISBN 978-0-07-014589-4, OCLC 496946032, présentation en ligne)
- (en) Arndt Bode, Euro-Par 2000 parallel processing : 6th International Euro-Par Conference, Munich, Germany, August 29-September 1, 2000 : proceedings, Berlin New York, Springer, coll. « Lecture notes in computer science » (no 1900), , 1368 p. (ISBN 978-3-540-67956-1, OCLC 44969185, présentation en ligne)
- (en) Dick Buttlar, Jacqueline Farrell et Bradford Nichols, PThreads Programming., O'Reilly Media, , 286 p. (ISBN 978-1-4493-6474-8 et 1449364748, lire en ligne)
- (en) Brian Hook, Write Portable Code : An Introduction to Developing Software for Multiple Platforms, San Francisco, No Starch Press, , 1re éd., 272 p. (ISBN 978-1-59327-056-8, présentation en ligne)
- (en) Amit Singh, Mac OS X Internals : A Systems Approach, Addison-Wesley Professional, , 1680 p. (ISBN 978-0-13-270226-3, présentation en ligne)