Цепные строковые подстановки в gmake - PullRequest
0 голосов
/ 11 января 2019

В GNU make я хотел бы выполнить несколько строковых подстановок для двоичного текста, содержащего несколько «заполнителей», например ::

MYTEXT:= blabla _FIRST_PLACEHOLDER_ blabla _SECOND_PLACEHOLDER_whateverblabla_THIRD_PLACEHOLDER_blablabla

Итак, я хотел бы заменить «заполнители» значениями следующим образом:

_FIRST_PLACEHOLDER_ => FIRST_VAL
_SECOND_PLACEHOLDER_ => SECOND_VAL
_THIRD_PLACEHOLDER_ => THIRD_VAL
...

Ниже показан отвратительный способ получить желаемый результат:

$(subst _FIRST_PLACEHOLDER_,FIRST_VAL, $(subst _SECOND_PLACEHOLDER_,SECOND_VAL, $(subst _THIRD_PLACEHOLDER_,THIRD_VAL, $(MYTEXT))))

Решение было бы простым найти за пределами мира make, но есть ли лучший способ, чем описанный выше, выполнить такую ​​рекурсивную замену, оставаясь в рамках make? Я попытался использовать $ (foreach), но это просто объединяет результат каждой подстановки, примененной один раз к исходному $(MYTEXT).

1 Ответ

0 голосов
/ 12 января 2019

Итеративное решение

Это решение требует перезаписи переменных _p и _x.

# -*- gnu-make -*-
ORIGINAL         := 123__PLACE_HOLDER__1567__PLACE_HOLDER__2890
REPLACEMENT_LIST :=       \
    __PLACE_HOLDER__1=ABC \
    __PLACE_HOLDER__2=DEF \

_replace1 = $(eval _x := $(subst $(word 1,$(1)),$(word 2,$(1)),$(_x)))
replace   = $(strip \
    $(eval _x := $(strip $(2))) \
    $(foreach _p,$(strip $(1)),$(call _replace1,$(subst =, ,$(_p)))) \
    $(_x) \
    $(eval _x :=) \
)

$(info ORIGINAL:    '$(ORIGINAL)')
$(info REPLACEMENT: '$(call replace,$(REPLACEMENT_LIST),$(ORIGINAL))')

.PHONY: all
all:

Пример выполнения:

$ make 
ORIGINAL:    '123__PLACE_HOLDER__1567__PLACE_HOLDER__2890'
REPLACEMENT: '123ABC567DEF890'
make: Nothing to be done for 'all'.

Рекурсивное решение

Преимущество этого решения состоит в том, что он не изменяет никакие переменные.

_replace2 = $(subst $(word 1,$(1)),$(word 2,$(1)),$(2))
_replace1 = $(call replace,$(2),$(call _replace2,$(subst =, ,$(1)),$(3)))
replace   = $(if $(1),$(call _replace1,$(firstword $(1)),$(wordlist 2,1000000,$(1)),$(2)),$(2))

или

_replace1 = $(subst $(word 1,$(1)),$(word 2,$(1)),$(2))
replace   = $(if $(1),$(call replace,$(wordlist 2,1000000,$(1)),$(call _replace1,$(subst =, ,$(firstword $(1))),$(2))),$(2))
...