Authentication-Results: mail-b.sr.ht; dkim=none Received: from mail.nullprogram.com (mail.nullprogram.com [192.241.191.137]) by mail-b.sr.ht (Postfix) with ESMTPS id DD40511EEC2 for <~skeeto/public-inbox@lists.sr.ht>; Sat, 25 Dec 2021 23:56:16 +0000 (UTC) Received: from nullprogram.com (localhost [127.0.0.1]) by mail.nullprogram.com (Postfix) with ESMTPS id 8A6A7C77EF; Sat, 25 Dec 2021 18:56:13 -0500 (EST) Date: Sat, 25 Dec 2021 18:56:12 -0500 From: Christopher Wellons To: Harris Snyder Cc: ~skeeto/public-inbox@lists.sr.ht Subject: Re: Meson/Ninja? Message-ID: <20211225235612.rfvpmwei6zdamybt@nullprogram.com> References: <20211223202217.qzsuyjoidpcdl7bk@nullprogram.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170113 (1.7.2) > 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.