Live data from Hacker News

Ninja: A simple way to do builds

jvns.ca

71–80 of 92 posts

Re: Ninja: A simple way to do builds

#71
post #70

It is a mistake to imagine Ninja just replacing Make. Ninja is the "rebuild-it" part of Make, made really, really fast and clean, a joy to use. The Ninja config file is not something you write or, even, look at. It's an intermediate file generated by your build-dependency tool such as CMake, Meson, or even (gods forbid) SCons. Those are smarter than Make in various ways, but are really not very good at all at actuall…

The ESP32 SDK (ESP-IDF) now is based on CMake and defaults to Ninja for the build target. They still support Makefiles as well but Ninja is quite noticeably faster.

Re: Ninja: A simple way to do builds

#72
post #8

Earlier quoted context omitted.

Ninja uses time stamps. See the “Comparison to Make” section in the linked manual.

Isn't using mtime a bad idea? https://news.ycombinator.com/item?id=18473744

No? The top comment in that thread is the author of Ninja discussing how he addressed the problems described in the article. And, despite its title, the article itself goes on to discuss why and how to use mtime in a build system.

Re: Ninja: A simple way to do builds

#73
post #49
post #44

Earlier quoted context omitted.

Re a new version of inkscape: Ninja does not force fully-correct builds, so it's on the author of the build.ninja file to either model this or not. (This is part of Ninja's objective of not mandating policy.) To get this fully correct, note that you would need to model all inputs that Inkscape might read, which includes not only binaries but also configuration files or dynamically-loaded plugins. Some systems (I thin…

> Even with tracing it can be really subtle The correct way of doing this is not tracing but a hermetic build. If you do a sandboxed build with nix, you will get a specific version of inkscape with a specific hash, which includes will include any inkscape extensions you include. And since the build will only be able to read files in the sandbox, none of the problems you list above can happen -- you can't pull random…

What you wrote is true, but it also seems to me unlikely that the OP is going to set up a sandboxed hermetic build to process a handful of pngs for her zine. I was instead explaining why Ninja doesn't attempt clever tricks to try to better approximate correctness.

Re: Ninja: A simple way to do builds

#74
post #17

For comparison, here’s a makefile for the trivial example (though you’ll have to fix the indentation): all: $(patsubst ${things_to_convert},%.svg,%.pdf) %.pdf: %.svg inkscape $ ${things_to_convert} is left undefined, as in the source article. It might be something like $(wildcard [STAR].svg) or $(shell find src -name '[STAR].svg'). [Turn each [STAR] into *; HN formatting idiosyncrasies are in play.] I like makefiles…

You are not wrong, but if the world where not full with even worse build systems it'd be a bit saying I prefer to drink from puddles because I find them wherever I go. Make is everywhere, but apart from UX issues such as the dumb syntax or the different flavors you'll encounter, the fundamental problem with it is that it just can't build things properly (the existence of make clean is the dead give away here). That's…

> - if inkscape writes out a partial file because full disk and you fix the problem, the partial svg will no be rebuilt

You can use the `.DELETE_ON_ERROR` phony target to solve this problem. You can read more about this in this short article:

https://innolitics.com/articles/make-delete-on-error/

Re: Ninja: A simple way to do builds

#75
post #17

Earlier quoted context omitted.

You are not wrong, but if the world where not full with even worse build systems it'd be a bit saying I prefer to drink from puddles because I find them wherever I go. Make is everywhere, but apart from UX issues such as the dumb syntax or the different flavors you'll encounter, the fundamental problem with it is that it just can't build things properly (the existence of make clean is the dead give away here). That's…

> - if your paths have white space in them This is probably my second biggest complaint about Make. > - if you change your Makefile, nothing will be rebuilt Heh, there’s a common trick for that: just slap Makefile on the end of prerequisite lists. I’ve worked with more complex projects that extend this to versioning the makefile with a `build/.makefile-v${MAKEFILE_VERSION}` common prerequisite so that you can bump th…

I've never seen the `touch` version of that safety versus broken output files before. I've only seen the `rm` version. Is `touch` advantageous? Edit: oh, oops, I should've followed the link; the output file in the example seems to be test output which would be more distinctly useful to inspect after the fact on partial failure. That makes sense.

Re: Ninja: A simple way to do builds

#76
post #57
post #19

Earlier quoted context omitted.

> - if your paths have white space in them, you are generally fucked Paths containing ':' are also fun. That make doesn't handle paths - and most likely other things - as a unit, but just substitutes their string representation into the makefile, is just asking for trouble.

> Paths containing ':' are also fun. To be fair, anyone who uses reserved/special characters in file names is asking for trouble in pretty much any usage.

Still, it's not great to trip over them.

Re: Ninja: A simple way to do builds

#77
post #48

Earlier quoted context omitted.

> I like makefiles in substantial part because there’s a very high probability of Make already being installed. I’m comfortable enough with them that I didn’t need to look anything up to write any of what I wrote above. There's an even higher probability of Perl being installed, and I'd much rather use that than Make. I've even been known to write a Perl script that calls Make after doing something complex that would…

> There's an even higher probability of Perl being installed You're showing your ignorance there, champ. Make is one of the utilities that's required by the UNIX specification,which means that each and every single UNIX or UNIX-like OS is required to make Make available to users in order to be considered an UNIX. So to make this quite explicit, for starters each and every install of macOS ships with make.

… sort of. Last I checked, the Make features required by POSIX were very anemic. What winds up all over the Web in tutorials etc. is mainly GNU Make, which is extended way beyond that, including in ways which can become practical necessities pretty fast.

Which would be why my projects use the “GNUmakefile” file name explicitly, even though e.g. I tend to write to POSIX sh where I can rather than following the “bash scripting” trend. I also remember seeing a project in the wild that had a separate GNUmakefile and BSDmakefile, presumably for similar reasons.

If you use only POSIX make syntax, great for you, but there's definitely a barrier compared to what a lot of people are used to thinking of as Make nowadays.

(This is also ignoring the part where “higher probability” at a glance refers more to popularity than to standards compliance, and I don't read the parent as implying being in an environment where POSIX/SUS compliance is directly related to the set of target systems.)

Re: Ninja: A simple way to do builds

#78
post #70

It is a mistake to imagine Ninja just replacing Make. Ninja is the "rebuild-it" part of Make, made really, really fast and clean, a joy to use. The Ninja config file is not something you write or, even, look at. It's an intermediate file generated by your build-dependency tool such as CMake, Meson, or even (gods forbid) SCons. Those are smarter than Make in various ways, but are really not very good at all at actuall…

The ESP32 SDK (ESP-IDF) now is based on CMake and defaults to Ninja for the build target. They still support Makefiles as well but Ninja is quite noticeably faster.

I use ninja over make with LLVM for this reason.

Re: Ninja: A simple way to do builds

#79
post #57

Earlier quoted context omitted.

> Paths containing ':' are also fun. To be fair, anyone who uses reserved/special characters in file names is asking for trouble in pretty much any usage.

But linux filename basically allows any byte sequence except EOF and /, so I think it is "make" fault to not being able to support it. Other proper build tools support it correctly.

Well, just because make is faulty, doesn't mean linux isn't too ;)

Spaces -- ok. But there is absolutely no use case for allowing near arbitrary byte sequences in filenames, it causes no end of trouble, and it would have been trivial to fix in a non-disruptive manner ages ago (mount -o allowreallydumbfilenames, off by default).

Re: Ninja: A simple way to do builds

#80

Of note, meson is mentioned to optionally use ninja as a build system, but the same is true of CMake. On thing to note is that the simplicity of ninja means that a lot of things need to be repeated. For a project I'm working on, the input build.ninja file is 142MB. Just generating that files takes a few minutes. I think an improvement would be to be able to split it in sub-trees and have ninja produce a "mark" file t…

Are you sure Ninja is the cause of the problems there? I agree that it’s repetitive, but you can at least put common expressions into build variables, so the overall build script size should scale about linearly with the number of files.

142MB is massive! How many files are being built and how much work is being done per file? 142,000 files with 1KB of unique command-line flags each?

Also, even though that’s a very large build script, I would have thought generating it should only take seconds, not minutes. How is the script being generated, and how long is spent generating it versus executing it?

Post reply on HN