theicfire / makefiletutorial

Learn make by example

Home Page:http://makefiletutorial.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Comment error in the cookbook.

Anthony6075 opened this issue · comments

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.

Thanks for the detailed description! Fixed.