I started using xmake a few days ago. Not sure if I will use it for new projects (due to CMake being the standard) but I definitely want to. The workflow is amazing and super fast. You just run `xmake create` and it creates your project. Then you can just run xmake and boom, it compiles it in an instant, linking dependencies, without needing to create a CMakeLists.txt, adding a submodule for every dependency you use, including your dependency's cmake file, blah blah (xmake has its own xrepo tool which allows for dependency management in a MUCH easier way)
> without needing to create a CMakeLists.txt, adding a submodule for every dependency you use, including your dependency's cmake file, blah blah (xmake has its own xrepo tool which allows for dependency management in a MUCH easier way)
You make it sound worse than it really is today. Using submodules for everything is the pre-vcpkg, pre-FetchContent, pre-ExternalProject way of including dependencies—more than half a decade out of date, and arguably more appropriate for GNU Autotools.
With CMake and vcpkg, it's not that much harder: add vcpkg as a Git submodule, add a vcpkg.json, and use its CMake toolchain to bootstrap and install packages with find_package(), done. Said vcpkg.json can be as minimal as (taken from my own projects):
Every time I try to fully migrate from submodules I hit the following roadblocks:
- vcpkg: dependencies that have custom patches only relevant for my software or where maintainers apply patches once every six months, dependencies where the author doesn't do versioning and the correct version to use is git HEAD
- vcpkg: not sure how I can pass specific flags to dependencies. For instance I need to build LLVM with specific CMake flags.
- CMake FetchContent : how do you handle dependencies that are other repos from your organization which may definitely get patches as part of the development of the software? With FetchContent all those go into build directories and aren't treated as source, I would like to be able to tell CMake "for this build, use source folder /foo for dependency "foo" instead of cloning its 300MB repo again
- How do you handle dependencies that takes ages to build. My software uses Qt, llvm, libclang, ffmpeg and a fair amount of other things. When I tried with vcpkg, the experience building for a new contributor took something like three hours on an average laptop and required dozens of gigabytes of space (software build itself is ~5 minutes with the current precompiled SDK I ship). The space thing is critical, I often get students, interns, OSS contributors etc which definitely cannot afford 30GB of free space on cheap laptops with 256G SSDs
> - vcpkg: dependencies that have custom patches only relevant for my software or where maintainers apply patches once every six months
Yeah, this is a pain point; maintainers need to be more on-the-ball about updating and maintaining packages and package versioning. Maintainers for large Linux package repos (e.g. apt, yum, pacman) can do it, I don't see why vcpkg maintainers can't.
> vcpkg: not sure how I can pass specific flags to dependencies. For instance I need to build LLVM with specific CMake flags.
Use overlay ports[1] and edit the portfile.cmake to pass in additional variables[2]. If you want this to be really configurable every time, then use `VCPKG_ENV_PASSTHROUGH`[3] in a custom triplet[4]. This Stack Overflow answer[5] (full disclosure: I wrote it) explains why you have to do this.
> I would like to be able to tell CMake "for this build, use source folder /foo for dependency "foo"
Use `FetchContent_Declare` with `SOURCE_DIR`[6; this leads to `ExternalProject`, but everything you can use there you can also use with `FetchContent`]. e.g.
> How do you handle dependencies that takes ages to build.
Link vcpkg's asset and binary caches to a network drive that all developer terminals can access straightforwardly. S3, Azure, GCP, GitHub, local/network filesystems are all supported[7][8].
I mean, you say "Linux distributions can do it" but obviously you cannot use distro packages for any serious deployment where your users expect your app to look and feel exactly the same whether they're on Ubuntu or Fedora or Arch (or macOS or Windows). Or if you have patches, e.g. I have a couple patches to Qt.
> Use `FetchContent_Declare` with `SOURCE_DIR`
I know about this but it doesn't solve my problem: I want people who develop to be able to point to the source dir elsewhere, but I want e.g. CI and people who just grab it from github to have it point to some commit in usual FetchContent fashion. And I don't want to have to pass CMake flags for each "co-developed" dependency, that would be a very bad developer experience too. Every cmake flag I add is another couple support tickets from junior developers mistyping it in my experience.
> a network drive that all developer terminals can access straightforwardly
> And I don't want to have to pass CMake flags for each "co-developed" dependency, that would be a very bad developer experience too. Every cmake flag I add is another couple support tickets from junior developers mistyping it in my experience.
Then set up your CMake logic to use FetchContent_Declare based on the boolean value of an option, set up CMake presets[1] with hard-coded values for each CMake command-line option, and ask your developers/set CI to choose between these presets.
You mentioned a precompiled SDK; you can still use vcpkg and overlay ports to redirect to these prebuilt binaries[2]. Replace 'system package manager' with your own paths.
Or, forgo vcpkg altogether if you think the long initial bring-up is a big problem, and just use CMake and your pre-compiled SDK to expose packages, libraries, and headers that your consuming source needs. Not everything is a vcpkg-shaped nail that needs a vcpkg hammer.
Yes... but as great as vcpkg is, it's still not ubiquitous enough that everything is on it, in the same way that everything is available for Rust via Cargo, or for Python via pip, or for Java/typescript via NPM.
> This is not very realistic. I don't want to become a package maintainer of somebody else's library.
Fair enough; then maybe ask the library developer nicely if they could add vcpkg support. Many C++ libraries de-facto support CMake and vcpkg because these have reached critical mass over the past half-decade or so.
I'd say submodules are worse in every metric—you still have to maintain someone else's library (imagine a CVE patch comes through, for instance); submodules themselves are so fragile that they can break your own repo, requiring a full delete + re-clone, and it leads to 'I have this code, I can now make changes to it' which makes updating even harder.
> you still have to maintain someone else's library (imagine a CVE patch comes through, for instance)
I wouldn't call `git pull` maintaining a library.
> it leads to 'I have this code, I can now make changes to it
I would say this is a big advantage! Probably one of the few areas where submodules are better than e.g. crates/pypi. It's great for fixing bugs for example. You can fix bugs in Rust crates you use, by using a special override in Cargo.toml, and I assume pip/NPM support that somehow took, but it is more of a pain.
You're absolutely right that submodules are fragile. But they work well enough that people still use them.
> requiring a full delete + re-clone
I've got pretty close to that but actually I've been able to get out of every submodules breakage that I got into. Did require some magic commands I found in a mailing list somewhere though which isn't fun.
I've had zero problems with stability though if you avoid these two features:
* Worktrees, which sucks because worktrees are great
* git checkout --recurse-submodules (or submodule.recurse). This is just fundamentally broken and has been forever.
There are very good reasons for closed source projects in fact not to use public repositories but the very least org-internal forks/mirrors. In that case dependency management referring fixed public repositories is no-go. If there are better solutions than submodules for these I would love to know. Fetch-content might do the trick? (Specifically, a complex project composed only of private git repositories).
- Publish your local/private mirror of the 3rd-party dep
- Edit the portfile for each dependency to point to your private repo, usually in `vcpkg_from_git`, `vcpkg_from_github`, `vcpkg_from_gitlab`, or `vcpkg_from_bitbucket`
- Publish these portfiles to your private vcpkg registry
- Set the registry in vcpkg-configuration.json (or the `vcpkg-configuration` field in vcpkg.json) to your private registry
I prefer ExternalProject_Add because that way I have full control of the build process. Adding even more abstractions leads to issues, edge cases and the like.
There's also https://github.com/cpm-cmake/CPM.cmake which is mostly a wrapper around FetchContent with good caching. I used vcpkg for https://github.com/zig-for/snfm - it made builds easy, but I'm on the fence if I'd use it for anything that is single platform. The thing that made it powerful was really good support for cross platform builds, but I could probably do the same thing with FetchContent and a few toolchain files.
Can I write a vcpkg.json that just refers to a git repository, tgz download link or similar decentralized identifier? (eg can I also use deps that have no special vcpkg support?)
You need to create an overlay port[1] for each dependency that isn't on vcpkg. So you need, at minimum, a `portfile.cmake` and a `vcpkg.json`[2] for each new dependency.
> just refers to a git repository, tgz download link or similar decentralized identifier
In the `portfile.cmake`, use the following functions correspondingly:
CMake is widely used even on Linux. I wouldn't call it a "standard", and there are many things about it that are unaesthetic, but it has some of the largest market share among C++ build systems. Most software doesn't swap out build systems, so market share is backward-looking and changes based on what new projects use.
I tend to use Meson for C++ because it is much more pleasant to use. Meson is definitely a minority build system, owing in some part to being new-ish, but I see it being used in new projects so it is still growing.
Having spent several years on Bazel and CMake, and only playing around with meson in the last week or so, meson is much more user friendly and easy to get started with.
And by playing around, I mean that I now have a non-trivial project (c. 50,000 loc, 20 libs/apps) that can compile with all three build systems. Then again, I'm a fan of 'keep it simple' in the first place, so I don't tend to do 'stupid' things in my build systems that makes it difficult to port.
I made myself learn modern cmake after using archaic cmake and programming hundreds of lines of cmake functions. Aren't the variable scope semantics kind of fun in an admittedly sadomasochistic way? I'm not particularly competent and I had no problem grossing myself out. I programmed things in cmake that made my ancient advanced perl look like go. However it does all work and your own invented cmake build system is certainly not the most gruesome out there, and there is a lot out there.
Then I tried meson for my own projects, after deciding that cmake was just too ugly and aesthetics matter, to me. For about 3 months I fought the carefully thought out constraints but still liked it. After that the meson design clicked and boy howdy the amount of mental energy I put into my build systems has gone down comfortably close to zero. I adore meson.
Ah I should mention that five years ago or more even I bumped into rough patches in meson but I can say zero in the last few years. Bugs get fixed.
I don't think it implausible though that cmake seems to be getting better for the projects I dive deep into, in an almost meson way. Maybe the days of a project ~/cmake directory containing tens of files and 1000s of lines of bespoke cmake code are dwindling.
Now that I've drunk the meson koolaid, especially about the syntax not being a full programming language, something natively supporting lua, like xmake seems to, makes me wary.
I could envisage cmake evolving towards meson by cleaning up it's complete weird syntax, but it suffers a little bit from something like Conway's Law: it's as convoluted as C++ because it deals with C++, and Hyrum's Law: again, because of C++, it has weird edge cases that people already depend on so it has to be backwards compatible for a long time.
I guess I'm saying cmake is the "build" system you'd expect for C++.
> After that the meson design clicked and boy howdy the amount of mental energy I put into my build systems has gone down comfortably close to zero. I adore meson.
I'm only a week or so into it, and it's been ridiculously easy to get along with so far.
The reason might be that cmake is one of the very few meta build systems that properly support Windows and MSVC (but also macOS and Xcode, compared to all that UNIX+GCC is easy-mode). One underappreciated feature of cmake is that it finds the installed Visual Studio toolchains and Windows SDKs without having to run from a "Visual Studio Developer Command Prompt".
Sadly, another example of the C++ community zigging when it should have zagged.
Cmake now has tooling in all the major IDEs, whereas the other build systems generally don't. Meson and Bazel are build models in CLion but they're relatively new. CMake is the leader at the moment, due to first mover advantage.
It’s used to build the external dependencies for Hercules (the mainframe emulator) but I personally consider it a humongous pain. It might be the reason no Linux distribution seems to dare to package Hercules 4.x
I use CMake when I have to, and XMake when I want to.
I use CLion for its CMake integration, and recently sought out XMake integration for it as well .. this works so well, I just don't see myself ever going back to CMake willfully.
Its just a huge difference in the semantics and ontology required to maintain projects with these tools.
I am now annoyed by the claims of those build systems. My own experience is using a visual studio project manually, and writing classic makefile for linux. Those are things I can't avoid learning.
The root of the problem is that windows/unix do things differently, but that doesn't change anyone's understanding of how a compiler/linker works.
I am against those build system: I need to learn how to use them, and I need to understand how they manage to "reunite" different toolchains.
Generally, I would guess I spend less time building something on each system with either visual studio/makefiles, than using a meta-build system.
Microsoft is at fault for making things differently, of course, but attempts to reunite platforms are often quite misguided
Of course, people who write libraries need those build systems, obviously, although I don't know what any other build system does better than CMake.
> Insanity for anyone who worked in ecosystems like go, c#, rust
On the other hand, I can easily pick a part of the "C ecosystem" that suits me really well, for there is so much choice! In rust, I'm stuck with some conventions that I must learn to love or else. In my case I like rust the language but cannot stand the ecosystem (most notably, the cargo tool). Similar thing for javascript: the language is OK, but the node ecosystem is nuts.
I don't understand, how we found ourself in the world where "one way, one tool, one repository" is good thing.
It is totalitarianism, you know? It is considered bad in politics and social life.
Diversity is considered good for healthy ecosystems!
There is no perfect analogy anywhere, of course, each analogy is flawed in one or another way.
But I don't think we should separate politics, social dynamics and tech. Because everything (unfortunately for us, techno geeks) is politics, as everything is done by people and politics is relationship between groups of people.
Your last sentence is perfectly applicable to politics too: it is way easier to be adult in totalitarian society, if your will to align yourself with "main party line", than in democratic society. You need to make much less choices yourself. But if you cannot align to this line, your life becomes miserable.
I think, that any monoculture is limited and bad. In tech too.
So yeah, what you're missing is that there are natural monopolies. One such would be a centralized tax collector for a nation state. Some others would be a centralized copyright, patent, vehicle or real estate registrar.
In terms of software it helps to have a centralized repository for code as this eases development quite a bit. Imagine you need libraries from multiple repositories. That's a pretty big pain point. Eventually everyone will migrate to just a single source.
Again, these are natural monopolies and primarily driven by the network effect.
Great example. First of all, we need dozen connectors. For network, for power, for special protocols, for special environments. No, USB-C doesn't cover it all, from space station to miniature device which needs I2C or I2S connection, for example.
But lets look at USB-C alone*. It is USB-C, all USB-C is the same from the user-faced side. But they are different inside! There are a lot of variations, with different PCB footprint, different certification (aviation or automotive grade connectors vs "simple" ones), different weather protection, different mounting options. It is great that we have a LOT of different vendors for USB-C, and A LOT of different USB-C connectors!
USB-C is standard, with multiple vendors. As C/C++. One connector. Multiple vendors. Diversity.
[*] - and close eyes on situation with USB-C which is worse than ever, with all these functions which can or cannot be supported and you can never know what is support before trying, multiplied with same problem with myriad of cables which all look the same, but works differently. So, really, USB-C is bad example. But lets pretend it is good.
As a user I couldn’t care less about all the bullshit innards of USB-C. All I care is that I can charge all my Android devices, all my iOS devices and my MacBooks with the same cable.
As a developer I couldn’t care less whether it’s CMake, XMake, Gradle, Autotools, Bazel, Webpack, Bash script or something else.
Is it standard? Is it not absolutely awful? Yes - let’s go, no: can you afford to pay devs to put up with learning yet another bullshit tool? Yes - let’s go, no - keep it to your hobby project until it reaches critical mass and becomes standard.
"Healthy ecosystems" is a disanalogous concept here.
"Diversity" is good in an ecosystem when you have multiple species that complement each other, forming a trophic chain (like plants, herbivores, carnivores, and decomposers).
The resultant monopoly is good at least initially because the victor, ideally, was the best at the niche it competed for. Having suddenly no competition allows it to stagnate, though, compared to if it had constant competition. Biology solves this with constant, random mutations in a cycle of death and reproduction. Maybe that's what WG21 represents for C++? ;D
In general, though, when you're "trying to do a narrow thing", diversity seems bad all around. Python beat Ruby because it was the totalitarian "there's one right way to do a thing" alternative, which was better. Apple stuff works better because it's a totalitarian design from the hardware on up (I admit this as an Apple hater). Cargo works better than CMake because it's an integrated and opinionated build system.
The "narrow thing" could even be a political agenda and a particular subset of social interactions, in which case diversity can also be viewed as negative politically and socially. See political gridlock and how much strife exists between races, religions, classes, and genders. For example, take the "don't go alone in a room with a woman" spiel that OpenBSD guy blathered about. He seemed to claim that women of low status with political axes to grind would seize clout by claiming false sexual harassment in situations without witnesses. If we suppose that scenario exists, it would impossible were there no diversity of gender/sexuality/politics/status in those environments, which would be better for the "narrow thing" of "have a BSD conference or whatever with no drama".
> GCC stagnated before llvm/clang becomes noticeable player.
Became?
Recently, it seems like LLVM's libc++ has stagnated, and clang is basically just copying GCC. If GCC stagnated before, it's nice competition seems to've rekindled its fire. :p
> monopoly is not praised, but rather considered bad.
Because economic monopolies are not self-competitive like organisms are and use their market capture to extract more value, unlike CMake or Linux (probably).
> There are myriad of Linux distributives. Is it bad, as they compete each other?
In that the labor required to make and maintain a good distribution is divided among them, it can be considered bad. In that users have to choose between an array of similar things, it's also bad for them. (If the things are very different, the choice becomes clearer, but then we move away from competition and toward complementing in the ecosystem sense.)
It easily cross-compiles to any target it supports, and natively handles C and C++ dependencies. Much of the complexity of supporting builds in other languages comes from the inclusion of object code in C or C++, so using Zig gives a leg up with that. It also handles caching quite cleanly.
I don't think it's an obvious choice for literally everything, at least not yet. But I'd suggest strongly considering it as a build tool for object-code-heavy applications, even if they don't use the Zig language itself.
I've been always wondering why do we even need specialized build tools and why does the community around every new programming language or framework feel obliged to invent their own, implemented in their native language. Why can't we just write a script in Python or any other scripting language which would fetch the deps, invoke the compilers, run the tests and spit out the package?
I can't answer myself because I only have basic theoretical idea of what build tools do, I have always mostly been using IDEs like VisualStudio which do everything behind the scenes in a press of a button.
You're right, there could be a single tool that everyone agrees to use, and that would make programming much nicer as you would be able to learn one build tool, and then use whatever language you want with it.
What a build system needs to offer, IMHO as someone who also wrote one, is the following:
* tasks (incl. figuring out the graph of dependencies between them and caching results).
* dependencies. Each language has its own repository so it needs to be pluggable. It also may need to resolve conflicts (e.g. Java can't handle multiple versions of the same lib, which you can get due to transitive deps).
* custom options for each language. Native projects may choose -static or -dynlib, Java projects which bytecode version to target and so on.
* tests, documentation generation, linting etc.
Of course there's more to it, but this is the minimum you need. To accomplish all of these, you'll probably need a real programming language or something very close to it - and that's where the problem lies: which language??
XMake chose Lua, which is a very good choice for this (it's a small language but high level and powerful enough to do everything you may need). But if you're writing Java or JS, do you really want to write builds in Lua? Or just use the language-specific build system? I don't think the answer should be obvious, but reality says we chose the latter.
I would love if one day, something like XMake (basically, a DSL to build stuff that's based on a simple lingua-franca, like Lua) became the standard for all communities, but that's not going to happen unless something changes completely in the industry.
> I've been always wondering why do we even need specialized build tools and why does the community around every new programming language or framework feel obliged to invent their own, implemented in their native language. Why can't we just write a script in Python or any other scripting language which would fetch the deps, invoke the compilers, run the tests and spit out the package?
Not-invented-here and developers want to do stupid things in build systems. Not normally intentionally or maliciously, it's just that if you can do something and the build system does not complain about it, it's in.
Then you get 'build systems a la carte' - that are designed based on rigor and experience such as Bazel and buck2 and you start seeing that you can no longer do those things for very good reasons such as guaranteed reproducibility and hermetic builds.
On Minecraft (Bedrock, so C++) for years we had a janky python script that used various platform specific project templates to crudely generate a franken-solution.
Eventually we got enough of an effort to do the long task of adopting CMake for every platform. It's soo much nicer and more consistent than what we had and handles most of our platforms out of the box with little custom tweaking for project file generation.
I do like the idea of it using a common language though. Lua, JS, etc. would all be a nice choice. I am not a fan of the custom language just for building.
Acquiring dependencies is a hard problem. There are generic solutions to at least parts of this, stuff like nix and bazel, but most devs choose an “easier” tool that’s tightly integrated with their language ecosystem rather than one that brings a lot of seemingly unneeded upfront complexity.
It could all be python, but you would need many customization points to serve all the use cases needed to build natively compiled code in all its forms.
Language ecosystems like Rust and Go, and even Haskell shrink the problem space to a smaller universe to grab dependencies. You can see this by how awkward it would be to build a program containing those three languages. They all have different package repositories and build workflows.
C, Fortran, C++ have very rough tools, but the community wants, and often needs, a wide range of dependency management options. Like mixing languages. Or shipping to PYPI. Or integrating with exotic embedded build environments.
You are spot on actually, despite - or because? - of your very high level perspective.
I also agree with the why to invet yet another tool for the same thing kind of note. Could be that fresh graduates think they know much better than those worked this field for long and revolutionise/disrupt it with cool new fresh (all the usual adjectives here) utility? Make life better for everyone at last, finding the Saint Grail that all the makers of brand new cool fresh (other adjectives) utilities of the way past - one comment here told half a decade is too old - could not? I don't know, but it is interesting seeing all the rage of new tools in thick row. Yet, still they are all bad so need to make yet another one!
Which make? I’m guessing you mean gnu make, well there’s several incompatible variants as bsd make and nmake. Also bash is not universally used, not windows, not current macos.
For new languages writing build tools in the language gives you convenient access to meta programming capabilities and removes a dependency (like python in your example)
Thanks, I was curious what are the main differences to Meson (the only general build system so far that I enjoyed using). From these past discussions I gathered:
Xmake's biggest advantage: it's a single binary (vs Meson requiring Python)
Meson's biggest advantage (aside from popularity): it's a declarative DSL rather (vs including a full-blown programming language like Lua in Xmake)
(The second point is subjective, I know some think that including a full programming language is a strength but to my eyes it's a downside that largely outweighs the Python dependency.)
> Meson's biggest advantage (aside from popularity): it's a declarative DSL rather
I personally don't consider this an advantage. We've ran into the limitations of a DSL way too often at work and at this point I prefer just having a plain programming language as an interface. This way you don't have to learn a custom DSL with its own quirsk, you always have the escape hatch of just writing custom code, and it tends to be less quirky.
I find that C and C++ need nontrivial code generation or environment tuning often enough that you really want a Turing complete expression syntax available.
There is the largely feature compatible muon¹ re-implementation that doesn't require Python, it is packaged in a few distributions too. As in all things of this nature there are some caveats².
It is actually pretty useful to have installed alongside meson, even if just for access to the manpages as documentation.
Does it scale for large monorepos? That's where CMake hits its limits. With tremendous effort we switched to Bazel, which has brought down configure+build times to less than 1/10.
I suppose, but you’d be limited to a small number of supported languages, whereas bazel works for just about anything. Like my sibling commenter noted, you only need it if you really need it.
Space of software projects' names are so limited...
There is (was) xmake already: build tool used by XFree86/x.org before x.org modularization. It was very good, much better than auto*-tools, but didn't get enough traction outside XFree86 project.
For a brief moment I thought it was about Premake [1] under a different name, but after checking xmake's Discussions [2] I have found the answer I was looking for.
That's actually very different, as first downloading the code and then executing it all at once removes the ability to differentiate--and then serve different files to--people who are separating the two steps for audit from people who are streaming the one to the other via pipe.
This paradigm is still reckless, though, even if you refused to believe in the security arguments: if you "merely" have a transient error during the script response--which might actually cut off only part of the last line you received!!--you shouldn't execute the fragment :/.
If you insist on doing this and you don't want it to feel like amateur hour to people like me--people who have a strong innate sense of exception safety--you (at least) need to use the bash -c with substitution and add a variable (so you can catch the error with set -e or &&).
It seems that C developers tend to use Turing-complete scripts for building instead of a declarative language. Using scripts means that build configuration cannot be processed by automated tools for extraction of information or modification. Why don't you want to use declarative build configuration?
In my experience the short answer is that there are no declarative build tools for C or C++.
The longer answer is that there are no declarative build tools because all the build tools aim to support all the insane build requirements of existing C or C++ projects. At that point embedding a turing complete scripting language actually makes for simpler build descriptions than some massive declarative system trying to handle all the corner cases.
Of course, that raises the question: why don't any C or C++ build tools limit themselves to some sane subset of build requirements? That, I don't have a good answer for.
In general this exists in order to detect features of the target compiler, libraries, platform and etc. A lot of languages can get away with making assumptions, due to either having only one implementation/compiler, supporting very few platforms/architectures or being otherwise insensitive to the environment.
I think I'm for Turing-completeness. Let me try to give my reasons...
1. No, using Turing-complete scripts does not prevent information extraction and meaningful automation. You can ask the program to dump useful information, e.g. targets, compiler flags, etc. That's what rizsotto/Bear does for Makefile. CMAKE_EXPORT_COMPILE_COMMANDS is another example.
2. I don't really think you can do anything further with declarative build languages, unless it is a really limited one like JSON or XML. Meson (a relatively advanced one in the space) advocates for non-Turing-completeness, but you still cannot, for example, modify meson build files reliably using an external tool other than a text editor.
3. Complex build configuration usually requires non-trivial computation and/or dynamic dependency graph building. Turing-completeness gives you a possibility and you don't need to wait for build tool upgrades.
Comparing Meson to CMake, I find the niceties of Meson are usually not inherently non-TC. That is, you can theoretically reimplement a nicer CMake with all the niceties of Meson, while still being TC.
Makefiles are mostly declarative and very definitely turing complete when you want that. That's a good compromise, simple stuff is simple and complex stuff is possible.
All a rigidly non-turin-complete build tool means is the day will come where you have to throw it away and rewrite everything in a more powerful language, probably at the last minute and with a bunch of fires taking light around you.
re: C/C++ development: anybody using conda/pixi for dependency management? Here's an example of compiling a C++ SDL program using pixi and the SDL dependency from conda-forge [1].
Seems viable as a replacement for things like vckpg [2] which only builds from source.
I'm still researching this but it seems like rattler [3] is the tool to use to build/publish packages. The supported repos are: prefix.dev's own hosting, anaconda.org, artifactory or a self-hosted server.
C++ modules need a lot of communication between build systems, compilers, packaging environments, and other dev tools like clangd. Given some of that interop isn't available anywhere due to missing or at least unimplemented protocols, I expect XMake is overpromising here. The CMake blogs are more qualified:
As the xmake C++ module main contributor, i can affirm that xmake module support is ahead of cmake, i added support for gcc, clang and msvc, headerunits, import std, automatic reuse of bmi when flags are compatible,import module from an external package (like glm or vulkan_hpp) and i’m closely watching compilers repository to support new things before compiler release
for clangd i can't do much currently, there is a PR that add some support, i tried it, but doesn't require for now buildsystem intervention
Looks pretty neat. Probably a lot easier to use than Bazel, unless you need to compile C++ and Java or TypeScript, e.g. for building Android or web apps with a native dependency all from source.
please explain how you can truly support something like 404020 different OS, architecture, toolchain, and programming languages without automated regression testing every single one of them. and then please tell me what system can run this testing because i would love to see that.
The other great thing about D is you don't need anything like that
Example:
dmd -i -Isrc/ src/main.d
and the compiler will automatically grab files you import, and when you need packages you can rely on dub, compiler is so fast that in most cases you don't need any form of caching, a full rebuild of my game takes less than 1sec
sadly so much is tied into cmake with all its eccentricities of being a weird custom macro language, hard to see using anything besides cmake unless I stop using C
Some of the wisdom from the recent XZ backdoor incident was that cmake was a contributing factor, due to its internal complexity.
Some of the current trend is to strip out autotools and cmake, and go back to the basics, because modern OS support is a subset of what was relevant 20 years ago.
I am deeply sick of "compile and run a program to guess stuff about the environment" as a model. Especially in the context of cross compiling and cmake my patience is totally exhausted.
I'm not convinced it's necessary any more. When a compiler claims to implement c99, it probably does implement c99. Lots of ugly target dependent hackery is now fixed at source by doing more sensible things in the target and/or the target having died off decades ago.
Libuv does horrendous platform specific stuff on targets I don't recognise, in raw C, and it's totally possible to compile it without doing any configure or cmake style nonsense because the platform specific things are in their own source files.
90% of the target specific stuff I can handle by asking the C preprocessor what it's building. The remaining 10% can be specified by editing a header or passing compiler flags or similar.
Right now for C libraries I want to depend on I'm patching the source on import to not need any configure check or magic compiler flags, then building every C file separately into an object with the same invocation, and it is working just fine.