it-swarm.dev

¿Cómo usar todos los archivos * .c en un directorio con el sistema de compilación de Cmake?

Quiero encontrar todos los archivos .c en un directorio y agregarlos a los archivos SRC para compilarlos en cmake. ¿Cómo puedo hacer esto en CMakeList.txt.

para makefiles regulares puedo crear

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

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

51
user256537

Prueba esto:

AUX_SOURCE_DIRECTORY

Encuentra todos los archivos de origen en un directorio.

AUX_SOURCE_DIRECTORY(dir VARIABLE) 

Recopila los nombres de todos los archivos de origen en el directorio especificado y almacena la lista en la variable proporcionada. Este comando está destinado a ser utilizado por proyectos que utilizan la creación de instancias explícita de plantillas. Los archivos de creación de instancias de plantillas pueden almacenarse en un subdirectorio de "Plantillas" y recopilarse automáticamente utilizando este comando para evitar la inclusión manual de todas las instancias.

Es tentador utilizar este comando para evitar escribir la lista de archivos de origen para una biblioteca o un destino ejecutable. Si bien esto parece funcionar, CMake no tiene forma de generar 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 es necesario volver a ejecutar CMake porque el archivo CMakeLists.txt se modifica para agregar una nueva fuente. Cuando la fuente se acaba de agregar al directorio sin modificar este archivo, uno tendría que ejecutar CMake manualmente para generar un sistema de compilación que incorpore el nuevo archivo.

44
whitequark

¿Qué hay de los buenos viejos globos?

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

GLOB_RECURSE ejemplo recursivo

Básicamente, hace que el * también vaya a los subdirectorios:

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

Y luego nuestras fuentes podrían ubicarse, por ejemplo, como:

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

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

El uso de GLOB_RECURSE en el nivel superior de CMake (es decir, "*.c" en lugar de "src/*.c") es probablemente una mala idea, ya que puede recoger .c generados por el propio CMake que se colocan bajo build/.

Ejemplo ejecutable en GitHub .

Sí, tienes dos opciones. Supongamos que la estructura de carpetas es algo 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, debe agregar CMakeLists.txt cada uno de los subdirectorios. Luego tienes que incluir y enlazar todos esos subdirectorios. Esta es una tarea bastante difícil. Así que 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 el código fuente anterior, este es el comando:

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

Si desea crear un archivo ejecutable utilizando el código fuente anterior, este es el comando:

 ADD_EXECUTABLE(autopilot ${autopilot})
1
GPrathap

Puede usar AUX_SOURCE_DIRECTORY como se describe en @whitequark, pero realmente no funcionará como espera, ya que CMake no podrá determinar cuándo se agregarán nuevos archivos (que es una especie de punto con el uso de un comodín).

0
JesperE