Создание разделенных запятыми списков в GNU Make
У меня есть Makefile с набором логических элементов, которые должны использоваться для управления флагами для внешнего приложения. Проблема в том, что флаг должен быть передан как строка, разделенная запятыми.
Что-то вроде этого (неработающий псевдокод):
WITH_LIST = ""
WITHOUT_LIST = ""
ifeq ($(BOOL_A),y)
# Append A to list "WITH_LIST"
else
# Append A to list "WITHOUT_LIST"
endif
ifeq ($(BOOL_B),y)
# Append B to list "WITH_LIST"
else
# Append B to list "WITHOUT_LIST"
endif
ifeq ($(BOOL_C),y)
# Append C to list "WITH_LIST"
else
# Append C to list "WITHOUT_LIST"
endif
Теперь, предполагая BOOL_A == y, BOOL_B == n и BOOL_C == y, мне нужно запустить следующую команду:
./app --with=A,C --with-out=B
Как я могу сгенерировать эту строку с помощью Gnu Make?
Ответы
Ответ 1
Сначала вы создаете два разделенных пробелами списка, используя ваш метод или титон.
Затем вы используете небольшой трюк в конце раздел 6.2 руководства GNU, чтобы создать переменную, содержащую одно пространство, и одну запятую, Затем вы можете использовать их в $(subst ...)
для изменения двух списков в разделенных запятой.
PARTS := A B C
BOOL_A := y
BOOL_B := n
BOOL_C := y
WITH_LIST := $(foreach part, $(PARTS), $(if $(filter y, $(BOOL_$(part))), $(part)))
WITHOUT_LIST := $(filter-out $(WITH_LIST), $(PARTS))
null :=
space := $(null) #
comma := ,
WITH_LIST := $(subst $(space),$(comma),$(strip $(WITH_LIST)))
WITHOUT_LIST := $(subst $(space),$(comma),$(strip $(WITHOUT_LIST)))
all:
./app --with=$(WITH_LIST) --with-out=$(WITHOUT_LIST)
Ответ 2
Конструкция типа
OPTIONS+=$(if $(filter y,$(BOOL_A)),--with=A,--with-out=A)
должен работать.
Изменить: Извините, не учтено необходимое сопоставление.
PARTS=A B C
YESSES=$(foreach i,$(PARTS),$(if $(filter y,$(BOOL_$(i))),$(i)))
all:
echo with=$(shell echo $(YESSES) | tr ' ' ',')
Идея состоит в том, чтобы проверить каждую возможную часть X, задана ли она да и вставить ее в список, если она да. Этот список разделен пробелами и трудно компилируется с помощью make, но это легко сделать в оболочке.
Ответ 3
Или просто используйте sed
: уродливый (и непроверенный), но простой
WITH_LIST = $(shell echo A$(BOOL_A) B$(BOOL_B) C$(BOOL_C) | sed -e 's/[ABC][^yABC]*//g' -e 's/y//g' -e 's/ /,/g')
WITHOUT_LIST = $(shell echo A$(BOOL_A) B$(BOOL_B) C$(BOOL_C) | sed -e 's/[ABC]y[^ABC]*//g' -e 's/[^ABC ]//g' -e 's/ /,/g')