I'm compiling a large list of files in a Makefile.
my.list : ${deps}
rm -f $@
$(foreach F,$^,echo "${F}" >> $@;)
but ${deps} can be large and the generated command-line could be too large for one SHELL call. Is it possible to replace ';'
by a newline '\n' ?
You can define a variable that expands to a newline like so:
define NEWLINE
endef
Now you can use $(NEWLINE)
to expand to a newline.
This won't change anything though, the foreach
will still generate a single command with embedded newlines between the statements, rather than a single command with ;
between the statements.
As already mentioned in Jonathan Wakely's answer, the straightforward answer is
define newline
endef
Interestingly enough, for all chars except newline there is an easier way to get non-printable characters into variables with some help from the shell, e.g.:
tab := $(shell printf '\011')
It won't work here, though, because the builtin shell function replaces all newlines by spaces.
The version above is still a bit fragile though, in particular when combining with automake which will silently remove the second consecutive newline from the input file, turning newline
into an empty variable. To force it to keep the newline, we can extend the snippet:
blank :=
define newline
$(blank)
endef
Finally, to actually get a separate shell command for each dependency, you need to run the generated string through eval
:
define generate-rule =
my.list : $(1)
rm -f $$@
$(foreach F,$$^,$(newline)$(tab)echo "${F}" >> $@)
endef
$(eval $(call generate-rule,$(deps)))
Possibly the most straight-forward answer is to use:
@printf "\n"
You can also use this, as I commonly do, to show a description when each new make target executes. An example target:
.PHONY: clean-version
clean-version: ## Reset version back to committed version number
@printf "\n## Reset version to last committed version number ##\n\n"; \
$(GIT) checkout $(VERSION_FILE);
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