Sometimes you find yourself needing to insert a 'special' character in a Makefile: perhaps you need a newline inside a $(error) message, or a space character in a $(subst) or a comma as the argument to a GNU Make function. Those three simple things can be frustratingly hard in GNU Make; this article takes you through simple GNU Make syntax that removes the frustration.
GNU Make's escaping rules
GNU Make's handling of 'tab' as the start of a command is a legendary language feature, but some other special characters can trip you up. GNU Make's handling of $, %, ?, *, [, ~, \, and # are all special.
Every GNU Make user is familiar with $ for starting a macro reference. It's possible to write $(macro) or ${macro} to get the value of macro and if the macro name is a single character (such as a) then the parens can be dropped and the short hand $a used.
To get a literal $ you write $$. So to define a macro containing a single $ symbol you'd write:
dollar := $$
The % character rears its ugly head in three different places: in the vpath directive, in a $(patsubst) and in a pattern or static-pattern rule.
Escaping % is not as simple as $, but it only needs to be done in the three situation above, and the same rules apply for each.
The three rules for % escaping are:
1. % can be escaped with a single \ character (i.e. \% becomes a literal %.
2. If you need to put a literal \ in front of a % (i.e. you want the \ to not escape the %) then escape it with \ (i.e. \\% becomes a literal \ followed by a % character that will be used for the pattern match).
3. Don't worry about escaping \ anywhere else in a pattern, it will be treated as literal (i.e. \hello is \hello).
?, *, [, and ] get treated specially when they appear in a filename. A Makefile that does
*.c:
@command
Will actually search for all .c files in the current directory and define a rule for each. The target (and the same applies for prerequisites and files mentioned in the include
directive) are globbed if they contain a wildcard character. The globbing characters have the same meaning as in the Bourne shell.
The ~ character is also handled specially in filenames and is expanded to the home directory of the current user.
All of those special filename characters can be escaped with a \. The following Makefile defines a rule for the file named literally *.c.
\*.c:
@command
As well as the escaping function mentioned in this section, the \ can also be used as an continuation character at the end of a line:
all: \
prerequisite \
something else
@command
The # character is used to start a comment and it can be made literal with a \ escape:
pound := \#
I just want a newline!
GNU Make does its best to insulate you from the newline character. You can't escape a newline, there's no syntax for special characters (e.g. you can't write \n), and even the $(shell) function strips newlines from the returned value.
But you can define a macro that contains a newline using the define syntax:
define newline
endef
(Note that there are two blanks lines in the definition above). With that definition $(newline) will expand to a newline and it can be used to format an error message nicely:
$(error This is an error message$(newline)with two lines)
Because of GNU Make's rather liberal macro naming






