web-dev-qa-db-fra.com

Recherche CMake récursive pour les fichiers d'en-tête et source

Je suis nouveau à CMake et voudrais demander si quelqu'un peut aider dans le problème suivant. 

J'ai des fichiers source et en-tête C++ dans leurs dossiers respectifs et je souhaite maintenant créer un fichier texte CMake qui les recherche de manière récursive. 

Actuellement, je le fais de cette façon: 

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CarDetectorDAISY)

file(GLOB_RECURSE SRCS *.cpp)
file(GLOB_RECURSE HDRS *.h)

ADD_EXECUTABLE(stereo_framework  ${SRCS} ${HDRS})
TARGET_LINK_LIBRARIES(stereo_framework) 

Cela crée mon fichier CarDetectorDAISY.sln solution et lorsque je tente de le construire, il affiche une erreur indiquant que les fichiers d’en-tête ne sont pas trouvés (fichier ou répertoire de ce type). 

Ce serait vraiment reconnaissant si quelqu'un peut m'aider s'il vous plaît. Merci.

16
Sanchit

Il vous manque probablement un ou plusieurs include_directories . L'ajout d'en-têtes à la liste de fichiers de l'appel add_executable n'ajoute pas réellement au chemin de recherche du compilateur - c'est une fonctionnalité pratique, dans la mesure où ils sont ajoutés à la structure de dossiers du projet dans les IDE.

Donc, dans votre racine, dites que vous avez /my_lib/foo.h et que vous voulez l’inclure dans un fichier source en tant que

#include "my_lib/foo.h"

Ensuite, dans votre CMakeLists.txt, vous devez faire:

include_directories(${CMAKE_SOURCE_DIR})

Si, au contraire, vous voulez juste faire

#include "foo.h"

puis dans le CMakeLists.txt, faites

include_directories(${CMAKE_SOURCE_DIR}/my_lib)


Je devrais mentionner que file(GLOB...) n’est pas le moyen recommandé de rassembler votre liste de sources - vous devriez vraiment simplement ajouter chaque fichier explicitement dans le fichier CMakeLists.txt. Ainsi, si vous ajoutez ou supprimez un fichier source ultérieurement, le fichier CMakeLists.txt est modifié et CMake est automatiquement réexécuté à la prochaine tentative de création. Dans la documentation pour file:

Nous vous déconseillons d’utiliser GLOB pour collecter une liste de fichiers source à partir de votre arborescence. Si aucun fichier CMakeLists.txt ne change lors de l'ajout ou de la suppression d'une source, le système de génération généré ne sait pas quand demander à CMake de se régénérer.

21
Fraser

Juste pour clarifier un point dans la réponse de Fraser:

Les en-têtes ne doivent pas être passés à ADD_EXECUTABLE.

La raison en est que la commande de compilation prévue sous Linux, par exemple, est simplement:

gcc main.c mylib.c

et pas:

gcc main.c mylib.c mylib.h

Le pré-processeur C analyse ensuite mylib.c et voit un #include "mylib.h" et utilise son chemin de recherche pour ces fichiers.

En utilisant include_directories à la place, nous modifions le chemin de recherche du préprocesseur cpp, ce qui constitue l'approche correcte. En GCC, cela se traduit par l’ajout de l’indicateur -I à la ligne de commande:

gcc -Inew/path/to/search/for/headers main.c mylib.c