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.
In the manual: The eval function is very special: it allows you to define new makefile constructs that are not constant; which are the result of evaluating other variables and functions. The argument to the eval function is expanded, then the results of that expansion are parsed as makefile syntax.
$(shell) $(shell) is a special function in gmake that runs an external command and captures the output for use in the makefile. For example, you could get the current working directory like this: CWD=$(shell pwd) all: @echo This makefile lives in $(CWD).
And in your scenario, $MAKE is used in commands part (recipe) of makefile. It means whenever there is a change in dependency, make executes the command make --no-print-directory post-build in whichever directory you are on.
The ifeq directive begins the conditional, and specifies the condition. It contains two arguments, separated by a comma and surrounded by parentheses. Variable substitution is performed on both arguments and then they are compared.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With