No espírito de .ONESHELL, é possível chegar bem perto em ambientes desafiadores .ONESHELL:
define _oneshell_newline_
endef
define oneshell
@eval "$$(printf '%s\n' '$(strip \
$(subst $(_oneshell_newline_),\n, \
$(subst \,\/, \
$(subst /,//, \
$(subst ','"'"',$(1))))))' | \
sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef
Um exemplo de uso seria algo assim:
define TEST
printf '>\n%s\n' "Hello
World\n/$$$$/"
endef
all:
$(call oneshell,$(TEST))
Isso mostra a saída (assumindo pid 27801):
>
Hello
World\n/27801/
Essa abordagem permite algumas funcionalidades extras:
define oneshell
@eval "set -eux ; $$(printf '%s\n' '$(strip \
$(subst $(_oneshell_newline_),\n, \
$(subst \,\/, \
$(subst /,//, \
$(subst ','"'"',$(1))))))' | \
sed -e 's,\\n,\n,g' -e 's,\\/,\\,g' -e 's,//,/,g')"
endef
Essas opções de shell irão:
- Imprime cada comando à medida que é executado
- Saia no primeiro comando com falha
- Trate o uso de variáveis de shell indefinidas como um erro
Outras possibilidades interessantes provavelmente surgirão.
export ANNOUNCE_BODY
apenas define a variável dentro das regras - não permite fazer referência a $$ ANNOUNCE_BODY para definir outras variáveis.