Cette semaine, nous allons vous montrer comment compiler notre librairie de programmation C++ sous Linux et l'installer comme une librairie système. Cette installation est très simple grâce à cmake.
Tout d'abord, faisons un rapide rappel de C++ et des différentes phases de la vie d'un programme écrit en C++.
La compilation
La première phase consiste à compiler les fichiers sources, les fichiers .cpp et .h, pour générer des fichiers objet .o qui contiennent le code binaire que la machine est capable d'exécuter. Lors de cette phase, le compilateur a besoin du fichier .cpp, mais il a aussi besoin d'avoir accès à tous les fichiers .h qui sont référencés dans le fichier .cpp. Sous Linux, les headers sont en général stockés dans les répertoires /usr/include et /usr/local/include, mais le compilateur a une option qui permet d'ajouter d'autres répertoires à cette liste.
L'édition de liens
La deuxième phase est l'édition de liens, qui consiste à prendre tous les fichiers .o et les librairies externes pour former l'exécutable. Durant cette étape, le linker va vérifier que toutes les parties sont compatibles entre elles et que chaque fonction ou objet référencé est disponible. Et pour finir, il va générer le fichier de l'exécutable.
Le linker a deux manières d'utiliser une librairie externe. Il peut l'intégrer à l’exécutable (édition statique) ou stocker une référence sur la librairie (édition dynamique). Lors de l'édition statique, les librairies sont incluses dans l’exécutable. Le programme généré est donc plus gros, mais il contient tout le code nécessaire à son exécution.
Lors de l'édition dynamique, l'exécutable inclut seulement une référence à la librairie. L'exécutable est plus petit, mais lors de l’exécution du programme il faut que la librairie soit installée sur la machine.
Sous Linux, les bibliothèques (dynamiques ou statiques) sont en général stockées dans les répertoires /lib et /usr/lib, mais le linker a une option qui permet de rechercher les librairies dans d'autres répertoires.
L'exécution
Lors de l’exécution, le système d'exploitation vérifie que les libraires dynamiques référencées par l’exécutable sont disponibles dans les répertoires /lib ou /usr/lib. Si c'est le cas, il les ajoute dynamiquement et l’exécution du programme peut continuer, sinon l'application plante avec un message "cannot open shared object file: No such file or directory".
Pourquoi installer notre librairie globalement
L’intérêt d'installer la version statique de notre librairie est de simplifier les scriptes de build. Une fois installée globalement, tous les outils, compilateurs, linkers, etc ont accès à la librairie. Il n'est plus nécessaire de spécifier dans votre projet où les fichiers de notre librairie sont situés. C'est surtout utile avec docker et les outils de cross compilation.
L’intérêt d'installer la version dynamique de notre librairie C++ est presque nul. Théoriquement, cela permet d'économiser de la place sur le disque dur si plusieurs programmes utilisent la même librairie, car tous les programmes n'ont plus besoin d'inclure le code de la librairie. La contrepartie est que le code ne fonctionne plus que sur des machines qui ont cette librairie installée.
Comment installer la librairie statique sous Linux
Après cette longue introduction, voici comment installer la librairie Yoctopuce sur votre système Linux. La solution la plus simple est d'utiliser cmake et d’exécuter les commandes suivantes à la racine de la librairie Yoctopuce.
mkdir build_static cd build_static cmake ../Sources/ cmake --build . sudo cmake --install .
Les deux premières commandes créent un répertoire temporaire build_static qui sera utilisé par cmake. Il faut ensuite créer le projet cmake en lui passant le répertoire vers les fichiers sources de la librairie Yoctopuce, et la compiler avec la commande cmake --build. Ces commandes ne font que compiler la libraire pour l'architecture de la machine, mais la libraire n'est pas encore installée dans le bon répertoire.
La dernière commande sudo cmake --install . installe la librairie statique et les headers dans les répertoires standard de votre installation Linux. C'est du reste pour cette raison que cette commande doit être exécutée avec sudo car ces répertoires sont protégés.
Une fois la librairie statique installée, il n'y a plus besoin de spécifier le path de la librairie et des headers. Tous les outils de compilation et d'édition de liens peuvent utiliser la librairie de programmation C++ de Yoctopuce.
Comment installer la librairie dynamique sous Linux
Si vous désirez installer la librairie dynamique, il faut simplement ajouter l'option -DBUILD_SHARED_LIBS=ON lors de la génération du projet cmake.
mkdir build_dynamic cd build_dynamic cmake ../Sources/ -DBUILD_SHARED_LIBS=ON cmake --build . cmake --install .
Conclusion
Vous savez désormais comment compiler et installer facilement la librairie de programmation C++ de Yoctopuce. Si vous utilisez docker, cela vous permet de simplifier l’installation de la librairie dans vos conteneurs.
Pour les autres situations, nous continuons de recommander d'inclure les fichiers sources de notre librairie à votre projet. L'avantage de cette solution est qu'elle vous laisse le contrôle complet des options de compilation. De plus, l'exécutable final contiendra tout ce qui est nécessaire pour utiliser les modules Yoctopuce et fonctionnera sur toutes les machines.
Nous avons du reste un article qui explique comment ajouter les fichiers sources de notre librairie dans la plupart des IDE.