Live data from Hacker News

Using Make – writing less Makefile

text.causal.agency

101–110 of 200 posts

Re: Using Make – writing less Makefile

#101

Earlier quoted context omitted.

A similar tool is `task` https://taskfile.dev/ . It is quite capable and also a single executable. I've grown to quite like it.

I prefer task over just, while I am not a huge fan of YAML, we now use it everywhere so it just makes sense to not learn yet another DSL for Just and just use YAML.

How do task and just compare to SCons?

Although SCons is Python (which is a pro or con depending upon your perspective), it has strong dependency management. Or is the argument that dependency management is part of build, not general project maintenance?

Re: Using Make – writing less Makefile

#102
post #87
post #59

Earlier quoted context omitted.

I should rephrase, by dependencies I mean third party dependencies. That is on the build system not the compiler. And make tends to fall significantly behind Ninja in my experience for cold builds. Here’s a post from someone else that echoes my experience https://david.rothlis.net/ninja-benchmark/ but for a sufficiently complex project even a well tuned make build is about 20% slower on CI, which is about 10-20m per…

Ninja excludes a lot of features of make which are expensive to implement and cause it to be slower to parse so naturally in certain situations ninja runs faster than make. If your build time is actually affected by how long it takes to read the makefiles then this is important (e.g. building Android).

When the makefiles are well organized, all of them have just a few lines, with a few definitions, perhaps at most ten lines, but usually less, and they include a single bigger common Makefile, with most of the definitions, all the rules and all the make targets.

So reading all the makefiles should take a negligible time, even in a big project.

I have seen too many projects with huge makefiles and with much more makefiles than necessary, but all of those are examples of misuse of make, which are easier solved by an efficient use of make, instead of by replacing make with another tool.

For instance, there are many projects with a Makefile in each directory with source files, which is a very bad choice that multiplies the number of makefiles. Makefiles should exist only in a dedicated build directory, not in source directories, except for very small projects with a handful of source files.

The best way IMO, is to have a single very small Makefile for each final file that must be built, e.g. executable file or library, in a dedicated subdirectory of the build directory. This allows for a maximum simplification of the Makefiles and their number and size is independent on the number of source directories and on the number of source files.

Re: Using Make – writing less Makefile

#103
post #53

Earlier quoted context omitted.

Not downvoting you. Just curious to know why? In my experience, as long as the Makefile is less than about 100 lines, it's the most useful workflow system ever. Because it's available almost everywhere. After about 100 lines, yeah, it is not great. And that idiotic tab character. I know the historical reason why tab was used. I wish they had fixed it to accept both tabs and spaces a long time ago.

It's a poor, verbose, arcane solution in every problem space it purports to solve. It was fine in its era, but that's a long time ago. It is completely unsuitable as a project management tool and a poor task runner. Also its ubiquity is overhyped. There's no build platform where I can't download the tools I need, that's the entire point of a build platform, and most such platforms come with far more advanced tools pr…

Make has few dependencies so it's a way to build an operating system up from ground 0. Any tool/language that wishes to be generally useful in an OS doesn't want to be built by something that is only available much further up the tree like python.

So it gets used a lot and it's only a language for dependencies and rules. It doesn't do "project management". Its the simplicity of what it's trying to that saves it from ever becoming irrelevant - because it can be made to fit almost any use case. It's not a special tool for enforcing one structure or building only one language - something that seems highly regressive to me but which is adopted by many languages now.

Re: Using Make – writing less Makefile

#104
post #91

Earlier quoted context omitted.

With all due respect, I don't understand the first part of your comment. Make's core purpose is to execute commands, isn't it? How was it not designed to execute commands?

No, no. Make's principal purpose is to put a set of files into a desired state. It can "make" a particular file by invoking a dependent graph of commands that produce that file from other files. It checks timestamps and only run steps where the resulting files are older than some of the (transitive) source files. You can invoke it by naming a named rule, not a file, but the logic will remain. If this is not what you…

I also don't like Make for running commands.

I was using Make for running commands, but it interprets all command line parameters as build targets, which was annoying. And Bash scripts in Makefiles aren't type safe, became messy.

Nowadays I use Make only for building. And Deno + Typescript instead, for running commands & scripts.

(Hadn't heard about Just — the scrips aren't type safe though?)

Re: Using Make – writing less Makefile

#105
post #34
post #30

The author should mention the automatic variables: https://web.mit.edu/gnu/doc/html/make_10.html#SEC94 Specifically, in one of the examples, to list all dependencies as the input to `cc`, you can write `$^` instead of `$(OBJS)`.

OBJS is a little more clear to what's happening than $^ I'm not a fan of magic symbols. Hard to remember, especially across languages.

Make actually has some of the more sensible shortcuts, which are easy to remember

$@ -> the target (like an email address)

$^ -> the dependencies (look up)

$ only the first dependency (look up sign, but rotated 90s left to point at the first one)

Re: Using Make – writing less Makefile

#106

Make's killer feature was conditionally rebuilding based on changed dependencies. Back in the day, it was easy for a medium to largish software project to take many hours, or even days to fully rebuild. C and C++ were especially bad, especially "every file transitively includes every header" type projects. Make saved a lot of that pain, even if linking still sucked. I love make and still spin up a minimalist Makefile…

I see people now with long javascript builds that waste time doing many things repeatedly - it's quite ironic. Eventually people find crap to fill up the performance that's available.

The problem is that now the tools aren't designed as composable bits that you can really parallelise with a makefile. C/C++ are designed that way and if they didn't use header files I'd consider them perfect from the build system's point of view :-). Golang and java for example are a nuisance.

Re: Using Make – writing less Makefile

#107

Is there any reason to use make over ninja and gn?

ninja is faster at parsing large makefiles and I'm reasonably certain it's because it lacks certain expensive features of make.

Do you need those features? You'd have to read about make to find out but it boils down to there being not much performance difference for small builds so make might have an edge there. When you get to android sized builds the reading of makefiles can take minutes and ninja wins there enough to make it worth sacrificing the features.

Re: Using Make – writing less Makefile

#108
Make is the grilling of the hacker world. You just want to light up some quality lumpwood charcoal and get a nice smokey crust on some steaks, cook up some hamburgers, and crisp up some chicken for your guests over the course of an afternoon…

…but oh no there is a constant stream of inquisitive folk coming over, beer in hand, suggesting cool adjustments / hacks / “improvements” to your setup. With grilling it’s actually pretty easy to defend oneself from this unsolicited advice. There’s only one grill after all. It’s not like it’s some company wide grill that anyone can make changes to solely by convincing one other person to sign off on their PR / MR / changeset.

I’ve seen some very “clever” makefiles (and cmake lists.txt) over the years. It is hacker catnip for all manner of Jackson Pollock ad hoc scripting rubbish and I lament every commit that did anything except make the makefile less complex! All new software engineers should be given a shiny ball to play with when they get bored with their day job, lest they decide to take out their playful creativity on the build system instead.

Re: Using Make – writing less Makefile

#109
post #51

Quasi-tangent: I was once hit by a coworker doing first code review on a new repo with "hmm...I'm not familiar with using Makefiles as a project management tool. So something something [don't remember] we should replace that." It struck me as weird because I don't see `make` as a build tool so much as automating shell script snippets you would/could type at the command line. From that POV I conceptually see Makefiles…

I really like GNU Make because it has a hidden superpower: the "-j" parameter enables instant, easy parallelization. I have a project with many subprojects and I use "-j16" to invoke the same command in all of the subprojects, 16 at a time. It saves a lot of time and it works for all commands that don't touch other subprojects. Like you, I use Make as a front end to lower level build tools. It seems to fit that role…

‘-j -l $MAXLOAD’ is even more polite on shared systems. Avoids most runaways, but not all.

Re: Using Make – writing less Makefile

#110

I say this as someone with 20+ years of experience in C and C++: Using make is a huge waste of time in 2023 (and forward). Learning the intricacies of make actively blocks you from Getting Things Done. Yeah, make is kind of neat because it has this functional what_I_want : how_to_get_it syntax, but it doesn't actually work that way. It's a huge waste of time to try to get it working so unless you meet the following c…

If meson fits your project it's worth using it - it could turn into a straightjacket later but changing to something else isn't the end of the world if it cost little effort to implement it in the first place.

As for trying to use a "modern" language to write scripts.......well if they're not declarative and don't understand dependencies then how can they be better?

make is no paragon - it just contains solutions to lots of problems that exist in build systems. The fact that those problems exist and make has ways to solve them isn't make's fault. Everyone might perhaps want builds to "just work" so they can ignore them and such people write scripts and use the concept of "rebuild and clean" a lot and it works until the build gets big and slow.

"modern" tools get written with many simplifying assumptions and become slowly complicated as they hit all the problems make hit long ago and try to find ways to solve them.

Post reply on HN