Very great tutorial!
But I'd like to point out a small error in comments of the cookbook.
In line 8 and line 9, you said:
# Note the single quotes around the * expressions. Make will incorrectly expand these otherwise.
SRCS := $(shell find $(SRC_DIRS) -name '*.cpp' -or -name '*.c' -or -name '*.s')
Of course you need the single quotes. However, without them, it is not Make which expands the wildcard *
, and actually it is your shell.
In GNU make docs, 4.4 Using Wildcard Characters in File Names said:
Wildcard expansion is performed by make automatically in targets and in prerequisites. In recipes, the shell is responsible for wildcard expansion. In other contexts, wildcard expansion happens only if you request it explicitly with the wildcard function.
and 4.4.3 The Function wildcard said:
But wildcard expansion does not normally take place when a variable is set, or inside the arguments of a function.
As part of argument of function shell
, GNU make will not expand *
, which is passed to your shell literally.
So why is there single quotes necessary? The reasons are as follows.
Before shell invokes command find
, it will execute filename expansion. I use bash for example here.
In GNU bash manual, 3.5.8 Filename Expansion said:
Bash scans each word for the characters ‘*’, ‘?’, and ‘[’. If one of these characters appears, and is not quoted, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of filenames matching the pattern (see Pattern Matching).
Then *.cpp
will expand to c++ source files in current working directory, which is undesirable because command find
would not get the asterisk. Therefore, you need single quotes to prevent shell from filename expansion.