A Simple Makefile Tutorial (2008)
19 points by kenballus
19 points by kenballus
Again a missed opportunity to teach POSIX make, which undergoes constant and consistent expansion. This tutorial uses GNUisms left and right, making the resulting makefile unportable.
This tutorial uses GNUisms left and right, making the resulting makefile unportable.
I understand what you're getting at there, but GNU Make is quite portable. Even in the mid-00s when I needed to use HPUX or Solaris, it was no big deal to install GNU Make on the system and update the build practices to call gmake ... instead of make ....
For the kinds of Makefiles in this tutorial, I tend to agree with you. But for those where people are really using GNU Make features (like, say, crypto++) I'd say it's worth just using it unless you specifically need a platform GNU make hasn't been ported to. It's highly portable, free software. I couldn't even name a platform where I have cared about building software in the past 25 years that it didn't run. (I've cared about many. Including but not limited to Mac, Windows, Solaris, AIX, FreeBSD, OpenBSD, NetBSD, Solaris, HP/UX, IllumOS, and various flavors of Linux.)
You raise a good point, but I meant portability in the sense that you do not rely on one single implementation. While GNU is a very reliable 'vendor', it still is one implementer. It has become more en vogue to rely on single-implementation solutions (e.g. the rust compiler), but I find this a bad state of affairs.
It's important to consider the target audience of the post. I have seen multiple professors at multiple universities completely bungle teaching make. In more advanced classes, it's considered to be something that an intro C class should cover. In intro C classes, it's an afterthought. This leads to an unfortunate situation in which most students copy-paste makefiles without understanding them.
The post could certainly be better, but I think it does a good job for the intended readership. If you're worried about GNUisms, then you're better at make than the authors are expecting, so it makes sense that some of the simplifications (e.g., omitting the discussion of POSIX make vs gmake vs bmake vs ...) are irksome.
It's worth noting, IMO, that Apple's default vendoring of make is GNU Make 3.81 (which is the final release using GPL v2, if I remember correctly). I usually find this to be a sensible default for most of my Makefiles.
POSIX make lacks a lot of things, but I do wish people would call GNU Makefiles GNUmakefile instead of Makefile. If both exist, GNU Make will prefer the GNU one, other Make implementations will ignore it. You can have a Makefile with a dummy rule that looks something like:
.PHONY all
all:
echo "This project requires GNU make"
If you try to use GNU extensions with a different Make, you'll often get a load of completely incomprehensible errors. That is not friendly.
In college, I mostly copied and pasted Makefiles from class until finding this. There are some bugs in the writing, but on the whole I think it does a great job introducing the concepts to newcomers.
Anyway, here's what I think doesn't work about this post:
Makefiles are a simple way to organize code compilation.
Missing $(CFLAGS) in Makefile 2. (EDIT: This is not true. See below.)
-I. is generally worse than just using double-quoted includes, imo.
- Missing
$(CFLAGS)in Makefile 2.
CFLAGS is typically unimportant for the link stage, which is what Makefile 2 is presenting; you would use LDFLAGS for that.
As for the compile stage (.c -> .o), POSIX make specifies that a conformant implementation must provide the following default rule:
.c.o:
$(CC) $(CFLAGS) -c $<
...which will compile any file foo.c into foo.o.
Honestly I would love to see tutorials for Makefiles that don't involve C at all. These examples don't really make any sense to me, and it implies a much stronger connection between make and C than actually exists.
I was just learning make at the time of writing this post, so take it with a grain of salt: Java without Eclipse (2013)
Thanks.
I remember reading somewhere that the main reason Ant was created was that Make was too hard to get running on Windows for Java users.
Odd, because I used make when doung Java development. Granted, that was 30 years ago with Microsoft’s make, but it worked.
What is state of the art in terms of build systems? I used handwritten Makefiles for a long time, then CMake.
At one extreme, probably something like Bazel or Buck2, which completely orchestrate the build to be deterministic and heavily rely on caching and remote execution capabilities (as in, local execution is just remote execution on localhost).
recently i skimmed over meson/ninja/bazel. got the impression they need more lines of config than a whole makefile is long. ended up using awk for scan-while-build