Comment créer un cmake en-tête de la seule bibliothèque qui dépend de fichiers d'en-tête?
J'ai un projet avec la structure suivante:
project
|
|-------> lib1
| |----> lib1.h
|
|-------> lib2
| |----> lib2.h
|
|-------> main.cc
Les deux libs lib1
et lib2
contiennent uniquement les fichiers d'en-tête, tandis que lib2.h
comprend lib1.h
, et main.cc
comprend lib2.h
.
Comment puis-je écrire le fichier cmake pour ce projet maintenant? J'ai essayé de créer un l'interface de la bibliothèque pour lib2
, mais le compilateur ne peut pas trouver lib1.h
. Voici le contenu de mes fichiers cmake:
CMakeLists.txt pour lib2:
add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE lib2.h)
target_include_directories(lib2 INTERFACE ../lib1/lib1.h)
CMakeLists.txt pour l'ensemble du projet:
add_executable(project main.cc)
target_link_libraries(project lib2)
Quel est le problème dans les fichiers cmake?
- Ne pouvez-vous pas juste la liste de vos en-têtes dans
add_executable
et de supprimer tous lesadd_library
? - Une chose qui me semble bizarre dans votre code source et pourrait expliquer le problème:
target_include_directories()
est uniquement pour les répertoires qui contiennent des fichiers d'en-tête. Il devrait donc êtretarget_include_directories(lib2 INTERFACE ../lib1)
. - Merci à tous pour les commentaires!
Vous devez vous connecter pour publier un commentaire.
Comme indiqué dans les commentaires,
target_include_directories
devrait être donnée à un chemin d'accès à un répertoire, pas dans un fichier.En outre, si vous souhaitez créer une dépendance pour
lib2
surlib1
, vous devez le faire par le biais detarget_link_libraries
: une dépendance n'est pas seulement inclure des répertoires, mais aussi sur les options de compilation, des définitions, des propriétés ciblées...target_sources
ne fonctionne pas avec les bibliothèques d'interface. De cette réponse, Vous pouvez utiliser une cible personnalisée sans commandes d'associer les sources à une cible sans impact sur le processus de construction (pour msvc, QtCreator et d'autres outils basés sur l'interface, ce qui rend les sources accessibles par le biais de l'IDE; autant que je sache, c'est inutile pour les autres outils de construction).Votre cmake peut ressembler à ceci:
Avancé astuce: vous pouvez spécifier un autre répertoire dans
target_include_directories
pour l'arbre de construction et de l'arborescence de l'installation (voir la documentation):target_sources
ne devrait pas être nécessaire puisque la cible est de type "INTERFACE", et n'est pas compilé par lui-même. En passant sources directement àadd_library
même donne l'erreur suivante:add_library INTERFACE library requires no source arguments.
target_sources
est également nécessaire pour les sources pour être visible dans les Projets volet de QtCreator IDE facilement.target_link_libraries(lib2 lib1)
, j'obtiens cette erreurINTERFACE library can only be used with the INTERFACE keyword of target_link_libraries
je suppose que cela signifielib2
par l'interface de la bibliothèque ici. Je peux sortir de cette erreur si j'ajoute le mot-clé INTERFACE dans le target_link_libraries commande avantlib1
.target_link_libraries(lib2 INTERFACE lib1)
J'ai utilisé un vide
_only_for_compiling_the_lib.cpp
fichier comme la plus simple et la plus rapide solution de contournement, mais clairement la solution ci-dessus est fortement conseillé.Je n'était tout simplement pas au courant de
INTERFACE
mot-clé.Ce problème était dû à plein de problème de chemin d'accès de l'INTERFACE des fichiers de la bibliothèque, qui se fixe dans cmake version 3.13.
Pour plus d'info:
https://gitlab.kitware.com/cmake/cmake/issues/17556
Cette page contient également un exemple pour mieux comprendre.