This doesn't seem like a well thought out introduction. There's quite a lot of randomness. For example, the first makefile says:
This makefile will always run. The default target is some_binary,
because it is first.
some_binary:
echo "nothing"
Actually, it's not true that that will always echo nothing because some_binary isn't declared as phony and so if some_binary exists on the CWD echo "nothing" will not happen.
Also, the language here is weird. The tutorial talks about makefiles running and targets calling targets.
4.8 states:
1) We do not use *.o, because that is just the string *.o,
which might be useful in the commands, but is only one
target and does not expand."
That's not true. Consider the following
*.foo: ; @echo $@
If there are any files in the CWD that match *.foo then it is expanded and rules created for each file.
I appreciate what the person is trying to do, just quickly jot down some notes for new people.
For the first concern, phony is mentioned a bit later, likely did not want to start-off with added complexity for the reader.
For the second point, but then bar.foo and baz.foo are already there and would be up to date, so what's the point in that? Most cases it's not what you want, that note is pointing-out a common gotcha.
So though precisely you are totally correct, it's not what the author was going for.
Some opinion of mine now. I do not like GNU make document linked. It goes into too much detail and then close to the end is just a short warnings about how so much of the above was GNU specific. I prefer the BSD make man page, but obviously that is not a good starting point for someone new to make. I recommend the book "Managing Projects with make" personally.
This is a good compromise between abstract and concrete knowledge.
Most manuals either cover only some special cases and leave you alone to find out what's more. Then they cover only the whole syntax as BNF, or a whole API doc, or something. But nothing in between, drawing the connection between practical usage and abstract description of what's all possible.
Why? It's standardized the project (thus facilitate use by others), manage dependencies, and provide a simple way to manage a project. Also, many other languages have already something that does that (gem, python package, jar) and not C.
2. It regularly breaks compatibility through regressions or feature removal, thus having to pin a specific version of autotools to a project to build it.
1. For someone that installed Linux From Scratch, I can say that it's really nice that most of softwares use that. It's maybe not standardized like POSIX or other systems, but it's some kind of standardized by default.
3. It does not download the dependencies but it can verify that your system has all it needs to build the project.
I don't have much experience with make and autotools so feel free to disagree with what I said and say why.
Define dependencies. Autoconf checks for api 'usability' such as 'hey in 1981 some unused api since 1982 had a bug in foobar do we have that bug?'. It also just spits out shell scripts in the end but that are bloated beyond belief.
Things like this are good for a basis of understanding. But if you need help figuring how to tie stuff all together, the suckless[0] guys are masters of brevity.
The tutorial is allright but I would prefer for it not to exist (or not need to exist) because Make is so arcane and touchy that it should've been replaced a long long time ago. I really hate Make. There are better alternatives out there (e.g. SCons)
People hate Make because it doesn't define any conventions for its use. You can use it to do anything, but it does very little by default. This gives you a tremendous amount of freedom to declare exactly what it means to "build" an arbitrary component, but it also means you have to declare it yourself.
Many of the modern build tools move away from that. CMake, for instance, drops the ability to build arbitrary assemblages of files and focuses almost exclusively on giving you a nicely-constrained language for defining compilation targets and allowing you to support many different compilers.
Maven, Ivy, and it's ilk focus on declaring run-time dependencies and on some concept of a "build l lifecycle."
Having used all these systems, I find that there are things I need to do when running a build that I can easily do in Make, but which are encumbered significantly by other tools.
Make's syntax sucks, and it expects you to know a bunch of arcane stuff about how your project is built, but in exchange you get the ability to build literally anything.
Better is very much in the eye of the beholder. I dislike most build tools, SCons included. I've found them all to be of varying degrees of meh to terrible.
But since Make is in use in so so many projects having good tutorials and material available is valuably to anyone who ends up needing to contribute to such an (open source) project.
I understand that people need resources to understand the Makefiles of existing projects, but I fear that tutorials might encourage people to use Make in new projects. Yes, I really want to extinguish Make. Other build tools are also "bad" but Make deserves a special place in hell.
Been using Make for decades, I don't see the problem. It works sufficiently well to be in use in a lot of my projects as a comfortable and productive environment. As with all 'tool X must die' conversations, one must always end with the only relevant conclusion that should be made: ymmv.
It's true, but it has the benefit that your makefiles are now complient with every other cmake users makefiles, and not special snowflakes. That makes it more likely that someone has already had your problem and posted a turnkey solution.
I was one of the folks that mentioned tup in that link. Allow me to take a moment and mention my support for it again. It is an incredibly simple build-system with a ton of advantages over make et al.
I use tup widely across my personal projects and I must say, it has dramatically simplified my dev life.
Oh man I wish I could love tup. That syntax is great, it cleans all by itself, and figures-out dependencies all by it self - even the source file often! But it was a total no-go when I tried on FreeBSD. Basically it does those awesome things by leveraging FUSE and makes all sorts of assumptions about how FUSE operates which are not true on FreeBSD. More over those assumptions would need to change as some of them are bugs and others are honest to goodness differences for good reason. So it boils down to, tup is just too clever sadly.
That's such a bummer! I'm sorry to hear that it doesn't work for FreeBSD! You should consider opening a bug about it; the devs seem pretty open and responsive. Maybe they'll get it fixed for you!
It is still better to have one kind-of-bad build tool, than hundreds of build tools that are slightly better. Every time you have to install new software and something goes wrong, you'd have to learn a new build tool!
https://www.gnu.org/software/make/manual/
This doesn't seem like a well thought out introduction. There's quite a lot of randomness. For example, the first makefile says:
Actually, it's not true that that will always echo nothing because some_binary isn't declared as phony and so if some_binary exists on the CWD echo "nothing" will not happen.Also, the language here is weird. The tutorial talks about makefiles running and targets calling targets.
4.8 states:
That's not true. Consider the following If there are any files in the CWD that match *.foo then it is expanded and rules created for each file.