Hacker News new | ask | show | jobs
by rraval 2376 days ago
This... isn't even using the `make` part of Makefiles at all.

If you look at the final example, every [1] rule is marked as `.PHONY`. `make` bundles 2 capabilities: a dependency graph and an out-of-date check to rebuild files. This demonstration uses neither.

The author would be better served with a shell script and a `case` block. The advantages:

- Functions! The `check-environment` rule is really a function call in disguise.

- No 2 phase execution. The author talks about using variables like `APP`, but those are make variables with very different semantics than shell variables (which are also available inside the recipes).

[1] Yes, there's a `check-environment` "rule" that isn't marked, but it likely should be since it isn't building a file target named `check-environment`.

2 comments

I disagree. Make is more than a build system, it's also an automation tool. It gives you a fairly flexible format for managing different tasks with shared variables and autocompletion and more.

You can do it with a bunch of shell scripts too but I prefer having everything in a single file.

> Make is more than a build system, it's also an automation tool.

I agree with that, but I don't believe that the GP said otherwise. Make is an automation tool, but what it aims to automate is exactly dependency tracking. Other features, like actually performing the tasks, are off-loaded to the shell and other tools.

> It gives you a fairly flexible format for managing different tasks with shared variables and autocompletion and more.

You could as well be describing a shell here, which already have these features.

> You can do it with a bunch of shell scripts too but I prefer having everything in a single file.

What stops you from using a single shell script? Likewise, you have a Makefile delegate tasks to other Makefiles (as the author has done for the build-tokenizer rule).

Anyway, you should of course use them in any manner that suits you, but for a guide on "using Makefiles for Go" I think it's an oversight to ignore the main selling point of make by just using it as you would a switched shell script with no dependency tracking. It just introduces another syntax and new caveats to the problem, adding little value.

I think people kind of talk past each other in these discussions because there isn't a standardised vocabulary. I would call that kind of anaemic Makefile a "task runner" rather than a build system. And yes indeed, a task runner can easily be written as a single POSIX/Bash shellscript that has conditional behaviour based on its first argument. The `case ... in ...` statement in shell is rather nice!
I'm more confused as to why use .PHONY in so many places. Golang builds from .go files whos modification times are changed when written to, same as .c and .cpp files, so make is able to know when the go compiler needs to be called, or not.
Make absolutely does not understand all the scenarios for rebuild, and go build has much more complicated logic than that. For one, it's content-based not mtime-based. For another, a command needs rebuild if any of its dependencies change, not just its own source file. Make absolutely does not get that right for Go.