¿Es mejor especificar los archivos fuente con GLOB o cada archivo individualmente en CMake?

Resuelto Marenz asked hace 15 años • 7 respuestas

CMake ofrece varias formas de especificar los archivos de origen para un destino. Una es utilizar globbing ( documentación ), por ejemplo:

FILE(GLOB MY_SRCS dir/*)

Otro método consiste en especificar cada archivo individualmente.

¿Qué camino se prefiere? Globbing parece fácil, pero he oído que tiene algunas desventajas.

Marenz avatar Jun 22 '09 20:06 Marenz
Aceptado

Divulgación completa: originalmente prefería el enfoque global por su simplicidad, pero a lo largo de los años he llegado a reconocer que enumerar explícitamente los archivos es menos propenso a errores para proyectos grandes de múltiples desarrolladores.

Respuesta original:


Las ventajas del globbing son:

  • Es fácil agregar archivos nuevos ya que solo se enumeran en un lugar: en el disco. No globalizar crea duplicación.

  • Su archivo CMakeLists.txt será más corto. Esta es una gran ventaja si tienes muchos archivos. No globalizar hace que se pierda la lógica de CMake entre enormes listas de archivos.

Las ventajas de utilizar listas de archivos codificadas son:

  • CMake rastreará correctamente las dependencias de un nuevo archivo en el disco: si usamos glob, los archivos que no se hayan agregado la primera vez cuando se ejecutó CMake no se seleccionarán

  • Asegúrese de que solo se agreguen los archivos que desee. Globbing puede detectar archivos perdidos que no desea.

Para solucionar el primer problema, simplemente puede "tocar" el CMakeLists.txt que realiza el global, ya sea usando el comando táctil o escribiendo el archivo sin cambios. Esto obligará a CMake a volver a ejecutarse y seleccionar el nuevo archivo.

Para solucionar el segundo problema, puedes organizar tu código cuidadosamente en directorios, que es lo que probablemente harás de todos modos. En el peor de los casos, puede utilizar el list(REMOVE_ITEM)comando para limpiar la lista global de archivos:

file(GLOB to_remove file_to_remove.cpp)
list(REMOVE_ITEM list ${to_remove})

La única situación real en la que esto puede afectarte es si estás usando algo como git-bisect para probar versiones anteriores de tu código en el mismo directorio de compilación. En ese caso, es posible que deba limpiar y compilar más de lo necesario para asegurarse de obtener los archivos correctos en la lista. Este es un caso tan extremo, en el que ya estás alerta, que en realidad no es un problema.

richq avatar Jun 29 '2009 19:06 richq

La mejor manera de especificar archivos fuente en CMake es enumerarlos explícitamente .

Los propios creadores de CMake aconsejan no utilizar globbing.

Ver: Sistema de archivos

(No recomendamos usar GLOB para recopilar una lista de archivos fuente de su árbol de fuentes. Si ningún archivo CMakeLists.txt cambia cuando se agrega o elimina una fuente, entonces el sistema de compilación generado no puede saber cuándo pedirle a CMake que se regenere).

Por supuesto, es posible que desees saber cuáles son las desventajas: ¡ sigue leyendo!


Cuando el globalización falla:

La gran desventaja del globbing es que la creación/eliminación de archivos no actualizará automáticamente el sistema de compilación.

Si usted es la persona que agrega los archivos, esto puede parecer una compensación aceptable. Sin embargo, esto causa problemas a otras personas que crean su código; actualizan el proyecto desde el control de versiones, ejecutan la compilación y luego se comunican con usted quejándose de que
"la compilación no funciona".

Para empeorar las cosas, la falla generalmente genera algún error de enlace que no da ninguna pista sobre la causa del problema y se pierde tiempo solucionándolo.

En un proyecto en el que trabajé, comenzamos con el globbing, pero recibimos tantas quejas cuando se agregaron nuevos archivos que fue razón suficiente para enumerar archivos explícitamente en lugar de globbing.

Esto también interrumpe los flujos de trabajo comunes de Git
( git bisecty el cambio entre ramas de funciones).

Entonces no podría recomendar esto. Los problemas que causa superan con creces la conveniencia. Cuando alguien no puede crear su software debido a esto, puede perder mucho tiempo para localizar el problema o simplemente darse por vencido.

Y otra nota. CMakeLists.txtNo siempre basta con recordar tocar . Con las compilaciones automatizadas que utilizan globbing, tuve que ejecutar cmakeantes de cada compilación , ya que es posible que se hayan agregado o eliminado archivos desde la última compilación *.

Excepciones a la regla:

Hay ocasiones en las que es preferible el globbing:

  • Para configurar CMakeLists.txtarchivos para proyectos existentes que no usan CMake.
    es una forma rápida de hacer referencia a todas las fuentes (una vez que el sistema de compilación se esté ejecutando, reemplace el globbing con listas de archivos explícitas).
  • Cuando CMake no se usa como sistema de compilación principal , si, por ejemplo, está usando un proyecto que no usa CMake y le gustaría mantener su propio sistema de compilación para ello.
  • Para cualquier situación en la que la lista de archivos cambie con tanta frecuencia que su mantenimiento resulte poco práctico. En este caso, podría ser útil, pero luego debe aceptar ejecutar cmakepara generar archivos de compilación cada vez para obtener una compilación confiable/correcta (lo que va en contra de la intención de CMake: la capacidad de dividir la configuración de la compilación) .

* Sí, podría haber escrito un código para comparar el árbol de archivos en el disco antes y después de una actualización, pero esta no es una solución tan buena y es mejor dejarla en manos del sistema de compilación.

ideasman42 avatar Aug 30 '2013 17:08 ideasman42

En CMake 3.12, los comandos file(GLOB ...)yfile(GLOB_RECURSE ...) obtuvieron una CONFIGURE_DEPENDSopción que vuelve a ejecutar cmake si el valor del globo cambia. Como esa era la principal desventaja de buscar archivos fuente, ahora está bien hacerlo:

# Whenever this glob's value changes, cmake will rerun and update the build with the
# new/removed files.
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.cpp")

add_executable(my_target ${sources})

Sin embargo, algunas personas todavía recomiendan evitar buscar fuentes. De hecho, la documentación dice:

No recomendamos utilizar GLOB para recopilar una lista de archivos fuente de su árbol de fuentes. ... Es posible que la CONFIGURE_DEPENDSbandera no funcione de manera confiable en todos los generadores, o si en el futuro se agrega un nuevo generador que no puede admitirla, los proyectos que la utilicen se bloquearán. Incluso si CONFIGURE_DEPENDSfunciona de manera confiable, aún existe un costo por realizar la verificación en cada reconstrucción.

Personalmente, considero que los beneficios de no tener que administrar manualmente la lista de archivos fuente superan los posibles inconvenientes. Si tiene que volver a los archivos enumerados manualmente, esto se puede lograr fácilmente simplemente imprimiendo la lista de fuentes global y pegándola nuevamente.

Justin avatar Mar 21 '2019 23:03 Justin