Usunąć element ze zmiennej Makefile?

84

Mam plik makefile, który zawiera kilka innych plików makefile, które z kolei dodają do zmiennej takiej jak ta:

VAR := Something SomethingElse
VAR += SomeOtherThing

(...)

Teraz chcę usunąć SomethingElseze VARzmiennej. Co mam zamiast tego (...)zrobić?

Używam GNU Make i rozwiązanie specyficzne dla GNU Make będzie w porządku.

Bjarke Freund-Hansen
źródło

Odpowiedzi:

114

Możesz użyć filter-outfunkcji tekstowej, jeśli używasz GNU Make.

OTHERVAR := $(filter-out SomethingElse,$(VAR))
Mata
źródło
I jesteś pewien, że muszę użyć, =a nie :=?
Bjarke Freund-Hansen
1
Czy oba są poprawne w podanym przeze mnie przykładzie? Jeśli używam =, otrzymuję błąd makefile, który mówi coś o VAR ostatecznie odnosząc się do nieskończonej rekurencji. ( VAR = $(filter-out SomethingElse,$(VAR)))
Bjarke Freund-Hansen
4
Podsumowując, przyczyna zależy od zastosowania. Ale w moim przykładzie poprawna odpowiedź brzmiałaby: VAR := $(filter-out SomethingElse,$(VAR)) (Z :=i nie =). Dzięki. :)
Bjarke Freund-Hansen
13
Uwaga: można również użyć do wielu przedmiotów. Np VAR := $(filter-out A B C,$(VAR)). : .
suma kontrolna
1
Uwaga dla wszystkich, którzy przyjdą. filter-outdziała tylko ze słowami oddzielonymi spacjami. Jeśli chcesz usunąć coś z łańcucha, który nie jest oddzielony słowami, możesz użyć substzamiast filter-out. To znaczy: $(subst -world,,hello-world)dałoby wynik hello.
Jacob
7

Oprócz poprawnej odpowiedzi powyżej:

VAR = bla1 bla2 bla3 bla4 bla5

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

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

Wyjście:
VAR to: bla1 bla2 bla4 bla5

Zwróć uwagę, że powoduje to przerwanie całej „rekurencyjności” podczas wykonywania filtrowania, ale w twoim przypadku może to nie mieć znaczenia.

Andreas Mikael Bank
źródło
Czy to nie jest oczekiwane zachowanie? Najpierw definiujesz VAR normalnie, następnie od razu ustawiasz TMPVAR, rozszerzając w tym miejscu wartość VAR. Następnie normalnie zresetujesz VAR, aby odsyłał do odfiltrowanej wersji TMPVAR. A we wszystkim celuj w VAR użytkowania, a tym samym rozszerzaj go. Nie widzę, jak to łamie rekursywność lub jest w jakikolwiek sposób problematyczne?
Bjarke Freund-Hansen
1
Mogłem nie wiedzieć, o co mi chodzi. Wyobraź sobie BLA1 = bla1, wtedy VAR = $(BLA1) bla2 bla3 bla4 bla5zamiast definicja VAR powyżej. Wykonywanie BLA1 += bla1111po odfiltrowaniu nie będzie miało wpływu na wartość VAR, ponieważ utraci odniesienie do wartości $ (BLA1).
Andreas Mikael Bank
0

Ponieważ ja też mam podobną sytuację, chcę dodać nową odpowiedź. W moim przypadku do zmiennej string były też przecinki, a ponadto chciałem usunąć przecinek i ostatnie słowo:

VAR = "bla1, bla2"

W tym przypadku filtrowanie nie działa (nawet w poprzednich odpowiedziach, gdy nie ma cudzysłowów)

Moje rozwiązanie to użycie 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)"
maczanka
źródło