Element aus einer Makefile-Variablen entfernen?

83

Ich habe ein Makefile, das mehrere andere Makefiles enthält, die wiederum alle zu einer Variablen wie dieser hinzugefügt werden:

VAR := Something SomethingElse
VAR += SomeOtherThing

(...)

Jetzt möchte ich SomethingElseaus der VARVariablen entfernen . Was setze (...)ich dafür ein?

Ich verwende GNU Make und eine GNU Make-spezifische Lösung ist in Ordnung.

Bjarke Freund-Hansen
quelle

Antworten:

113

Sie können die filter-outTextfunktion verwenden, wenn Sie GNU Make verwenden.

OTHERVAR := $(filter-out SomethingElse,$(VAR))
Matte
quelle
Und du bist sicher, ich muss verwenden =und nicht :=?
Bjarke Freund-Hansen
1
Sind beide in dem Beispiel, das ich gegeben habe, richtig? Wenn ich benutze, =erhalte ich einen Makefile-Fehler, der etwas über VAR aussagt und sich schließlich in einer unendlichen Rekursion verweist. ( VAR = $(filter-out SomethingElse,$(VAR)))
Bjarke Freund-Hansen
4
Um es zusammenzufassen, es hängt natürlich von der Verwendung ab. Aber in meinem Beispiel wäre die richtige Antwort: VAR := $(filter-out SomethingElse,$(VAR)) (Mit :=und nicht =). Vielen Dank. :)
Bjarke Freund-Hansen
13
Hinweis: Kann auch für mehrere Elemente verwendet werden. ZB : VAR := $(filter-out A B C,$(VAR)).
Prüfsumme
1
Hinweis für alle anderen, die mitkommen. filter-outfunktioniert nur bei durch Leerzeichen getrennten Wörtern. Wenn Sie etwas aus einer Zeichenfolge entfernen müssen, die nicht durch Wörter getrennt ist, können Sie subststattdessen verwenden filter-out. Dh: $(subst -world,,hello-world)würde das Ergebnis geben hello.
Jacob
6

Oben auf der richtigen Antwort oben:

VAR = bla1 bla2 bla3 bla4 bla5

TMPVAR := $(VAR)
VAR = $(filter-out bla3, $(TMPVAR))

all:
    @echo "VAR is: $(VAR)"

Ausgabe:
VAR ist: bla1 bla2 bla4 bla5

Beachten Sie, dass dies die gesamte "Rekursivität" unterbricht, wenn das Herausfiltern ausgeführt wird. In Ihrem Fall spielt dies jedoch möglicherweise keine Rolle.

Andreas Mikael Bank
quelle
Ist das nicht erwartetes Verhalten? Wenn Sie VAR normal definieren, setzen Sie sofort TMPVAR und erweitern so VAR an dieser Stelle. Anschließend setzen Sie VAR normal zurück, um auf eine herausgefilterte Version von TMPVAR zu verweisen. Und im All-Target verwenden Sie VAR und erweitern es damit. Ich sehe nicht, wie dies die Rekursivität bricht oder in irgendeiner Weise problematisches Verhalten ist?
Bjarke Freund-Hansen
1
Ich könnte unklar gewesen sein, was ich meinte. Stellen Sie sich vor BLA1 = bla1, Sie hätten dann VAR = $(BLA1) bla2 bla3 bla4 bla5anstelle der obigen VAR-Definition. Die Ausführung BLA1 += bla1111nach dem Herausfiltern hat keine Auswirkung auf den Wert von VAR, da die Referenz auf den Wert von $ (BLA1) verloren gegangen ist.
Andreas Mikael Bank
0

Da ich auch eine ähnliche Situation habe, möchte ich eine neue Antwort hinzufügen. In meinem Fall gab es auch Kommas in der variablen Zeichenfolge, und außerdem wollte ich das Komma und das letzte Wort entfernen:

VAR = "bla1, bla2"

In diesem Fall funktioniert das Herausfiltern nicht (auch nicht in den vorherigen Antworten, wenn keine Anführungszeichen vorhanden sind).

Meine Lösung ist zu verwenden subst:

VAR = "bla1, bla2"

TTT = , bla2
TMPVAR := $(VAR)
SUBST = $(subst $(TTT),, $(TMPVAR))
FILT = $(filter-out $(TTT), $(TMPVAR))

subst:
    @echo "subst : $(SUBST)"

filter:
    @echo "filter-out : $(FILT)"
sop
quelle