Il y a environ un an, j'ai posé des questions sur les dépendances d'en-tête dans CMake .
J'ai réalisé récemment que le problème semblait être que CMake considérait ces fichiers d'en-tête comme externes au projet. Au moins, lors de la génération d'un projet Code :: Blocks, les fichiers d'en-tête n'apparaissent pas dans le projet (les fichiers source le font). Il me semble donc que CMake considère ces en-têtes comme externes au projet et ne les suit pas dans les dépendances.
Une recherche rapide dans le tutoriel CMake ne fait que pointer vers include_directories
ce qui ne semble pas faire ce que je souhaite ...
Quelle est la bonne façon de signaler à CMake qu'un répertoire particulier contient des en-têtes à inclure et que ces en-têtes doivent être suivis par le Makefile généré?
.cbp
dossier de projet. Maintenant, si le scanner de dépendances cmake ne parvient pas à identifier correctement un fichier d'en-tête en tant que dépendance d'un Makefile, il existe des moyens de résoudre ce problème, mais dans certains cas, il se trompe car il n'inclut pas un préprocesseur complet.Réponses:
Il faut faire deux choses.
Ajoutez d'abord le répertoire à inclure:
Dans le cas où vous êtes bloqué avec une très ancienne version de CMake (2.8.10 ou plus ancienne) sans prise en charge de
target_include_directories
, vous pouvez également utiliser l'héritage à lainclude_directories
place:Ensuite, vous devez également ajouter les fichiers d'en-tête à la liste de vos fichiers source pour la cible actuelle, par exemple:
De cette façon, les fichiers d'en-tête apparaîtront comme des dépendances dans le Makefile, et aussi par exemple dans le projet Visual Studio généré, si vous en générez un.
Comment utiliser ces fichiers d'en-tête pour plusieurs cibles:
la source
LIBROOT_HEADER_FILES
variableliba/CMakefile
etlibb/CMakefile
alors?include_directories
plustarget_include_directories
. Le premier le définit récursivement pour toutes les cibles de ce répertoire; alors que ce dernier le fixe comme objectif. Faire le premier casse la notion de graphique cible dans CMake et s'appuie à la place sur les effets secondaires de votre hiérarchie de fichiers.target_include_directories
pour le code CMake moderne. N'hésitez pas à m'inviter à un chat si vous n'êtes pas d'accord avec les changements.Tout d'abord, vous utilisez
include_directories()
pour dire à CMake d'ajouter le répertoire-I
à la ligne de commande de compilation. Deuxièmement, vous répertoriez les en-têtes dans votreadd_executable()
ouadd_library()
appelez.Par exemple, si les sources de votre projet sont dedans
src
et que vous avez besoin d'en-têtesinclude
, vous pouvez le faire comme ceci:la source
add_executable
? Je pensais que CMake avait compris automatiquement les dépendances des fichiers inclus.CMake ressemble plus à un langage de script si on le compare avec d'autres façons de créer un Makefile (par exemple make ou qmake). Ce n'est pas très cool comme Python, mais quand même.
Il n'y a rien de tel qu'une " bonne façon " si l'on regarde dans divers projets open source comment les gens incluent les répertoires. Mais il y a deux façons de procéder.
Les include_directories bruts ajouteront un répertoire au projet actuel et à tous les autres projets descendants que vous ajouterez via une série de commandes add_subdirectory . Parfois, les gens disent qu'une telle approche est un héritage.
Une manière plus élégante est avec target_include_directories . Il permet d'ajouter un répertoire pour un projet / cible spécifique sans (peut-être) héritage inutile ni conflit de divers répertoires d'inclusion. Permet également d'effectuer une configuration même subtile et d'ajouter l'un des marqueurs suivants pour cette commande.
PRIVÉ - à utiliser uniquement pour cette cible de génération spécifiée
PUBLIC - utilisez-le pour la cible spécifiée et pour les cibles liées à ce projet
INTERFACE - utilisez-le uniquement pour les cibles liées au projet en cours
PS:
Les deux commandes permettent de marquer un répertoire en tant que SYSTEM pour donner un indice que ce n'est pas votre entreprise que les répertoires spécifiés contiendront des avertissements.
Une réponse similaire est avec d'autres paires de commandes target_compile_definitions / add_definitions , target_compile_options / CMAKE_C_FLAGS
la source
Ajouter
include_directories("/your/path/here")
.Cela sera similaire à l'appel
gcc
avec-I/your/path/here/
option.Assurez-vous de mettre des guillemets doubles autour du chemin. D'autres personnes n'ont pas mentionné cela et cela m'a fait coincé pendant 2 jours. Cette réponse s'adresse donc aux personnes qui sont très nouvelles à CMake et très confuses.
la source
J'ai eu le même problème.
Mon répertoire de projet était comme ceci:
Et ce que j'avais l'habitude d'inclure les fichiers dans tous ces dossiers:
Et cela a totalement fonctionné.
la source