This is the code excerpt from ghc.mk, part of Haskell source compilation. I find it different, because the author has chosen to write one function block in a single line. Is it a common practice in writing makefiles?And I like to put echo statements in each one of the case handles for debugging, but with the current setup, I am not able to and make  interprets my echo statements as shell commands. define installLibsTo        $(call INSTALL_DIR,$2)        for i in $1; do \                case $$i in \                  *.a) \                    $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \                    $(RANLIB_CMD) $2/`basename $$i` ;; \                  *.dll) \                    $(call INSTALL_PROGRAM,$(INSTALL_OPTS),$$i,$2) ; \                    $(STRIP_CMD) $2/`basename $$i` ;; \                  *) \                  $(call INSTALL_DATA,$(INSTALL_OPTS),$$i,$2); \                  esac; \    doneendef
Switch-case block inside define keyword in a single logical line in a makefile
shell;make;newlines
The whole shell command is on a single logical line because the syntax of makefiles makes it necessary. In a makefile rule, each recipe line is executed in a separate shell instance. Before the parser gets to this point, backslash-newline sequences are removed, so a newline immediately preceded by a backslash doesn't count as a newline. This means that you can write this (I use 8 spaces to stand for a tab):target:        for x in $^; do \          somecommand $$x; \        doneand a shell command like this will be executed to build target:for x in dependency1 dependency2 dependency3; do           somecommand $x;         doneThe shell doesn't receive any newline here (which is why the ; is necessary before done).If you wrote this makefile:target:        for x in $^; do          somecommand $$x;        donethen each of for x in ; do, somecommand $x; and done would be executed in a separate shell, which wouldn't work.The installLibsTo variable that you show is a larger example with the same constraints. When it's used, it'll expand to two logical recipe lines, one that executes the command constructed by the call to the INSTALL_DIR function and one that executes the for loop.