BSD make and built-in rules
──────────────────────────────────────────────────────────────────────
I just realized a specificity of BSD makefile: there is no built-in
rule to link a program for which you specify the object
prerequesties.

Take the following makefile, BSD make will automatically compile it
as expected:

       $ more -e makefile
       pgm: pgm.c

       $ make
       cc -O2 -pipe    -o pgm pgm.c

Now try to make it generate an object file (the second line could be
infered by make, but I added it for clarity):

       $ more -e makefile
       pgm: pgm.o
       pgm.o: pgm.c

       $ make
       cc -O2 -pipe   -c pgm.c

The target "pgm" is NOT generated !

This is actually what the POSIX spec for make specifies [0].
There is no built-in rule to build a target from a .o file, only
from a .c file. And if you think about it, it make sense, because a
single suffix rule to turn a .o into a binary would only work if you
binary doesn't link multiple objects. so you'd better avoid creating
the object file in this case, and use the .c rule…

It means that when a binary must be built out of multiple object
files, you have to specify the target rule:

       pgm: pgm.o util.o
               $(CC) $(LDFLAGS) -o $@ pgm.o util.o

I guess I'll be rewriting makefiles in the next few days…
--
~wgs

[0]: https://pubs.opengroup.org/onlinepubs/009695399/utilities/make.html#tag_04_84_13_08

20200909.1844