2010-01-21 4 views
42

Quiero encontrar todos los archivos .c en un directorio y agregarlos a todos los archivos SRC para compilar en cmake. ¿Cómo puedo hacer esto en CMakeList.txt?cómo encontrar todos los archivos * .c para el sistema de compilación Cmake

de Makefile regulares puedo crear

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

pero no pude conseguir cómo hacer algo como esto en CMakeList.txt.

+1

Tenga en cuenta que "recopilar todos los archivos fuente con glob" ** no es recomendado ** en CMake: * No recomendamos usar 'GLOB' para recopilar una lista de archivos fuente de su árbol fuente. Si no se cambia ningún archivo 'CMakeLists.txt' cuando se agrega o elimina una fuente, el sistema de compilación generado no puede saber cuándo solicitar la regeneración de CMake. * - a partir de [documentación] (https://cmake.org/cmake/help/ v3.7/command/file.html) –

+0

@FranklinYu ¿existe una alternativa que no requiera escribir cada nombre de archivo manualmente? –

+1

@Ciro Si quiere evitar escribir cada nombre de archivo, entonces creo que 'foreach' mencionado por OP es el camino a seguir. Sin embargo, el equipo de CMake parece recomendar * escribir manualmente cada nombre de archivo *. –

Respuesta

39

Prueba esto:

AUX_SOURCE_DIRECTORY

Encuentra todos los archivos de origen en un directorio.

AUX_SOURCE_DIRECTORY(dir VARIABLE) 

recoge los nombres de todos los archivos de origen en el directorio especificado y almacena la lista en la variable proporcionada. Este comando está destinado al para que lo usen los proyectos que usan instancias explícitas de plantillas. Los archivos de creación de instancias de plantillas se pueden almacenar en un subdirectorio "Plantillas" y se recopilan automáticamente con este comando para evitar que enumere manualmente todas las instancias.

Es tentador usar este comando para evitar escribir la lista de los archivos fuente para una biblioteca o un objetivo ejecutable. Si bien esto parece funcionar, no hay forma de que CMake genere un sistema de compilación que sepa cuándo se ha agregado un nuevo archivo fuente . Normalmente, el sistema de compilación generado sabe cuándo debe volver a ejecutar CMake porque el archivo CMakeLists.txt está modificado para agregar una nueva fuente. Cuando la fuente se acaba de agregar al directorio sin modificar este archivo, uno tendría que volver a ejecutar CMake manualmente para generar un sistema de compilación que incorpore el nuevo archivo.

+11

asegúrese y lea la última parte que comienza con "Es tentador usar este comando para evitar ..." – SaoPauloooo

+1

@SaoPauloooo, como está escrito a continuación, "no hay forma de que Cmake genere un sistema de compilación que sepa cuándo un nuevo el archivo fuente ha sido agregado ". Este comando es la respuesta más cercana a la pregunta de OP. Bien por mí. – whitequark

0

Se puede utilizar como AUX_SOURCE_DIRECTORY @whitequark descrito, pero realmente no funcionar como se esperaba, ya que CMake no será capaz de determinar cuando se añaden nuevos archivos (que es una especie de todo el punto con el uso de un comodín)

+2

AUX_SOURCE_DIRECTORY se realiza bien por ahora. Muchas gracias. AUX_SOURCE_DIRECTORY ($ {} PROJECT_INC_DIR de control/src CTR_SOURCES) ADD_EXECUTABLE ($ {} $ {EXE_NAME CTR_SOURCES}) –

41

¿Qué tal el buen viejo globbing?

FILE(GLOB MyCSources *.c) 
ADD_EXECUTABLE(MyExecutable ${MyCSources}) 
+0

Esto funciona muy bien, pero ¿evita la advertencia (que CMake no sabrá cuando se añaden nuevos archivos) en las otras dos respuestas? – kylewm

+1

No, no es así. Aún necesitará volver a ejecutar CMake una vez que se agregue un nuevo archivo. –

+8

(que acabó estando bien para mis necesidades ... más fácil que editar CMakeList cada vez que agrega un archivo fuente) – kylewm

1

Sí, tienes dos opciones. Supongamos que la estructura de la carpeta es similar a esto.

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

Si va a utilizar AUX_SOURCE_DIRECTORY hay que añadir CMakeLists.txt cada uno de los subdirectorios. Luego debe incluir y vincular todos esos subdirectorios. Esta es una tarea bastante difícil. Entonces puedes GLOB y hacer el trabajo muy fácilmente. Así es como se hace.

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

Si desea crear una biblioteca utilizando por encima de código fuente Este es el comando:

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

Si desea crear un archivo ejecutable utilizando por encima de código fuente Este es el comando:

ADD_EXECUTABLE(autopilot ${autopilot}) 
0

GLOB_RECURSE ejemplo recursiva

Básicamente hace que el * también van en subdirectorios:

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

Y entonces nuestras fuentes podría estar situada por ejemplo como:

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

Y main.c utiliza #include "d/a.h" y a.c utiliza #include "a.h".

Usando GLOB_RECURSE en el nivel superior CMake (es decir, en lugar de "*.c""src/*.c") es probablemente una mala idea, ya que puede recoger .c archivos generados por la naturaleza CMake que se sometan a build/.

Ejecutable, ejemplo on GitHub.

Cuestiones relacionadas