In addition to all the things that @J_H hasthe other contributorors have mentioned: the first target of a Makefile is its default target, i.e. the one that gets built if you just say make on the command line. Therefore, I always structure my Makefiles like this:
# Copyright blabla and other legal blurbs.
default: all
all: distrib run
# ...
Rationale: It makes the default target explicit and prevents you from accidentally changing it by placing another rule above it.
I also think that it is more common to have just one .PHONY instruction in a Makefile:
.PHONY: all clean run \
distrib .force_rebuild
I have also re-ordered the phony targets to what I am used to.
But there is nothing wrong with your version. Keep it, if you prefer it.
The .PHONY also tends to appear at the end of the Makefile, after the targets, not at the beginning.
But what is the purpose of the run target? If the executable image you are building is "whoa", how helpful is it to be able to say "make run" and see a message "Running program..." before your latest masterpiece breaks loose? What about just ./whoa? ;)
You can also try to have a look at the Makefiles generated by the GNU autotools. Download the latest version of the GNU coreutils (https://ftp.gnu.org/gnu/coreutils/), run ./configure to generate all Makefiles of the project.
Things to have a look at:
- See how they execute the
Makefiles recursively. - Silent vs. verbose: Run
make. That is the default, "silent" version. Then start over withmake cleanand thenmake V=1to see the verbose version. Look into theMakefileto see how it is done. - Automatic dependency generation: The compiler option
-MDautomatically creates complete dependencies for all C/C++ files asMakefilesnippets and-MPalso creates phony targets to suppress warnings if headers are moved or deleted. You can see how the dependencies insrc/.depsare created and updated insrc/Makefile.
The Makefiles generated by the GNU autotools are pretty complex but a good reference. The documentation of GNU make will help you understand them.