make syntax is newline-delimited, but $(shell ...) replaces newlines with whitespace. So what's the least ugly way to do
$(eval $(shell program-that-emits-makefile-fragment))
which doesn't work the way one might like.
make syntax is newline-delimited, but $(shell ...) replaces newlines with whitespace. So what's the least ugly way to do
$(eval $(shell program-that-emits-makefile-fragment))
which doesn't work the way one might like.
This will probably do for what you have in mind:
makefile_fragment:
program-that-emits-makefile-fragment > $@
include makefile_fragment
Is that enough? There are additional tricks you can use if you need them, such as having the rule add context around what the program produces, or piping the output through sed to glom it into one line, then parsing it out with backslashes.
The issue has already been reported to the GNU make maintainers:
http://savannah.gnu.org/bugs/?28230
It was closed with the following comment:
As Philip mentions, this is the intended/documented behavior.
I recommend using "include" rather than eval; have your script write out a file, then include that file.
ADDED: There's a workaround! Here's a sample GNUmakefile (replace 8 spaces by tabs; yes, there are two empty lines after define newline
):
define newline
endef
$(eval $(subst #,$(newline),$(shell { echo 'war:'; echo ' echo "not love?"'; echo ' echo "Give peace a chance!"'; } | tr '\n' '#')))
More generally, that's $(eval $(subst #,$(newline),$(shell myscript | tr '\n' '#')))
You have to pick a character that won't appear in the output of the script; #
seems a good candidate.
Here's a way to do it by hijacking the % substitution character, so we don't need to rely on a char that doesn't appear in the output of myscript.
define nl
enddef
$(foreach line, $(shell myscript | sed -e 's/%/\\%/' -e 's/$$/%/'), \
$(eval $(patsubst %, $(line), $(nl))))