Live data from Hacker News

Using Makefile(s) for Go

danishpraka.sh

51–60 of 104 posts

Re: Using Makefile(s) for Go

#51
post #10
post #3

I've seen a lot of developers, especially developers with C backgrounds, reach for Makefiles when approaching Go development, and I think it's a harmful practice. So, I'd like to offer a respectful but firm rebuttal to this article. :) I dislike using make(1) with Go for two reasons. The first is that make was developed for building C projects, and therefore is oriented around that task. Building C projects is a lot…

I think there’s a distinction to be drawn here between a couple use cases for Makefiles (specifically for building software): * Makefiles can act as shortcuts for common existing functionality of the build toolchain * Makefiles can add new functionality that is not part of the build toolchain * Makefiles can add new functionality that replicates existing functionality in the build toolchain An example of the first ca…

I use make for the first case a lot. If there was a tool for running bash functions from a predefined file just as easy and ubiquitous as make, I would switch in a heartbeat.

Re: Using Makefile(s) for Go

#52
post #36
post #17

Earlier quoted context omitted.

Why do people on this website use "make(1)" instead of "make" in writing? And I know it's in the man pages but what is this number even for?

As the previous replies stated, the "1" is the section of the manual the page you are requesting occurs in. If you have trouble remembering what the sections are, I recommend running "man man" in the terminal. The section numbers are explained near the beginning.

Irix (IIRC) used to respond to the argumentless command "man" with the supremely snotty "appropo what", which made me laugh out loud the first time I saw it

Re: Using Makefile(s) for Go

#53
post #11

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…

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.

Re: Using Makefile(s) for Go

#54
post #33

Earlier quoted context omitted.

I am generally able to keep things so that during development, "go build" works. This is great for quick turnarounds during dev and early testing. Since I consider it necessary for production executables to explain where they came from, and I therefore embed the Git commit hash and other such information into the executable, it is simply a non-starter to ship my production executables coming from a bare "go build". S…

Let me stress that packaging software and deploying software has two different concerns. Your script might work wonders for deployments and shipping it to your infrastructure. But it might be completely broken if anyone want to package up the code and redistribute the software in a linux distribution.

Absolutely it would be. But I'd be in a lot of trouble if the software in question showed up in a Linux distro. :)

Re: Using Makefile(s) for Go

#55
post #10

Earlier quoted context omitted.

I think there’s a distinction to be drawn here between a couple use cases for Makefiles (specifically for building software): * Makefiles can act as shortcuts for common existing functionality of the build toolchain * Makefiles can add new functionality that is not part of the build toolchain * Makefiles can add new functionality that replicates existing functionality in the build toolchain An example of the first ca…

I use make for the first case a lot. If there was a tool for running bash functions from a predefined file just as easy and ubiquitous as make, I would switch in a heartbeat.

Put "$@" at the bottom of the file. Then type ./filename function.

You can extend that to a fancier function dispatcher, argument checker, etc, if you want.

Re: Using Makefile(s) for Go

#56

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…

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

Re: Using Makefile(s) for Go

#57

rm -rf ${APP} is a code smell. If ${APP} is not a directory, -r should not be in this command. At best it is possibly confusing, and at worst if somehow ${APP} accidentally becomes a directory it will just remove it and you will have no idea that it was a directory, whereas just rm -f ${APP} will fail because it can't unlink a directory. Build success is an important factor in a CI/CD pipeline, therefore builds shoul…

I find that complexity of a Makefile isn't necessarily a function of its size. Ideally, one should be able to reason about each target individually, specifying its dependencies without consideration for how they are generated, whether they already exist etc. In such an ideal situation, it doesn't matter how large the Makefile is. Maintenance problems IMO happen when you can't trust tasks to fully specify their dependencies or that task commands only generate the target output.

Over all I agree with your argument, though.

Re: Using Makefile(s) for Go

#58
post #29

Earlier quoted context omitted.

either the parent edited his comment or you haven't read it, you're quoting the only sentence that hasn't got a reason in it.

None of those reasons explain why a Makefile is any better than a scripting language.

Here's 3 reasons:

- Makefiles are a de-facto standard. People know them and those who don't can read how they work in 2000 tutorials. They shouldn't have to read your (and everybody's) custom (and different) script to build a project they've downloaded.

- Makefiles are specialised to the tasks of building, running tests, etc. A scripting language is general purpose. As such, it encourages adding all kinds of crap, from overcomplicated steps, to security issues.

- Makefile just needs make which is part of the core set for any distro and works fine on Mac and Windows (WSL or elsewhere) as well. Users shouldn't have to install a scripting language (or even a specific version of one) just to build a project.

Re: Using Makefile(s) for Go

#59
post #55

Earlier quoted context omitted.

I use make for the first case a lot. If there was a tool for running bash functions from a predefined file just as easy and ubiquitous as make, I would switch in a heartbeat.

Put "$@" at the bottom of the file. Then type ./filename function. You can extend that to a fancier function dispatcher, argument checker, etc, if you want.

Well technically simple to do, that misses the point.

That is neither ubiquitous, nor (as a result), trivial for a newcomer to understand.

If I clone a repo and see a makefile, I know what to do.

If I clone a repo and see './hack.sh' or './runme' or './do' or whatever you chose to call it, I have no clue whether I should invoke it or not.

There are few alternatives to make that have the same level of mindshare, and thus the same ease of use for a given newcomer to grok what to do.

Most alternatives are language specific (e.g. "rake" in rails did a good job of building programmer expectations that you use 'rake ...' to do various common tasks).

Re: Using Makefile(s) for Go

#60
post #59
post #55

Earlier quoted context omitted.

Put "$@" at the bottom of the file. Then type ./filename function. You can extend that to a fancier function dispatcher, argument checker, etc, if you want.

Well technically simple to do, that misses the point. That is neither ubiquitous, nor (as a result), trivial for a newcomer to understand. If I clone a repo and see a makefile, I know what to do. If I clone a repo and see './hack.sh' or './runme' or './do' or whatever you chose to call it, I have no clue whether I should invoke it or not. There are few alternatives to make that have the same level of mindshare, and t…

If you name it "configure" then most people will run it; you can put the instructions there.
Post reply on HN