Удалить элемент из переменной Makefile?

84

У меня есть make-файл, который включает несколько других make-файлов, которые, в свою очередь, добавляют к такой переменной:

VAR := Something SomethingElse
VAR += SomeOtherThing

(...)

Теперь я хочу удалить SomethingElseиз VARпеременной. Что я для этого положил (...)?

Я использую GNU Make, и мне подойдет конкретное решение GNU Make.

Бьярке Фройнд-Хансен
источник

Ответы:

114

Вы можете использовать filter-outтекстовую функцию, если используете GNU Make.

OTHERVAR := $(filter-out SomethingElse,$(VAR))
Мат
источник
А ты уверен, что надо использовать =а нет :=?
Бьярке Фройнд-Хансен,
1
Правильны ли оба в приведенном мной примере? Если я использую, =я получаю сообщение об ошибке makefile, в котором говорится, что VAR в конечном итоге ссылается на себя в бесконечной рекурсии. ( VAR = $(filter-out SomethingElse,$(VAR)))
Бьярке Фройнд-Хансен
4
Подводя итог, это, конечно, зависит от использования. Но в моем примере правильный ответ будет: VAR := $(filter-out SomethingElse,$(VAR)):=и не =). Благодарю. :)
Бьярке Фройнд-Хансен
13
Примечание: также может использоваться на нескольких предметах. Например: VAR := $(filter-out A B C,$(VAR)).
контрольная сумма
1
Примечание для всех, кто придет. filter-outработает только со словами, разделенными пробелами. Если вам нужно удалить что-то из строки, не разделенное словами, вы можете использовать substвместо filter-out. Т.е.: $(subst -world,,hello-world)дала бы результат hello.
Джейкоб
7

В дополнение к правильному ответу выше:

VAR = bla1 bla2 bla3 bla4 bla5

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

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

Выход:
VAR: bla1 bla2 bla4 bla5

Обратите внимание, что это нарушает всю «рекурсивность» при выполнении фильтрации, но в вашем случае это может не иметь значения.

Андреас Микаэль Банк
источник
Это не ожидаемое поведение? Сначала вы определяете VAR как обычно, затем вы сразу же устанавливаете TMPVAR, расширяя VAR на этом этапе. Затем вы обычно сбрасываете VAR, чтобы ссылаться на отфильтрованную версию TMPVAR. И во всех целевых вы используете VAR и таким образом расширяете его. Я не понимаю, как это нарушает рекурсивность или каким-либо образом является проблемным поведением?
Бьярке Фройнд-Хансен
1
Возможно, я не совсем понял, что имел в виду. Представьте себе BLA1 = bla1, то VAR = $(BLA1) bla2 bla3 bla4 bla5вместо определения VAR выше. Выполнение BLA1 += bla1111после фильтрации не повлияет на значение VAR, так как оно потеряет ссылку на значение $ (BLA1).
Andreas Mikael Bank
0

Так как у меня тоже похожая ситуация, хочу добавить новый ответ. В моем случае в строке переменных также были запятые, и, более того, я хотел удалить запятую и последнее слово:

VAR = "bla1, bla2"

В этом случае фильтрация не работает (даже в предыдущих ответах, когда нет кавычек)

Мое решение - использовать 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)"
подачка
источник