Hacker News new | ask | show | jobs
by IHLayman 2385 days ago
I use Makefiles for Go projects all the time, but not in the way the article describes. First off, in a pre `go mod` world, if you had dependencies to check before running the build, then a Makefile was the easiest way to manage that. But even in a post `go mod` world, there are good reasons to use one that the article totally overlooks:

* Makefiles introduce a topological sort to build steps. This is the reason you use it instead of build shell scripts: it allows build steps to run in parallel, it guarantees order by dependency which is the best way to read build steps, and it makes file freshness an easy element to check for a build step, which is still needed for Go projects with multiple subpackages.

* Go projects usually have more than go files that are required in making an executable. If you run a web server and you are bundling static pages into your executable, Makefiles are the best way to handle that.

* If you are building for multiple architectures, or want to encode the git tag/branch into the executable, it is better to have that Makefile bake in the necessary options on the build step and keep it uniform across the build.

* If you write a Go file and bake that into a Docker image, I find it best to drop the image and container hashes into files so that I can get to them easily for docker exec/attach/rm/rmi commmands.

But there is one bigger reason Makefiles work for our entire team. We standardize on using Makefiles as the entrypoint for our builds. We have a polyglot environment at work so sometimes it gets confusing to figure out how to build a project. By standardizing on running 'make' we are all on the same page. Have a Javascript project to webpack? Run make and have make call yarn. Have a python wheel to construct? Run make and have make call python setup.py. You have a Java project that requires a sequence of maven commands to build? Run make and have the makefile call maven.

Is that inefficient? You bet it is. Does it make it easier to sort out what to do to build a project for the first time? Yes it does. Does it make it 100% easier for our CI/CD framework to work with multiple languages and scan for the necessary compilers and dependencies? Heck yeah.

[edited for lousy formatting]

3 comments

That was an excellent comment!

I use make for almost all my projects (regardless of language) and I have a system where "make init" sets up the environment (install packages, set up containers, and so on) and "make run" runs it and "make test" tests it.

Now I can come back to projects from 5-10 years ago and get them running with minimal effort since all the magic is in the makefile and not my in forgetful brain.

Do you have a tutorial or book you'd recommend for how to pursue this kind of workflow? I'm definitely interested as I dabble in more languages and am beginning to struggle with some of these kinds of environmental details
The GNU make documentation is the best introduction to make I know of, and a stellar example of technical writing.

https://www.gnu.org/software/make/manual/make.html

Managing Projects with GNU Make by O'Reilly is a good start. Make is much less mystifying if you get through all of its quirks. Make is not great in many ways (significant tabs are annoying, for example), but it's no SBT.
Also - Make will exist pretty much in any Unix-based environment. Any alternatives will require prerequisite installation of things.

Although, I work in a team where a lot of devs are on Windows, and they complain about it.

I'm pretty sure MacOS and most of the headless Linux distributions require you to install it (from a package manager or similar). It's not hard, but usually the alternatives aren't hard to install either.
I've never had that issue. Make existed on all Mac systems I've worked on. Perhaps it got pulled in via other tools, but recently I ran into an issue with the Make on my Mac, and only because the version out of the box is a 3.x, from 2006.
I might be mistaken about MacOS, but it definitely doesn't exist on centos, ubuntu, debian, or alpine--at least not their headless/server variants.
You can run into issues with BSD Make being provided, but needing GNU Make though. Not hard to work through, though.
> Although, I work in a team where a lot of devs are on Windows, and they complain about it.

Interesting. Is WSL somehow not up to running make compatibly?

What do Windows devs prefer instead of Make?
From my experience, clicking the "build" button (or using the equivalent keyboard shortcut) in Visual Studio.
Pain.
> This is the reason you use it instead of build shell scripts: it allows build steps to run in parallel, it guarantees order by dependency which is the best way to read build steps, and it makes file freshness an easy element to check for a build step

This is indeed true way beyond Go. Alternatives/replacements to make (rake, scons, bespoke shell scripts, whatever) make this in a range going from painfully non obvious to downright impossible.

For all its limitations and reputation for complexity, Makefiles can achieve a form of simplicity that renders this very simple, outrageously self documenting, and language independent.