~skeeto/public-inbox

5 3

Meson/Ninja?

Details
Message ID
<CAKF5_T=0JTOU=AGVGF-u6J5RKRtRQ5YP0X85Rr4g=Q=V2GFd3Q@mail.gmail.com>
DKIM signature
pass
Download raw message
Hi Chris,

I know you're an advocate of Make, but I'm curious if you've had a
look at Meson/Ninja and, if so, if you had a "review" of them?

--Harris
Details
Message ID
<20211223202217.qzsuyjoidpcdl7bk@nullprogram.com>
In-Reply-To
<CAKF5_T=0JTOU=AGVGF-u6J5RKRtRQ5YP0X85Rr4g=Q=V2GFd3Q@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
Interesting question, Harris. Since Make has served me well enough all 
these years, I haven't had much reason to look at Meson or Ninja. I don't 
like dependencies, even build dependencies, that don't bring something 
substantial to the table. Make is a standard development tool with 
multiple, independent implementations, and so, in practice, it's not 
really a dependency. Like, say, a text editor, it's safe to simply assume 
it's present alongside a compiler, even on Windows. I include Make in 
w64devkit after all, so there's really no excuse not to have it on hand 
when building my software.

I was aware of Ninja due to it being an output option for CMake, though 
I've never used that feature. It's written in C++, which is reasonable 
enough for me to consider it. Though Ninja is low level in the same way 
Make is low level, so it's not bringing anything new to the table. It 
claims to be faster, though that won't apply to the way I build software, 
where Make already consumes less than 0.01% of the total build time (full 
build), and only a couple of milliseconds when there's nothing to do. The 
website says you're not really supposed to write Ninja build files by 
hand, and it's intended to be generated by yet another build dependency 
(CMake, Meson, etc.). So I see no benefits versus Make, just the cost of 
an extra dependency and an unconventional build interface.

When I've run into projects using Meson, my reaction has always been to 
roll my eyes and bypass Meson, manually invoking the compiler on the 
source files. These projects have always been simple enough that they 
don't even need much of a build system, let alone an esoteric one.

Looking more closely at Meson now, I see its written in Python. This is an 
inappropriate implementation language for a build system, and more than 
enough reason enough for me to never touch it. A build system ought to be 
written in a systems language. If I depend on Meson, then I also 
transitively depend on a full Python interpreter and package system (to 
install Meson) since the Python community has yet to solve distribution / 
delivery. Fortunately Meson doesn't have further Python dependencies of 
its own, so at least it's not nearly as bad as it could be.

Trying it out some existing Meson builds listed on their site, I see it 
makes a common mistake with CMake: The output build scripts contains 
absolute paths to the project itself. A consequence is that I can't mix 
tools with different views of the file system. For example, tools running 
in Cygwin or Msys2 see different paths than native Windows tools, so they 
may be confused when invoked by Meson or CMake builds from the other 
system. This was at one point a deal-breaker for me with CMake. Though it 
seems Meson uses relative paths more than CMake, so maybe in practice it's 
not an issue.

The only build system I've ever liked more than plain old Makefiles is "go 
build". Unfortunately it's too late for C and C++ to have something like 
that — the ecosystem has been fragmented into incompatible ways of doing 
things for far too long.
Details
Message ID
<cf9a4d77-feca-2c21-2ddc-2e9b0125517b@harry.pm>
In-Reply-To
<20211223202217.qzsuyjoidpcdl7bk@nullprogram.com> (view parent)
DKIM signature
pass
Download raw message
 > Looking more closely at Meson now, I see its written in Python. This
 > is an inappropriate implementation language for a build system, and
 > more than enough reason enough for me to never touch it.

For what it's worth you're not the only one to feel that way. There is a 
C implementation of meson on sourcehut that seems to be actively 
developed: https://sr.ht/~lattis/muon/

Obviously that doesn't change the value proposition of why you'd use 
meson instead of make, but it does help cut an unnecessary python 
dependency.

Harry
Details
Message ID
<CAKF5_TmpnS4_R-HSH3gjfLka1SW_PR+uEjTFazk4ypwwnKC8Mw@mail.gmail.com>
In-Reply-To
<20211223202217.qzsuyjoidpcdl7bk@nullprogram.com> (view parent)
DKIM signature
pass
Download raw message
Good review. I hadn't realized that Meson was written in Python. I
generally agree with the points you make in your email, but I also
feel that Make has a few deficiencies... having a separate build
directory and source directory, for example, is more difficult than it
should be, and supporting the cross platform use case more or less
requires you to have more than one makefile (in fact if memory serves,
you made the same point in one of your articles on makefiles).

... I'm not sure I'm bothered enough by Make's deficiencies to write
my own build system, though :)

Harris
Details
Message ID
<20211225224149.bfjpkbbs7t3whiti@nullprogram.com>
In-Reply-To
<cf9a4d77-feca-2c21-2ddc-2e9b0125517b@harry.pm> (view parent)
DKIM signature
missing
Download raw message
> There is a C implementation on sourcehut

Thanks, Harry, I wasn't aware of this. That's more reasonable, and it's 
healthier in the long term for Meson to have multiple implementations.
Details
Message ID
<20211225235612.rfvpmwei6zdamybt@nullprogram.com>
In-Reply-To
<CAKF5_TmpnS4_R-HSH3gjfLka1SW_PR+uEjTFazk4ypwwnKC8Mw@mail.gmail.com> (view parent)
DKIM signature
missing
Download raw message
> having a separate build directory and source directory

Yup, Make is far from perfect, and it doesn't make this easy. As is the 
case for most GNU Make extensions, its VPATH extension is too poorly 
designed to improve this situation even for GNU Make.

When I've had projects grow large enough enough that maintaining a 
Makefile becomes difficult, and I still care about incremental builds, I 
hand-write a shell script to drive GCC -MM -MT over the source files, 
automatically handling the header dependencies, and covering cases like 
out-of-source builds since I can brute force the rules (vs. relying on 
Make's limited inference rule matching). That script is essentially doing 
the same work as CMake or Meson, but at a fraction of the cost and with 
more flexibility.

None of my open source projects have ever become complex enough to warrant 
that treatment, so I can't point to any of my real world examples, but I 
put together an example for Enchive just now:

https://gist.github.com/skeeto/b07bbfbf8ec7d4075685e8e9f0a7a888

I check in the generated Makefile so that the actual build doesn't depend 
on the script or GCC in particular. (Also, running "gcc -MM" on Windows is 
painfully slow due to Windows' poor file system performance, so I like to 
avoid it.)

> supporting the cross platform use case more or less requires you to have 
> more than one makefile

Sticking to GCC or Clang, I can cover all platforms with a single Makefile 
since the compiler interface is essentially the same across all supported 
platforms. A past obstacle has been relying on unix utilities (esp. rm), 
which may not be present on Windows even alongside GCC and Make. This was 
a major part of my motivation for w64devkit, serving as a reliable, 
standard build environment on Windows without lugging Cygwin or Msys2.

In my w64devkit guide from March, I mentioned my convention of using an 
EXE Make variable to automatically append an extension to the linked 
targets. This covers both the cross-compilation and w64devkit cases.

I *do* use a separate "NMakefile" for interfacing with MSVC tooling, where 
I follow cl's unconventional (even for Windows) interface and only use 
Windows utilities (as painful as that is). See my "asteroids-demo" for an 
example. This is where something like CMake or Meson might have an 
advantage, covering both GCC/Clang and MSVC/clang-cl from a single build 
configuration. However, like before, I know how to use MSVC, and I'd 
rather do it myself and have full control even if I have to maintain a 
separate Makefile.

My best solution for dealing with arbitrary, weird platforms is having an 
amalgamation build that concatenates all source files into a single source 
file / translation unit. Then, just as with SQLite, you don't need any 
build system: Simply invoke the compiler directly on the single source 
file. Enchive works like this, which is how I support all platforms and 
compilers from a single build definition. This is also a major feature of 
unity builds, though those have the additional cost of lacking fast 
incremental builds during development. Amalgamation is the subject of a 
whole new article I've been intending to write for awhile, but haven't 
gotten around to it yet.
Reply to thread Export thread (mbox)