web-dev-qa-db-fra.com

Comment utiliser tous les fichiers * .c dans un répertoire avec le système de construction Cmake?

Je veux trouver tous les fichiers .c dans un répertoire et les ajouter tous aux fichiers SRC à compiler dans cmake. Comment puis-je faire cela dans CMakeList.txt.

pour les makefiles réguliers, je peux créer 

SPECIFIED_SRC_FILE  = $(foreach d,$(SPECIFIED_SRC_DIRS),$(wildcard $(addprefix $(d)/*,*.c)))

mais je ne savais pas comment faire quelque chose comme ça dans CMakeList.txt.

46
user256537

Essaye ça:

AUX_SOURCE_DIRECTORY

Trouver tous les fichiers source dans un répertoire. 

AUX_SOURCE_DIRECTORY(dir VARIABLE) 

Collecte les noms de tous les fichiers source dans le répertoire spécifié et stocke la liste dans la variable fournie. Cette commande est destinée à utiliser par les projets utilisant l'instanciation de modèle explicite . Les fichiers d'instanciation de modèles peuvent être stockés dans un "Modèles" sous-répertoire et collectés automatiquement à l'aide de cette commande pour éviter listant manuellement toutes les instanciations. 

Il est tentant d'utiliser cette commande pour éviter d'écrire la liste des sources fichiers pour une bibliothèque ou une cible exécutable. Bien que cela semble fonctionner, CMake n’a aucun moyen de générer un système de compilation qui sache quand un nouveau fichier source a été ajouté. Normalement, le système de compilation généré sait quand il doit réexécuter CMake car le fichier CMakeLists.txt est modifié pour ajouter une nouvelle source. Quand la source vient d’être ajoutée au fichier répertoire sans modifier ce fichier, il faudrait manuellement Relancez CMake pour générer un système de compilation intégrant le nouveau fichier.

42
whitequark

Que diriez-vous du bon vieux Glouton?

FILE(GLOB MyCSources *.c)
ADD_EXECUTABLE(MyExecutable ${MyCSources})
50
Dat Chu

GLOB_RECURSE exemple récursif

Fondamentalement, le * est également placé dans les sous-répertoires:

cmake_minimum_required(VERSION 3.0)
file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.c")
add_executable(main ${SOURCES})

Et puis nos sources pourraient être localisées par exemple comme:

src/main.c
src/d/a.c
src/d/a.h

Et main.c utilise #include "d/a.h" et a.c utilise #include "a.h".

Utiliser GLOB_RECURSE sur le niveau supérieur de CMake (à savoir "*.c" au lieu de "src/*.c") est probablement une mauvaise idée, car il peut récupérer les fichiers .c générés par CMake lui-même et placés sous build/.

Exemple exécutable sur GitHub .

Oui, vous avez deux options. Supposons que la structure du dossier ressemble à ceci. 

├── autopilot
            │   ├── _AutoPilot.cpp
            │   ├── _AutoPilot.h
            │   └── action
            │       ├── ActionBase.cpp
            │       ├── ActionBase.h
            │       ├── APcopter
            │       │   ├── APcopter_avoid.cpp
            │       │   ├── APcopter_avoid.h

Si vous devez utiliser AUX_SOURCE_DIRECTORY, vous devez ajouter CMakeLists.txt à chacun des sous-répertoires. Ensuite, vous devez inclure et lier tous ces sous-répertoires. C'est une tâche assez difficile. Vous pouvez donc GLOB et faire le travail très facilement. Voici comment cela se fait.

  file(GLOB autopilot_sources ./*.cpp ./*/*.cpp ./*/*/*.cpp ./*/*/*/*.cpp ./*.c ./*/*.c ./*/*/*.c ./*/*/*/*.c)
  SET( autopilot ${autopilot_sources})  

Si vous voulez créer une bibliothèque en utilisant le code source ci-dessus, utilisez la commande suivante: 

  ADD_LIBRARY ( autopilot  ${autopilot})
  TARGET_LINK_LIBRARIES ( autopilot)  

Si vous voulez créer un fichier exécutable en utilisant le code source ci-dessus, utilisez la commande suivante: 

 ADD_EXECUTABLE(autopilot ${autopilot})
1
GPrathap

Vous pouvez utiliser AUX_SOURCE_DIRECTORY comme décrit par @whitequark, mais cela ne fonctionnera pas comme prévu, car CMake ne sera pas en mesure de déterminer quand de nouveaux fichiers sont ajoutés (ce qui est génial avec l'utilisation d'un caractère générique).

0
JesperE