créer une bibliothèque statique à partir du projet entier avec cmake

c ++ – project, disons, foo est maintenu par le cmake. On veut créer une bibliothèque libfoo.a (avec toutes les classes / méthodes / fonctions créées dans l’arbre source complet) pour permettre la création de programmes pouvant être liés à la bibliothèque avec -lfoo .

ok, considérons maintenant un exemple de jouet, et le prolbem sera clair. Directory foo (racine du projet) contient des répertoires a et b . Deux CmakeLists.txt sont créés:

 # a/CMakeLists.txt add_library(A ) # b/CMakeLists.txt add_library(B ) 

Et un CMakeLists.txt pour le répertoire racine:

 add_subdirectory(a) add_subdirectory(b) add_library(foo  target_link_libraries(foo AB) 

Cela a été une surprise pour moi: après la construction de libfoo.a ne contient que des méthodes de foo_sources , et a_sources , b_sources sont exclues. C’est correct dans le cas où les exécutables sont construits avec le même projet: lors de la création d’exécutables, cmake “devine” que a et b doivent être liés si elle est liée à foo . Mais dans le cas où l’exécutable est créé “en dehors” du projet pour utiliser la bibliothèque foo il faut établir un lien avec -lfoo -la -lb , maintenant, imaginez un projet avec beaucoup de sous-répertoires – comment y faire face? alors la question est “comment créer une bibliothèque, en agrégeant les méthodes du projet entier avec les moyens de cmake?”

Googling m’a amené à intégrer relativement récemment (apparu dans 2.8.8) une opportunité de OBJECT library . Un bel exemple d’utilisation est montré ici . Maintenant, le problème ci-dessus peut être résolu avec cela:

 # a/CMakeLists.txt add_library(A OBJECT ) # b/CMakeLists.txt add_library(B OBJECT ) # foo/CMakeLists.txt add_subdirectory(a) add_subdirectory(b) add_library(foo  $ $) 

problème semble être résolu, malheureusement, pas tout à fait.

Si la chaîne de dépendance est plus longue que 2, par exemple, foo dépend de A , qui dépend de B , le problème persiste. C’est parce que,

Les bibliothèques d’objects ne peuvent contenir que des sources (et des en-têtes) qui comstacknt des fichiers objects.

et

Les bibliothèques d’objects ne peuvent pas être imscopes, exscopes, installées ou liées.

(les citations sont tirées du même lien )

J’ai essayé plusieurs combinaisons de target_link_library() , add_library(), add_library(... OBJECT ..) essayant de lier A et B à foo sans succès (erreur lors du processus cmake).

Je dois perdre quelque chose de simple, aidez-moi s’il vous plaît, merci! Je ne suis pas sûr que ce soit important: le projet est maintenu à linux.

Je pense que vous vous embrouillez dans le terme “dépend de”. Si vous construisez une bibliothèque nommée foo et qu’elle a deux parties, A et B , le fait que A dépende de B importe peu. la bibliothèque doit contenir les deux. Le code CMake que vous avez montré va construire correctement.

Oui, je soutiens la réponse @Pete Becker @. Mais il faut dire aussi que ces bibliothèques ont $ et $ fait pas du tout une bibliothèque, mais plutôt une liste interne de modules d’objects. Il n’y a pas de dépendances entre la compilation des modules object (à l’exception des sources générées automatiquement) afin qu’ils puissent être réalisés dans n’importe quel ordre et en parallèle.

Je suppose que le terme plus correct pour votre intention est de rassembler plusieurs TARGET_OBJECTS sous une bibliothèque d’objects uniques. C’est vraiment dommage que vous ne puissiez pas écrire add_library(B OBJECT b.cpp $) . Mais vous pouvez toujours le mettre en œuvre par vous-même:

 add_library(A OBJECT a.cpp) set(A_OBJECTS $) add_library(B OBJECT b.cpp) set(B_OBJECTS $ ${A_OBJECTS}) add_library(foo ${B_OBJECTS}) 

Il suffit de créer des variables spéciales _OBJECTS pour les utiliser chaque fois que vous souhaitez inclure ces bibliothèques d’objects dans une bibliothèque, un fichier exécutable ou dans le cadre d’une autre bibliothèque d’objects avec cette version _OBJECTS .