Warum funktioniert patsubst nicht mehr, wenn die sekundäre Erweiterung von $$ * verwendet wird?

8

Hier ist ein Beispiel aus dem GNU Make-Handbuch-Abschnitt über die sekundäre Erweiterung (etwas vereinfacht):

%Vor%

Das funktioniert großartig; Es baut bar.o und baz.o :

%Vor%

Aber wenn ich dieses Beispiel nur geringfügig zwicke, funktioniert patsubst nicht mehr:

%Vor%

Er erstellt nicht mehr bar.o und baz.o und verwendet stattdessen die Dateien *.c direkt als Voraussetzung!

%Vor%

Bitte beachten Sie, dass der $$($$*_SRCS) -Teil eindeutig funktioniert, was sich in der Tatsache widerspiegelt, dass foo_SRCS gefunden und als Voraussetzung verwendet wurde. Aber aus irgendeinem Grund ist der patsubst Teil ein No-Op! Anstatt %.c durch %.o zu ersetzen, wird nur foo_SRCS direkt verwendet.

Was ist hier los? Wie kann ich mein Beispiel zur Arbeit bringen?

BEARBEITEN: Ich hatte eine Theorie, dass die % -Zeichen innerhalb der patsubst früh ausgewertet wurden, indem die stem match (foo) verwendet wurde, so dass der patsubst selbst in etwa so aussah:

%Vor%

Um diese Theorie zu testen, habe ich eine Datei namens foo.c zu foo_SRCS :

hinzugefügt %Vor%

Das führte zu etwas noch Seltsamerem:

%Vor%     
Josh Haberman 31.08.2014, 06:44
quelle

2 Antworten

4

Die Prozentzeichen werden von make als Übereinstimmungen mit dem Platzhalter im Stamm gelesen und durch die Stielübereinstimmung ersetzt. Wenn Sie die Ausgabe make -p für Ihr Beispiel überprüfen, sehen Sie, dass die analysierte Zielzeile wie folgt aussieht:

%Vor%

Was, was die Marke betrifft, ist nur ein wirklich seltsamer Satz von gemusterten Zielen (oder so ähnlich).

Wenn Sie die prozentualen Zeichen aus make parsing auf ähnliche Weise umgehen wie Sie die $ aus der make-Auswertung entfernen, erhalten Sie, was Sie arbeiten möchten:

%Vor%

Für weitere Informationen Ersatzreferenzen (dh $(foo_SRCS:.c=.o) ) können Wird für Transformationen wie diese anstelle des längeren Aufrufs von patsubst verwendet. In diesem Fall funktioniert es zwar in diesem Szenario mit einem ähnlichen Escapen von : (über c := : ), aber es scheint nicht die einzige Voraussetzung für das Ziel zu sein (mit make gibt es einen Makefile:23: *** commands commence before first target. Stop. Fehler, dass I nicht ganz verstehen) zumindest mit GNU Make 3.81.

    
Etan Reisner 31.08.2014, 13:18
quelle
4

Sie mischen drei Funktionen, die nicht gut zusammenpassen: sekundäre Erweiterung , Musterregeln , und patsubst . Ich werde versuchen, im Detail zu erklären, was make bei der Auswertung Ihres Codes (AFAIUI) macht.

Beginnen wir mit Ihrem ersten Makefile:

%Vor%

Lesephase. Alle Dollarzeichen sind ausgeblendet, daher findet hier keine Bewertung statt. Make gibt die folgende Regel in ihre Datenbank ein:

%Vor%

Musterersetzung. Was making betrifft, ist dies nur eine weitere Musterregel mit Ziel %.a und zwei Voraussetzungen, die durch Leerzeichen getrennt sind: $(patsubst und %.c,%.o,$($*_SRCS)) .

foo.a stimmt mit dem Zielmuster überein, und daher wird das erste % in jeder Voraussetzung durch foo ersetzt. Die Regel wird:

%Vor%

Aktualisierungsphase des Ziels. Wenn Sie die sekundäre Erweiterung angefordert haben, wird das Muster in der Zielaktualisierungsphase erneut ausgewertet:

%Vor%

Und so enden Sie mit der Ausführung des Befehls

%Vor%

Und was ist mit foo.c? Wenn Sie foo.c zu foo_SRCS hinzufügen, sieht die sekundäre Erweiterung wie folgt aus:

%Vor%

Und die Regel schlägt fehl, weil make nicht weiß, wie man %.o erstellt.

Workaround. Sie können die Zeichen % mit einem Backslash umgehen:

%Vor%     
pdw 09.04.2015 23:22
quelle

Tags und Links