build - not - ¿Cómo recopilar archivos fuente con CMake sin globbing?
descarga cmake (4)
La documentación de CMake establece explícitamente que no se recomienda que el file(GLOB ...)
recopile archivos de origen para una compilación, pero no menciona cuál es el método recomendado en realidad.
Especificar cada archivo fuente manualmente me suena un poco demasiado manualmente. Entonces, ¿cuál es el método correcto para recopilar archivos de origen, si no es un file(GLOB ...)
?
De hecho, el manual es el método recomendado. Al recomendar el uso de GLOB, la documentación simplemente advierte contra un sistema de compilación que depende de los archivos presentes. Por ejemplo, desea agregar un ejecutable de prueba, por lo que crea mytest.cpp. Ups. Ahora se rompe la compilación de tu biblioteca. La documentación para AUX_SOURCE_DIRECTORY (propósito similar a la creación de globos para los archivos de origen) da la siguiente advertencia:
Es tentador utilizar este comando para evitar escribir la lista de archivos de origen para una biblioteca o 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 agrega al directorio sin modificar este archivo, uno tendría que volver a ejecutar manualmente CMake para generar un sistema de compilación que incorpore el nuevo archivo.
Si está seguro de que desea todos los contenidos de un directorio, y no planea agregar nuevos, entonces use un GLOB.
Además, no olvide que la lista de archivos manualmente no tiene que implicar escribir todos los nombres de archivo. Podría hacer, por ejemplo, ls *.cpp >> CMakeLists.txt
, luego usar su editor para mover la lista de archivos al lugar correcto en el archivo.
Uso GLOB para eso exactamente y cada vez que agrego un archivo ejecuto
touch ../src/CMakeLists.txt
El siguiente comando make
volverá a escanear los directorios.
"No hay forma de que CMake genere un sistema de compilación que sepa cuándo se ha agregado un nuevo archivo fuente" ¿De verdad? Está bien, entonces dilo !
No es 100% automático, pero es mucho más fácil que agregar archivos manualmente.
Utilizo un CMakeLists.txt convencional y un script en python para actualizarlo. Ejecuto el script de Python manualmente después de agregar archivos.
import os
import re
def relFiles(base, sub):
fullSub = os.path.join(base,sub)
abs = [os.path.join(dp, f) for dp, dn, fn in os.walk(fullSub) for f in fn]
return [os.path.relpath(f, base) for f in abs]
def updateAddLibrary(cmakelistsDir, subs):
cmakelists = os.path.join(cmakelistsDir, "CMakeLists.txt")
listings = [relFiles(cmakelistsDir, sub) for sub in subs]
files = [f for listing in listings for f in listing] #flatten
with open(cmakelists, ''r'') as file:
text = file.read()
sources = "".join([" %s/n" % f.replace(''//', ''/'') for f in files])
text = re.sub(r"add_library/s*/(/s*([^/s/)]+).*?/)",
r"add_library(/1/n%s)" % sources,
text, 1, re.DOTALL)
with open(cmakelists, "w") as file:
file.write(text)
dir = os.path.dirname(os.path.abspath(__file__))
updateAddLibrary(dir, [''inc'',''src''])
Ejemplo anterior:
...
add_library(MyLib
inc/a.h
)
...
después:
...
add_library(MyLib
inc/a.h
inc/sub/b.h
src/a.cpp
)
...
Yo uso cog , un módulo de python. Aquí hay una muestra para recolectar el archivo .cpp:
El CMakeLists.txt:
set(SRC_FILES "")
# [[[cog
# import cog, glob
# for src in glob.glob(''*.cpp''):
# if "skeleton" in src: continue
# cog.outl("SET(SRC_FILES ${SRC_FILES} %s)" % src)
# ]]]
# [[[end]]]
add_library(mylib STATIC ${SRC_FILES})
Y luego, corre:
python -m cogapp -r CMakeLists.txt
El archivo CMakeLists.txt se actualizará en su lugar.
Para saber cómo instalar cog y otros usos, lea cog .