¿Por qué usar make sobre un script de shell?

128

Make me parece simplemente un script de shell con un manejo un poco más fácil de los argumentos de la línea de comandos.

¿Por qué es estándar ejecutar make en lugar de ./make.sh

HoboBen
fuente
para la pregunta inversa: ¿por qué usar el script de shell sobre make (debido al manejo aparentemente más fácil de los argumentos de la línea de comandos), especialmente para tareas de administrador del sistema, lea aquí: unix.stackexchange.com/a/497601/1170
lesmana

Respuestas:

125

La idea general es que makeadmite (razonablemente) reconstrucciones mínimas, es decir, usted le dice qué partes de su programa dependen de qué otras partes. Cuando actualiza alguna parte del programa, solo reconstruye las partes que dependen de eso. Si bien podría hacer esto con un script de shell, sería mucho más trabajo (verificar explícitamente las fechas de última modificación en todos los archivos, etc.) La única alternativa obvia con un script de shell es reconstruir todo cada vez. Para proyectos pequeños, este es un enfoque perfectamente razonable, pero para un proyecto grande, una reconstrucción completa podría tomar fácilmente una hora o más; si lo usa make, puede lograr lo mismo en un minuto o dos ...

Probablemente también debería agregar que hay bastantes alternativas para hacer que tienen capacidades al menos ampliamente similares. Especialmente en los casos en que solo se están reconstruyendo unos pocos archivos en un proyecto grande, algunos de ellos (por ejemplo, Ninja ) a menudo son considerablemente más rápidos que los de creación.

Jerry Coffin
fuente
66

Make es un sistema experto

Hay varias cosas que hacen que sean difíciles de hacer con los scripts de shell ...

  • Por supuesto, verifica qué está desactualizado, para construir solo lo que necesita construir
  • Realiza un análisis topológico u otro tipo de análisis de árbol que determina qué depende de qué y en qué orden construir las cosas desactualizadas de modo que cada requisito previo se cree antes de cada dependencia, y solo se construya una vez.
  • Es un lenguaje para la programación declarativa . Se pueden agregar nuevos elementos sin necesidad de fusionarlos en un flujo de control imperativo.
  • Contiene un motor de inferencia para procesar reglas, patrones y fechas, y esto, cuando se combina con las reglas en su Makefile particular, es lo que convierte a Make en un sistema experto .
  • Tiene un procesador macro.
  • Ver también: un resumen anterior de make .
DigitalRoss
fuente
2
Sin embargo, es bastante limitado como sistema experto. Por ejemplo, cada inferencia puede usar la misma regla solo una vez.
reinierpost
1
Solo para desarrollar el punto 2) en términos de ingeniería más simples, un script de shell impone un orden lineal, mientras que un archivo MAKE es como un árbol. Elimina dependencias cronológicas innecesarias (aunque en la práctica el proceso de creación se ejecutaría linealmente).
Sridhar Sarnobat
2
... Creo que el problema con Makefiles sobre scripts de shell es análogo al problema con CSS sobre JavaScript. No es tan obvio en qué orden cronológico se ejecuta cada nodo. Aunque al menos con Makefiles todavía puede ver el comando de shell real. Con CSS incluso eso se abstrae.
Sridhar Sarnobat
Tengo algunos comentarios que agradezco si alguien los aclara. 1 / ¿No están relacionados sus primeros y dos puntos, en el sentido de que ese orden topológico es cómo se implica la construcción incremental? 2 / ¿no puede señalar el número 3 implementado usando la composición de funciones también? 3 / Me gustaría entender más sobre las ventajas de 4 y 5 para el usuario final de MakeFile, y por qué estas ventajas no se pueden implementar componiendo comandos de shell juntos
Amine Hajyoussef
Esta es la primera vez que me encuentro con Make descrito como un sistema experto. Como alguien que ha construido sistemas expertos, no es algo que hubiera considerado. Obviamente, Make tiene un motor de inferencia para deducir cómo construir su programa a través de las reglas declarativas especificadas en el archivo MAKE, pero es menos obvio que es un sistema basado en el conocimiento, ya que las reglas (hoja) son comandos de shell que se ejecutan en lugar de hechos. Y el término "sistema experto" se utiliza para referirse a un sistema que ha capturado con éxito la experiencia de un experto de clase mundial, que no es el caso. El jurado todavía está afuera para mí.
Dennis
9

Make garantiza que solo los archivos necesarios se vuelvan a compilar cuando realice cambios en sus archivos fuente.

Por ejemplo:

final : 1.o 2.o
    gcc -o final 1.o 2.o

1.o : 1.c 2.h
    gcc -c 1.c

2.o : 2.c 2.h
    gcc -c 2.c

Si solo cambio el archivo 2.hy lo ejecuto make, ejecuta los 3 comandos, en orden inverso.

Si solo cambio el archivo 1.cy lo ejecuto make, solo ejecuta los primeros 2 comandos en orden inverso.

Intentar lograr eso con su propio script de shell implicará muchas if/elsecomprobaciones.

Chris Dodd
fuente
o use algo como esto rsync -r -c -I $SOURCE $DEST_DIRen shell.
Spartacus9
9

Además de lo anterior, Make es un lenguaje de programación paralelo declarativo (-ish).

Digamos que tiene 4.000 archivos gráficos para convertir y 4 CPU. Intente escribir un script de shell de 10 líneas (estoy siendo generoso aquí) que lo hará de manera confiable mientras satura sus CPU.

Quizás la verdadera pregunta es por qué la gente se molesta en escribir scripts de shell.

bobbogo
fuente
1
Sí, está aflojando el orden lineal total en un orden más parecido a un árbol.
Sridhar Sarnobat
4

make maneja las dependencias: el archivo MAKE las describe: el binario depende de los archivos de objetos, cada archivo de objetos depende de un archivo de origen y encabezados ... cuando se ejecuta make, se compara la fecha de los archivos para determinar qué se necesita volver a compilar .

Uno puede invocar directamente un objetivo para no construir todo lo descrito en el Makefile.

Además, la sintaxis de make proporciona sustitución, vpath

Todo esto se puede escribir en scripts de shell, haciendo que ya lo tenga.

philant
fuente