Créer une bibliothèque C ++ avec CMake

J’essaie de créer une structure de bibliothèque raisonnable et un fichier CMake qui permettrait à d’autres projets CMake d’inclure facilement cette bibliothèque. J’ai trouvé beaucoup de questions similaires, cependant, aucune d’entre elles ne semble adresser mon problème exact .
Ma structure actuelle est la suivante:

/*MyLibrary/ ├── CMakeLists.txt (including lib subdirectories) ├── external/ │ └── googletest/ ├── lib/ │ ├── common/ │ │ ├── CMakeList.txt (creates static lib common) │ │ ├── include/common/*.h │ │ └── src/*.cpp │ ├── cipher/ │ │ ├── CMakeList.txt (creates static lib cipher) │ │ ├── include/cipher/*.h │ │ └── src/*.cpp └── test/ ├── main.cpp (code for executing google test) ├── CMakeLists.txt (creates unittest executable) ├── common/*Test.cpp └── cipher/*Test.cpp */ 

Maintenant, je veux créer un projet avec une structure de répertoires similaire, mais le problème survient lorsque je veux créer une bibliothèque statique dans ce projet avec le même nom que l’une des bibliothèques statiques de MyLibrary ( common par exemple).
Je pensais inclure la bibliothèque dans le projet en utilisant add_subdirectory(external/MyLibrary) dans les projets CMakeLists, mais cela échouait car les noms des bibliothèques statiques se collaient.
Même lorsque je résous ce problème en renommant la bibliothèque (ce qui, à mon avis, n’est pas une solution élégante), je me retrouve avec des conflits de googletest parce que la bibliothèque et mon projet dépendent tous deux de googletest.

Y a-t-il un moyen de résoudre cela facilement? Je pensais à 2 possibilités:

  • Dans MyLibrary je MyLibrary une bibliothèque statique à partir de toutes les sous-bibliothèques nommées libMyLibrary.a et n’inclurais que cette bibliothèque (option preffered, mais je ne sais pas comment l’obtenir dans CMake).
  • Forcer les utilisateurs de la bibliothèque à l’installer et à ne pas inclure la bibliothèque en tant que sous-module de projet (la dernière option que je choisirais)

Existe-t-il un autre moyen raisonnable de le résoudre qui rendrait ma bibliothèque compatible avec la plupart des projets CMake? Sinon, comment puis-je obtenir au moins une des options mentionnées?

En bref:
Comment créer un fichier CMake pour une bibliothèque afin que celle-ci soit facile à inclure dans d’autres projets CMake?
Comment puis-je gérer les dépendances redondantes telles que googletest?

Comment créer un fichier CMake pour une bibliothèque afin que celle-ci soit facile à inclure dans d’autres projets CMake?

Il n’ya pas d’approche universelle à cette fin.

En incluant votre projet dans un autre projet avec add_subdirectory() , vous “ouvrez” les éléments internes de votre projet à un autre. Outre l’avantage d’avoir la cible de la bibliothèque prête à être reliée, cette approche présente également des inconvénients. Les collisions de la cible, les collisions de variables en cache seront votre mal de tête, parmi d’autres problèmes.

Si vous souhaitez que votre projet soit inclus dans d’autres avec add_subdirectory , évitez d’utiliser des noms “génériques” pour vos cibles. Par exemple, utilisez _common au lieu de common .

Certaines cibles que vous ne pouvez pas renommer (comme gtest ). Si ces cibles ne sont pas vraiment nécessaires au fonctionnement de votre projet, créez une option pour les désactiver:

 option(_TESTING "Enable testing" ON) if(_TESTING) add_subdirectory(external/googletest) endif() 

Voir aussi ma réponse à la question similaire sur la collision de noms de cibles.