Soy un principiante make
y me pregunto cuándo usarlo make clean
.
Un colega me dijo que las compilaciones incrementales make
se basan en las marcas de tiempo de los archivos. Por lo tanto, si revisa una versión anterior de un archivo en su VCS, tendrá una marca de tiempo "antigua" y se marcará como "no es necesario volver a compilar este archivo". Entonces, ese archivo no se incluiría en la próxima compilación.
Según ese mismo colega, sería una razón para usar make clean
.
De todos modos, recibí la respuesta a la pregunta "cuándo usar make clean
" de otras preguntas de StackExchange, pero mi otra pregunta es:
¿Por qué las compilaciones incrementales que se
make
basan en marcas de tiempo de archivos y no en SHA-1 por ejemplo? Git, por ejemplo, muestra que podemos determinar con éxito si un archivo se modificó utilizando el SHA-1.
¿Es por problemas de velocidad?
make
fue creado en los años 70. SHA-1 fue creado en los años 90. Git fue creado en los años 00. Lo último que desea es que algunas compilaciones oscuras que estuvieron funcionando durante 30 años fallaran repentinamente porque alguien decidió modernizarse con un sistema probado.make
software, entonces su software no se romperá, sin embargo,make
hace un esfuerzo por tener compatibilidad con versiones anteriores. Cambiar el comportamiento central sin una buena razón es más o menos lo contrario de eso. Y las fechas muestran por qué no se hizo originalmente para usar SHA-1, o por qué no fue fácil adaptarlo cuando estuvo disponible (make
ya tenía décadas de antigüedad).Respuestas:
Un problema obvio (y posiblemente superficial) sería que el sistema de compilación tendría que mantener un registro de los hash de los archivos que se utilizaron para la última compilación. Si bien este problema ciertamente podría resolverse, requeriría almacenamiento lateral cuando la información de marca de tiempo ya está presente en el sistema de archivos.
Sin embargo, más en serio, el hash no transmitiría la misma semántica. Si sabe que el archivo T se creó a partir de la dependencia D con el hash H 1 y luego descubre que D ahora se convierte en hash a H 2 , ¿debería reconstruir T ? Probablemente sí, pero también podría ser que H 2 en realidad se refiera a una versión anterior del archivo. Las marcas de tiempo definen un orden, mientras que los hash solo son comparables para la igualdad.
Una característica que admite las marcas de tiempo es que simplemente puede actualizar la marca de tiempo (por ejemplo, utilizando la utilidad de línea de comandos POSIX
touch
) para engañarmake
y pensar que una dependencia ha cambiado o, lo que es más interesante, que un objetivo es más reciente de lo que realmente es. Si bien jugar con esto es una gran oportunidad para dispararte en el pie, es útil de vez en cuando. En un sistema basado en hash, necesitaría soporte del propio sistema de compilación para actualizar su base de datos interna de hashes utilizados para la última compilación sin realmente construir nada.Si bien ciertamente se podría argumentar el uso de hashes sobre marcas de tiempo, mi punto es que no son una mejor solución para lograr el mismo objetivo, sino una solución diferente para lograr un objetivo diferente. Cuál de estos objetivos es más deseable podría estar abierto a debate.
fuente
D
ahora tiene problemasH2
, y no tiene una salidaT2
construidaD@H2
, debe producirla y almacenarla. A partir de entonces, independientemente del orden deD
cambio entre los estadosH1
yH2
, podrá utilizar la salida en caché.Hashing un proyecto completo es muy lento. Tienes que leer cada byte de cada archivo. Git no hace hash en cada archivo cada vez que ejecutas uno de los
git status
dos. Tampoco los pagos de VCS normalmente establecen el tiempo de modificación de un archivo al tiempo original creado. Una restauración de respaldo lo haría, si tiene cuidado de hacerlo. Toda la razón por la que los sistemas de archivos tienen marcas de tiempo es para casos de uso como estos.Un desarrollador generalmente se ejecuta
make clean
cuando una dependencia no directamente rastreada por los cambios de Makefile. Irónicamente, esto generalmente incluye el Makefile mismo. Por lo general, también incluye versiones del compilador. Dependiendo de qué tan bien esté escrito su Makefile, podría incluir versiones de bibliotecas externas.Este es el tipo de cosas que tienden a actualizarse cuando se realiza una actualización de control de versiones, por lo que la mayoría de los desarrolladores solo tienen la costumbre de ejecutar una
make clean
al mismo tiempo, para que sepa que está comenzando desde cero. Puede escapar sin hacerlo muchas veces, pero es realmente difícil predecir los momentos en que no puede hacerlo.fuente
Algunos puntos sobre hashes vs marcas de tiempo en sistemas de compilación:
fuente