Je commencerai par répondre à la seconde question car l'essentiel du problème est ici.
Envoyé par
Anthares
Ensuite, pourquoi, lorsque j'essaie de fournir les fichiers lib1.so, lib2.so et Manager, ceux-ci ne fonctionnent pas sur un autre poste?
C'est une erreur assez classique, probablement héritée du monde Windows. La génération d'un produit se fait généralement en trois étapes : configuration, compilation puis installation. La dernière étape est souvent omise dans le monde Windows, du moins Visual. Il ne faut pas confondre placer les produits de compilation dans un répertoire (via les variables LIBRARY_OUTPUT_PATH et EXECUTABLE_OUTPUT_PATH) et les installer.
Ton erreur est due au fait que les librairies sont gérées de manière légèrement différentes suivant qu'elles sont utilisées dans l'environnement de développement (ton répertoire de compilation) et l'environnement d'utilisation (l'autre poste). Dans l'environnement de développement, pour éviter des erreurs de librairies non trouvées, CMake utilise le RPATH pour lier en dur les librairies entre elles. C'est particulièrement pratique pour exécuter des tests automatiquement. Par contre, dans l'environnement d'utilisation, qui ne ressemble pas du tout à l'environnement de développement, il faut enlever les références en dur, ce que CMake fait à l'installation, et les remplacer par une configuration système ou utilisateur (ce que l'on fait avec LD_LIBRARY_PATH, PATH ou des mécanismes systèmes plus compliqués).
Malheureusement, dans le monde Windows, il n'existe aucun mécanisme pour référencer en dur le chemin vers une librairie. Le seul moyen de pouvoir exécuter des tests automatiquement est donc de tout mettre au même endroit, d'où la raison principale de l'existence des variables EXECUTABLE_OUTPUT_PATH et LIBRARY_OUTPUT_PATH.
Par conséquent, si tu veux pouvoir utiliser tes librairies sur un autre poste, il faut que tu les installes. Ceci se fait avec la commande
install(TARGETS ... DESTINATION...)
Ensuite, après avoir configuré l'endroit où installer ses produits
cmake -D CMAKE_INSTALL_PREFIX=<InstallDir> .
puis compilé
, il faut installer les produits
Tu trouveras alors dans <InstallDir> tes librairies parfaitement utilisables sur tout autre poste.
Il est aussi possible de packager ses binaires en incluant CPack et en faisant make package. On peut ainsi construire une archive auto-extractible. Attention, faire un package nécessite toujours de spécifier les règles d'installation.
Envoyé par
Anthares
Ma première question est la suivante: est ce que mes CMakeList sont juste?
Quelques commentaires pour le reste:
- A part compliqué inutilement le projet, je ne vois aucun intérêt à faire un projet par target. Le mieux est de faire un projet à la racine (avec le cmake_minimum_required), y fixer les variables globales (elles sont héritées par les CMakeLists en-dessous) puis ajouter les différents sous-répertoires. Inutile donc de répéter les set BUILD_SHARED_LIBS BUILD_PATH LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH
- Sauf exception, on ne liste pas les .h dans les sources. La seule raison de les lister est de pouvoir les voir directement dans certains IDE.
- Sauf exception, on laisse le préfixe par défaut. CMake positionne un préfixe en cohérence avec la plateforme de développement (lib sous Linux, rien sous Windows). Dans ton cas, il suffirait de faire add_library(1 ...) sans changer le préfixe. Au passage, "1" ne me paraît pas être un super nom pour une librairie. Tu me diras, oui, mais il y a lib devant sauf que si je veux compiler avec à la main, je suis obligé de faire gcc ... -l1 ... Pas super clair...
- Je ne vois pas l'intérêt de faire link_directories.
- Inutile de linker Manager contre lib1 puisque lib2 linke contre lib1 (sauf si tu utilises directement lib1 dans Manager, et encore ceci ne serait pas nécessaire si tu travaillais en statique). De même, si lib1 ou lib2 utilise pthread, il faut le dire aussitôt. CMake assure la transitivité des librairies, ce qui change un peu des Makefiles faits à la main où on linke généralement tout ensemble au dernier moment. Il ne faut pas hésiter à utiliser la transitivité et à ne lister que les librairies que tu utilises réellement pour la target en cours de construction.
Partager