Practical Makefiles, by example
nuclear.mutantstargoat.com
nuclear.mutantstargoat.com
This works because if you add a new dependency to a file, that information will only be needed for the next build - the current file will already be considered out of date seeing as it was edited to add the #include.
gcc -MD -MP foo.c -o foo.o
Will compile foo.c into foo.o, and also generate foo.d (-MD).
Foo.d will contains make style dependencies, and also a phony target for every dependency (-MP). This allows you to delete dependant files, as make considers the target of a rule that has no perquisites or commands to be up to date if said target does not exist.A good Makefile should have any rules for building object files if you're using a language like C or C++, which Make has built-in rules for. If using another language, adding a few generic rules should be enough.
Here's a Makefile template I've been using for some time. It may look complicated initially but only the first 70 or so lines are the actual beef. The rest of the Makefile is helpful rules for tooling (tags, cscope, coverage, profile) but that doesn't work too well at the moment. It also supports out-of-source-tree builds (using vpath to locate source files, object files and other outputs go under $PWD, vpath is does not work for object files).
# Disable built in suffix rules
.SUFFIXES:
# Disable builtin pattern rules
MAKEFLAGS+=-rYes they can be a bit limiting, but even if you do not want to use built-in rules it's still a good idea to use generic rules using wildcards.
This is what lots of "Makefile tutorials" get wrong, they start by writing rules to build individual object files and targets.
Even if you want to write your own build rules, you should not need more than a few good rules for building and linking your object files.
DEPS = Makefile
%.o: %.c $(DEPS)
$(CC) $(CCFLAGS) -o $@ -c $<I prefer to run `make clean` manually when necessary rather than adding a rule to rebuild everything "just in case". But I can imagine that this might be useful in some cases.
CMake falls apart when you try to do something more complicated, e.g. building a bootable kernel image which requires special handling for compiling and/or linking. I have done a bare metal project using CMake and GNU Make and the latter was a lot easier.
To name a few other platforms where using GNU Make works better: Android NDK (default Android.mk build system is GNU Make, there are CMake-based hacks for Android but they were atrocious) and doing micro controller work like Arduino (when writing C, not using the Arduino language).
To give an example where CMake works a lot better than GNU Make is cross compiling, e.g. building Windows binaries on a Linux host. All it takes is a few lines of "toolchain specs" and apt-getting the mingw toolchain. But even this falls apart when you need to build both, "host" and "target" binaries like you often need with hardware projects.
CMake is by no means perfect and GNU Make is still a very useful tool to know.
I have admittedly limited experience with make and I always seem to forget what symbol stood for what. They don't seem to be particularly intuitive mnemonics to me.
For example, one could argue that '<' for target and '>' for dependencies would be a tad clearer.
I'm not sure what the deal is with '@' though.
Consider: 1. Paul Graham recommends to "do things that don't scale". 2. Google designed Blaze when gmake started to scale badly.
Chances are, gmake plus some shell scripts and language-dependent build flows is all you really need. Worry about replacing it with something more scalable when you actually have that problem :).
Frack Windows, and frack XML :-(
CMake is now all the rage. Like krapht said, just learn CMake and be done with it.
I prefer to just use plain Makefiles, they're easier to fix and "make correct" than anything else. For me, I guess. make is weird, but more minimal than cmake. (cmake is HUGE. autotools are a lot weirder than make. considering the alternatives, I actually like make...)
This should not be interpreted as an endorsement of CMakes miserable, quarter-assed BASIC-in-almost-s-exprs language.
[0] http://www.amazon.com/Mastering-CMake-Ken-Martin/dp/19309342...