Subject: Thoughts on Samurai vs Ninja

From: Ariadne Conill <[email-masked]>
Date: Sat, 28 Dec 2019 13:22:20 -0600

Hello,

I was reading through the archives and IRC logs and noticed a
comparison of samurai vs ninja to pkgconf vs pkg-config.

As the original author of pkgconf, I believe it is important to fill
in some details about the pkg-config transition, so let's start with
that I guess.  pkgconf was originally started by me[1], in 2011,
because pkg-config upstream maintenance had become lackluster, and we
wanted to add additional features to improve dependency calculation in
abuild based on pkg-config declarations.  I was one of the people
involved in maintaining the original pkg-config package in Alpine
until the point that pkgconf replaced it, which was not immediate.
While Alpine was an early adopter of pkgconf, Gentoo was the first
real adopter of it, because we were still working on edge cases.  As I
recall it, pkgconf did not fully replace pkg-config until release 0.7
or so -- I could look it up in git history, but it's not that
important.  The key point here is that pkgconf was written by me,
somebody who was heavily involved in Alpine packaging, as well as
making general architectural decisions for the distribution.  So, I
don't think it is really an accurate thing to say that samurai vs.
ninja is the same scenario.

When Natanael asks if the relationship is the same, what he asks is
basically if issues in samurai will result in a drop-everything hotfix
release being made within the same day.  That is the relationship that
pkgconf has with Alpine and other distributions, as it was a tool made
for the distributions to consume explicitly, by someone who is making
distributions.

Now, let's talk about Ninja's current situation.  Ninja is maintained
upstream by a Google employee and was designed for building Chromium.
For that case, things are fine, but that does not mean that Ninja
itself is a good distribution-scale build tool.  What I have learned
from writing and maintaining pkgconf is that distributions tend to
have requirements that are different than what developers working at
small scale have.  Distributions need standard ways of invoking build
tools, that match the behaviour of other build tools, while
small-scale developers don't.  In the case of Ninja, this translates
to the NINJA_FLAGS environment variable that has been rejected
numerous times.

Drew talks about the fact that Ninja is implemented in C++ a lot, as
if it were a defect.  In *that* case, I wholeheartedly disagree.  It
doesn't really matter if a programmer chooses to use a language you
personally dislike for their tools as long as the tools themselves are
not defective.  But, when we are talking about building software at
distribution scale, the tool *is* defective, as we cannot control it
in the same way as other tools, through environment variables.

In practice, the only real point of contention for Ninja being written
in C++ is that it stores the dependency graph as a `std::set<Edge *>`
type, which means that the dependency graph is ordered by pointer
addresses.  This is a poor design choice, but in practice should not
matter, as ninja build files are generated by a higher level tool
which is required to provide a full dependency graph.  However, it is
corner-cutting nonetheless, and is potentially eyebrow-raising when
you are looking at Ninja as a distribution-scale tool.  To illustrate
what I mean, it is basically the difference between using a star-bit
on a screwdriver to fix an Apple laptop instead of the correct
pentalobe screwdriver -- in practice, for a quick fix, it probably
doesn't really matter, but it still isn't the right way to do the job.

But is Samurai actually a suitable replacement that *is* a tool
designed to be used at distribution scale?  I believe it is, and I
believe it is an overall better tool than Ninja anyway, much in the
same way as pkgconf is a better pkg-config.  Michael Forney, who is
the maintainer of Samurai is also an Exherbo developer, and while
Exherbo is not operating at the same scale as Alpine, they have the
same fundamental requirements in terms of tool reliability and
developer SLA.  I believe wholeheartedly that if Alpine had a problem
with Samurai, it would be mitigated quickly.  So, from that end, I do
think the comparison to pkgconf is valid.

Accordingly, I would suggest dropping ninja entirely in favor of
samurai, by including a subpackage which symlinks /usr/bin/ninja to
/usr/bin/samu and provides=ninja as we do with pkg-config.

The code is simpler and does not order dependency graphs using pointer
addresses.  Samurai can be used in the exact same way as other tools
similar to it, such as make.  The maintainer of Samurai is far more
approachable than the maintainer of Ninja.  Those are the data points
that actually matter, and when you look at those data points alone,
the better option is obvious.

Ariadne

[1]: I have changed my name since then, obviously.