make: Regel Aufrufregel

70

Kann ich in einem Makefile eine Regel aus einer anderen Regel aufrufen?

Ähnlich zu:

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"
        rule1
Juan Pablo
quelle

Antworten:

107

Verwenden Sie entweder Abhängigkeiten oder rekursives Erstellen, um eine Verbindung von einer Regel zur anderen herzustellen.

Abhängigkeiten würden wie folgt ausgeführt (obwohl die Reihenfolge unterschiedlich sein wird):

rule1:
        echo "bye"
rule2:
        date
rule3: rule1
        @echo "hello"

Rekursives Erstellen würde folgendermaßen erfolgen (obwohl es sich um einen Unterprozess handelt):

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"
        $(MAKE) rule1

Weder ist perfekt; In der Tat können Sie mit rekursivem Make in erhebliche Probleme geraten, wenn Sie eine Schleife erstellen. Sie sollten wahrscheinlich auch eine .PHONYRegel hinzufügen , um diese Regeln als synthetisch zu kennzeichnen, damit ein Streuner rule1(usw.) im Verzeichnis keine Verwirrung stiftet.

Donal Fellows
quelle
27

Fügen Sie einfach eine neue Regel mit der gewünschten Reihenfolge hinzu.

rule1:
        echo "bye"
rule2:
        date
rule3:
        @echo "hello"

rule4: rule3 rule1
John Eikenberry
quelle
Imho das ist eine viel schönere Lösung als die anderen Antworten.
Jason McVetta
Einfach - ich mag es.
Petr Vepřek
6
Dies wird die Bestellung nicht auferlegen. Es wird nur sichergestellt, dass Regel1 und Regel3 vor Regel4 ausgeführt werden, keine Zusicherung bei der Bestellung
CristianDonosoC
1
Ich stimme dem Kommentar von CristianDonosoC zu. Da es hier keine Reihenfolge zwischen Regel1 und Regel3 gibt, erhalten Sie durch eine parallele Erstellung ( make -j2zum Beispiel) eine unbestimmte Ausführungsreihenfolge.
Seanahern
Es gibt eine Möglichkeit, Voraussetzungen in einer bestimmten Reihenfolge auszuführen : gnu.org/software/make/manual/html_node/Prerequisite-Types.html - Auf diese Weise sollte Regel 4 lauten:rule4: | rule3 rule1
Yoone
21

Makefiles sind nicht prozedural; "Regeln" sind keine Funktionen. Sie können jedoch angeben, dass eine Regel eine Voraussetzung für eine andere ist:

rule1:
    @echo "Rule 1"

rule2: rule1
    @echo "Rule 2"

Wenn Sie dies tun make rule2, sollten Sie sehen:

Rule 1
Rule 2
Oliver Charlesworth
quelle
2
Frustrierend ist jedoch, dass Sie "Regel 2 \ nRegel 1" nicht herausholen können
Leichtigkeitsrennen im Orbit
2
@Tomalak: Kommt auf deine Definition von "frustrierend" an! Sobald das OP akzeptiert, dass Regeln keine prozeduralen Funktionen sind, gibt es nicht viel zu frustrieren.
Oliver Charlesworth
Es beantwortet die Frage nicht. Es sollte Regel 2 und dann Regel 1 ausgeben. Dies ist, was der Autor erreichen möchte.
Nosbor
1
@nosbor - Das OP gibt nicht an, welche spezifische Ausgabe gewünscht wird.
Oliver Charlesworth
4

In GNU Make gibt es zwei erweiterte Funktionen, die dies tun können, obwohl sie nur unter mildernden Umständen verwendet werden sollten. Diese SO ist in Google am besten bewertet.

Regelvoraussetzungen werden eher empfohlen, aber manchmal benötigen Sie eine Nachanforderung.

GNU-Anruffunktion

GNU Make Eval-Funktion

Im Wesentlichen können Sie mit Eval Ziele im laufenden Betrieb erstellen, und mit Call können Funktionen wie "Definieren" erstellt werden.

Kevinf
quelle
0

Ein einfacher Weg, dies zu tun, ist:

ifeq (a, b)
    build_target:=one
else
    build_target:=two
endif

mytarget: $(build_target)
user2071070
quelle