2012-06-06 10 views
21

El CMake documentation establece explícitamente que file(GLOB ...) no es recomendado para recopilar archivos fuente para una compilación, pero no menciona cuál es realmente el método recomendado.Cómo recolectar archivos fuente con CMake sin englobar?

Especificar cada archivo de origen manualmente suena un poco demasiado manual para mí. Entonces, ¿cuál es el método correcto para recopilar archivos fuente, si no es file(GLOB ...)?

+0

Usted podría utilizar MUNDIALIZA de cmake en un script y tienen que añadir volcar los nombres de archivo. – Damian

Respuesta

17

Manual de hecho es el método recomendado. Al recomendar no usar GLOB, la documentación es simplemente una advertencia 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. Oops. Ahora tu compilación de la biblioteca se rompe. La documentación para AUX_SOURCE_DIRECTORY (propósito similar como comodines para los archivos fuente) da la siguiente advertencia:

Es tentador utilizar este comando para evitar la escritura de la lista de archivos fuente para una biblioteca o ejecutable de destino. 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.

Si está seguro de que quiere todos los contenidos de un directorio y no planea agregarlos, utilice un GLOB.

Además, no se olvide de enumerar los archivos manualmente, no tiene que implicar escribir todos los nombres de los archivos. Puede hacer, por ejemplo, ls *.cpp >> CMakeLists.txt, luego use su editor para mover la lista de archivos al lugar correcto en el archivo.

+0

Tipo de depende del IDE tbh. En Qt Creator, siempre vuelve a ejecutar CMake, por lo que usar GLOB no es un problema. – Lap

+2

'printf" add_library (xxx $ (ls * .cpp)) ">> ¡CMakeLists.txt' también debería ser bueno! – Alex

+0

No creo que su complicación sea válida, ya que las pruebas generalmente se encuentran en la carpeta de prueba y no deberían saturar el árbol de fuentes. – Arne

12

utilizo GLOB para exactamente el mismo y cada vez que agrego un archivo corro

touch ../src/CMakeLists.txt 

make El siguiente comando se volverá a explorar 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" ¿En serio? De acuerdo, así que dígale!

No es 100% automático, pero mucho más fácil que agregar archivos manualmente.

1

Yo uso cog, un módulo de python. Este es un ejemplo para recoger 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, ejecute:

python -m cogapp -r CMakeLists.txt 

El archivo CMakeLists.txt se actualizará en su sitio.

Para saber cómo instalar el engranaje y otros usos, lea the article from the author.

0

Uso un CMakeLists.txt convencional y un script de python para actualizarlo. Ejecuto el script 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 antes:

... 
add_library(MyLib 
    inc/a.h 
) 
... 

después:

... 
add_library(MyLib 
    inc/a.h 
    inc/sub/b.h 
    src/a.cpp 
)   
... 
Cuestiones relacionadas