Does POSIX make not support globs in prerequisites

makeportabilityposixwildcards

I was reading the POSIX 7 Make definition, and I've noticed that prerequisites are almost always described as “files”:

The make utility examines time relationships and shall update those derived files (called targets) that have modified times earlier than the modified times of the files (called prerequisites) from which they are derived.

Does that mean that a POSIX-compliant make should interpret rules like

binary.bin: src/main.c src/1.dir/*.c src/2.dir/*.c
    $(CC) -o binary.bin src/main.c src/1.dir/*.c src/2.dir/*.c

As literally looking for files named *.c in src/1.dir/ and src/2.dir/?

Does this also mean that, when using a POSIX-compliant make, the users have to enumerate every file in a project in the makefile?

Best Answer

I don't think there's any "lean" implementation of make which implements only the features required by the POSIX spec, and which could be used to validate makefiles for POSIX compliance. The POSIX make spec is pretty poor, leaving a lot of stuff underspecified, but including dubious and useless features.

FWIW, all Unix make implementations (including GNU make, BSD make, the dmake from solaris, etc) will expand glob patterns in both the target and the prerequisites. And this dates back to the very first implementation of make from Unix v7. Quoting from the original documentation:

Other lines give information about target files. The general form of an entry is:

target1 [target2 . . .] :[:] [dependent1 . . .] [; commands] [# . . .]
[(tab) commands] [# . . .]
 . . .

Items inside brackets may be omitted. Targets and dependents are strings of letters, digits, periods, and slashes. (Shell metacharacters * and ? are expanded.)

And tested in practice:

# touch foo.bar zoo.bar

# echo 'foo: *.bar; echo "($?)"' | make -f -
echo "(zoo.bar foo.bar)"
(zoo.bar foo.bar)

# echo 'foo: [zf]oo.bar; echo "($?)"' | make -f -
echo "(zoo.bar foo.bar)"
(zoo.bar foo.bar)
Related Question