Warum make over ein Shell-Skript verwenden?

127

Make scheint mir einfach ein Shell-Skript mit etwas einfacherem Umgang mit Kommandozeilenargumenten zu sein.

Warum ist es Standard, make anstelle von ./make.sh auszuführen?

HoboBen
quelle
Für die umgekehrte Frage: Warum Shell-Skript über make verwenden (aufgrund der offensichtlich einfacheren Handhabung von Befehlszeilenargumenten), insbesondere für Systemadministratoraufgaben, lesen Sie hier: unix.stackexchange.com/a/497601/1170
lesmana

Antworten:

124

Die allgemeine Idee ist, dass make(vernünftigerweise) minimale Neuerstellungen unterstützt werden - dh Sie sagen, welche Teile Ihres Programms von welchen anderen Teilen abhängen. Wenn Sie einen Teil des Programms aktualisieren, werden nur die Teile neu erstellt, die davon abhängen. Während Sie dies mit einem Shell-Skript tun könnten , wäre es viel mehr Arbeit (explizites Überprüfen der zuletzt geänderten Daten aller Dateien usw.). Die einzige offensichtliche Alternative mit einem Shell-Skript besteht darin, jedes Mal alles neu zu erstellen. Für kleine Projekte ist dies ein durchaus vernünftiger Ansatz, aber für ein großes Projekt kann ein vollständiger Umbau leicht eine Stunde oder länger dauern - mit makekönnen Sie das gleiche in ein oder zwei Minuten erreichen ...

Ich sollte wahrscheinlich auch hinzufügen, dass es einige Alternativen gibt, die zumindest weitgehend ähnliche Fähigkeiten aufweisen. Insbesondere in Fällen, in denen nur wenige Dateien in einem großen Projekt neu erstellt werden, sind einige von ihnen (z. B. Ninja ) häufig erheblich schneller als make.

Jerry Sarg
quelle
66

Make ist ein Expertensystem

Es gibt verschiedene Dinge, die mit Shell-Skripten schwer zu tun sind ...

  • Natürlich wird geprüft, was veraltet ist, um nur das zu erstellen, was zum Erstellen benötigt wird
  • Es führt eine topologische Sortierung durch oder eine andere Art von Baumanalyse durch, die bestimmt, was von welcher und welcher Reihenfolge abhängt, um die veralteten Dinge so zu erstellen, dass jede Voraussetzung vor jeder Abhängigkeit erstellt wird und nur einmal erstellt wird.
  • Es ist eine Sprache für deklarative Programmierung . Neue Elemente können hinzugefügt werden, ohne dass sie zu einem zwingenden Kontrollfluss zusammengeführt werden müssen.
  • Es enthält eine Inferenz-Engine zum Verarbeiten von Regeln, Mustern und Datumsangaben. In Kombination mit den Regeln in Ihrem Makefile wird daraus ein Expertensystem .
  • Es hat einen Makroprozessor.
  • Siehe auch: eine frühere Zusammenfassung von make .
DigitalRoss
quelle
2
Als Expertensystem ist es jedoch ziemlich begrenzt. Beispielsweise kann jede Folgerung dieselbe Regel nur einmal verwenden.
Reinierpost
1
Um auf Punkt 2) näher zu kommen, erzwingt ein Shell-Skript eine lineare Reihenfolge, während ein Makefile baumartig ist. Es beseitigt unnötige chronologische Abhängigkeiten (obwohl in der Praxis der Erstellungsprozess linear ausgeführt würde).
Sridhar Sarnobat
2
... Ich denke, das Problem mit Makefiles über Shell-Skripten ist analog zu dem Problem mit CSS über Javascript. Es ist bei weitem nicht so offensichtlich, in welcher chronologischen Reihenfolge jeder Knoten ausgeführt wird. Zumindest bei Makefiles wird der tatsächliche Shell-Befehl jedoch weiterhin angezeigt. Mit CSS wird auch das weg abstrahiert.
Sridhar Sarnobat
Ich habe ein paar Kommentare, die ich schätze, wenn jemand sie klarstellt. 1 / hängen Ihre ersten und zwei Punkte nicht zusammen, in dem Sinne, dass diese topologische Sortierung die Art und Weise ist, wie der inkrementelle Build implementiert wird? 2 / Kannst du Punkt 3 nicht auch mit Funktionszusammensetzung implementieren? 3 / Ich möchte mehr über die Vorteile von 4 und 5 für den MakeFile-Endbenutzer erfahren und warum diese Vorteile nicht durch gemeinsames
Erstellen
Dies ist das erste Mal, dass ich auf Make stoße, das als Expertensystem beschrieben wird. Als jemand, der Expertensysteme gebaut hat, hätte ich das nicht in Betracht gezogen. Make verfügt offensichtlich über eine Inferenz-Engine, mit der abgeleitet werden kann, wie Ihr Programm anhand der im Makefile angegebenen deklarativen Regeln erstellt wird. Es ist jedoch weniger offensichtlich, dass es sich um ein wissensbasiertes System handelt, da die (Blatt-) Regeln Shell-Befehle sind, die ausgeführt werden sollen, und keine Fakten. Und der Begriff "Expertensystem" bezieht sich auf ein System, das das Fachwissen eines Weltklasse-Experten erfolgreich erfasst hat, was nicht der Fall ist. Die Jury ist immer noch für mich da.
Dennis
9

Make stellt sicher, dass nur die erforderlichen Dateien neu kompiliert werden, wenn Sie Änderungen an Ihren Quelldateien vornehmen.

Beispielsweise:

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

Wenn ich 2.hnur die Datei ändere makeund ausführe, werden alle 3 Befehle in umgekehrter Reihenfolge ausgeführt.

Wenn ich 1.cnur die Datei ändere und ausführe make, werden nur die ersten beiden Befehle in umgekehrter Reihenfolge ausgeführt.

Der Versuch, dies mit Ihrem eigenen Shell-Skript zu erreichen, erfordert viele if/elseÜberprüfungen.

Chris Dodd
quelle
oder verwenden Sie so etwas rsync -r -c -I $SOURCE $DEST_DIRin der Shell.
Spartacus9
9

Darüber hinaus ist Make eine deklarative (-ish) parallele Programmiersprache.

Angenommen, Sie müssen 4.000 Grafikdateien und 4 CPUs konvertieren. Versuchen Sie, ein 10-zeiliges Shell-Skript zu schreiben (ich bin hier großzügig), das dies zuverlässig tut, während Ihre CPUs gesättigt sind.

Vielleicht ist die eigentliche Frage, warum sich die Leute die Mühe machen, Shell-Skripte zu schreiben.

Bobbogo
quelle
1
Ja, Sie lockern die gesamte lineare Reihenfolge in eine baumartigere Reihenfolge.
Sridhar Sarnobat
4

make behandelt Abhängigkeiten: Das Makefile beschreibt sie: Die Binärdatei hängt von Objektdateien ab, jede Objektdatei hängt von einer Quelldatei und Headern ab. Wenn make ausgeführt wird, wird das Datum der Dateien verglichen, um zu bestimmen, was neu kompiliert werden muss .

Man kann direkt ein Ziel aufrufen, um nicht alles zu erstellen, was im Makefile beschrieben ist.

Darüber hinaus bietet die make-Syntax die Substitution vpath

All dies kann in Shell-Skripten geschrieben werden, mit make haben Sie es bereits.

Philant
quelle