Live data from Hacker News

How I stopped worrying and loved Makefiles

gagor.pro

111–120 of 144 posts

Re: How I stopped worrying and loved Makefiles

#111
post #81

One issue I don't hear mentioned often is reuse. A task runner's tasks could be arbitrarily complicated, pulling in all sorts of dependencies of their own. This is less true for the traditional compile targets make was designed for. Because the things we do in a Makefile are pretty much always project local and don't get reused, it limits how much heavy lifting these tasks are likely to do for us. Whereas if you buil…

Build a CLI / complex task as part of your project, then invoke it via make. This pattern is much more about documenting and composing steps than implementing them

Why invoke it via make when it can invoke itself? It's just another dependency that's not needed in this scenario.

Re: How I stopped worrying and loved Makefiles

#112
post #79

Earlier quoted context omitted.

But this can literally just be done in a simple shell script as well. The makefile ends up just being a redundant way to run a shell script.

> But this can literally just be done in a simple shell script as well. Only if there's no dependencies. It's unusual that GP's type of usage has no dependencies.

I build .tf files from parameters for each host in the Makefile (and script which knows the vSphere topology) for one-shot execution (it only creates the VM, it doesn’t manage the lifecycle) and also template config that needs to be done before deployment - there are plenty of dependencies

Re: How I stopped worrying and loved Makefiles

#113

Earlier quoted context omitted.

If scripts need particular arguments the make is a good place to record them. I use it quite a lot for automating deployments - if you want to Terraform up a VM: make colo1-fooserver01.vm Then if you want to run Ansible against it: make colo1-fooserver01 You don’t have remember or type all of the flags or arguments - just type make and hit tab for a list of the targets that you can build

Most shells will tab complete after `./scripts/` too. In fact that's probably more common than make completion. I think the real reason is you have it all in one file rather than multiple scripts which makes it easier to edit and maintain.

Quite - one makefile rather than dozens of scripts which all do practically the same things.

Re: How I stopped worrying and loved Makefiles

#114
post #79

Earlier quoted context omitted.

But this can literally just be done in a simple shell script as well. The makefile ends up just being a redundant way to run a shell script.

> But this can literally just be done in a simple shell script as well. Only if there's no dependencies. It's unusual that GP's type of usage has no dependencies.

When my shell scripts depend on another script ... they run the other script. Make definitely has its place, especially when dependencies get complex and parallel, but it's hardly necessary for simple cases. Once Make is needed, it's trivial to drop in and have it wrap the standalone scripts.

Re: How I stopped worrying and loved Makefiles

#115
post #106

The "Simple Makefile for Python projects" exemplifies why I dislike (ab)using make. It doesn't actually track deps properly, so venv doesn't get updated if requirements.txt changes, and nor does the dependency change tracking work properly for test target. To make it more correct you'd need bunch of .stamp files and/or globs, and even then it might be iffy. For lots of uses the simple file mtime based change/dep trac…

My team uses Make to handle the top-level scripting for a Python development project, and it works great. It was pretty easy to set up the correct dependency relationships.

Make is a powerful tool. You just have to understand how it thinks about the world, and adjust your own thinking a bit if needed.

If you just want to have tasks that depend on other tasks, you don't need stamps, phony, or anything else.

But what happens when you want to say "only rebuild my venv if requirements.txt changed"? that's a file dependency that you can reasonably express between requirements.txt and venv/bin/activate. And then all of a sudden, you're squarely in Make's wheelhouse.

Re: How I stopped worrying and loved Makefiles

#116

Earlier quoted context omitted.

Yes, that's true. But it is "on-by-default" for 95% of desktop Linux machines, with no special action needed.

Its on until you try to tab-complete a filename that is created through make but the completion script can't detect it at which point the entire bash-completion package is uninstalled.

What?

Re: How I stopped worrying and loved Makefiles

#117
post #98

Earlier quoted context omitted.

Seeing people reinvent make every 10 years is very frustrating. Just learn make!

Make is conceptually great but brings a lot of legacy baggage. You often need to set up .PHONY targets, reset .SUFFIXES, and/or set MAKEFLAGS += --no-builtin-rules. There's also dollar-symbol variables (which plague Perl and shell as well) which made lots of sense in the 1970s with teletypes but hinder readability today (what the hell was $@ again?).

Or the fact that $FOO interprets as $(F)OO without the slightest warning. And of course if you're in a script line, you probably meant $$FOO..

Make certainly has some obscure variables, but of all the basic knowledge of Make you need to learn, $@ is near the top of the list (it's "target". an @ sign looks kind of like a bullseye. If you want to see it as visiting a dependency graph, it's the dependency you're currently "at").

Re: How I stopped worrying and loved Makefiles

#118
post #98

Earlier quoted context omitted.

Make is conceptually great but brings a lot of legacy baggage. You often need to set up .PHONY targets, reset .SUFFIXES, and/or set MAKEFLAGS += --no-builtin-rules. There's also dollar-symbol variables (which plague Perl and shell as well) which made lots of sense in the 1970s with teletypes but hinder readability today (what the hell was $@ again?).

Or the fact that $FOO interprets as $(F)OO without the slightest warning. And of course if you're in a script line, you probably meant $$FOO.. Make certainly has some obscure variables, but of all the basic knowledge of Make you need to learn, $@ is near the top of the list (it's "target". an @ sign looks kind of like a bullseye. If you want to see it as visiting a dependency graph, it's the dependency you're current…

Sure, if you use make enough, you likely remember the most important dollar-symbol stuff. But $@ is "all arguments (obeying quoting)" in bash, which is nothing like what it means in make.

Re: How I stopped worrying and loved Makefiles

#119
post #59
post #50

This pattern of usage always seems like abuse. When `make` is used as a glorified front-end to `bash` scriptlets, why not use `bash` directly instead of having two-level of scripting? See: https://blog.aloni.org/posts/bash-functional-command-relay/

It is abuse, but people love ergonomics more than they love reducing dependencies

If you use Make to build, and you use Make to deploy, it's good for ergonomics, and it's good for reducing dependencies.

Certainly abuse, but hey.

Re: How I stopped worrying and loved Makefiles

#120

Earlier quoted context omitted.

Or the fact that $FOO interprets as $(F)OO without the slightest warning. And of course if you're in a script line, you probably meant $$FOO.. Make certainly has some obscure variables, but of all the basic knowledge of Make you need to learn, $@ is near the top of the list (it's "target". an @ sign looks kind of like a bullseye. If you want to see it as visiting a dependency graph, it's the dependency you're current…

Sure, if you use make enough, you likely remember the most important dollar-symbol stuff. But $@ is "all arguments (obeying quoting)" in bash, which is nothing like what it means in make.

That of course becomes "$$@" in a Makefile recipe if you want bash's behavior and not make's... which is one of the reasons I tend to keep my shell scripts in separate files, and only grow a Makefile to wrap them later if I have to. These days I just have the directory of scripts and no Makefile. Even the rare times I do C, I prefer a script that recompiles everything and slapping ccache on top of it (but usually I'm dealing with an existing Makefile, and I just pray that it's not generated by automake)
Post reply on HN