Make

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/make.html
https://man.openbsd.org/make

For Posix, you have to have the special target “.POSIX:” on the first non-comment line. (Special targets, beginning with a dot and containing uppercase letters, do not count as the default target even if they are first.)

Variable assignments may have spaces around the equals sign, but Posix points out that excluding the space before the equals sign avoids the ambiguity of an “include” directive versus assigning to a variable called “include”.

Don’t include comments on macro definition lines, because trailing space before the comment is usually included in the definition value.

Target names can only have ASCII alphanumeric, underscore (_), and full stop (.) characters. Therefore slashes (/), hyphens (-), and other punctuation aren’t allowed in targets written in makefiles.

Terminology

prerequisite
File that target depends on
rule
Target(s), prerequisites (if any), and commands to generate the target (if any)
inference rule
One target name has a dot (.) and no forward slash (/)
target rule
May have multiple targets
target
Generated file, or similar syntax (e.g. “.POSIX”, “.o.c”). The first target other than “special” targets and inference rules is the default target.
dependency line
associates targets and prerequisites

Line continuation

In general, any whitespace before the backslash and newline is collapsed into a single space.

By Posix, an escaped newline in a command should be retained, and the one “command line” will have two (or more) lines. Only the initial tab (if any) is removed.

BSD Make replaces the escaped newline and all leading whitespace with a single space, so the shell does not receive a backslash (\) nor newline, and a shell word cannot be continued across two makefile lines.

Avoid comments embedded in continued command lines.

Pattern macro expansions

Accepted as a future Posix Make feature: http://austingroupbugs.net/view.php?id=519.

$(name:a%b=c%d)

Gnu and BSD Make both seem to support this.

Pattern rules (metarules)

Proposed for Posix (http://austingroupbugs.net/view.php?id=513).

dest/%.o: src/%.c
→ $(CC) [. . .] $< -o $@

If the pattern has a prefix, it should end with a slash (. . ./%. . .) for portable behaviour.

If a target matches multiple patterns, the first matching pattern should be the most specific, and should have a shorter stem than the other matches.

More-specific patterns, with longer prefixes and suffixes, should come before less-specific patterns, otherwise the priority varies across implementations. Handling of targets that have a slash (/) and patterns that don’t have a slash varies.

therefore these are well defined:

%.o: src/%.c # subdir/x.o → src/subdir/x.c; all good. What about /abs/x.o?
dir/x_%: y_% # what if the target filename is dir/x_subdir/s → y_subdir/s or should it not match? should parent/dir/x_s match?

but this is not well defined:

x_%: # does dir/x_s match?

$(macro) or ${macro}?

$(name:suffix=new) is allowed, and works on the suffix of each "word" after splitting by spaces and newlines

Posix Make does not specify the := notation, but does not allow colons “:” in macro names either.