The least painful C/C++ build tool I've used is xmake

https://github.com/xmake-io/xmake

The reason why I like it (beyond ease-of-use) is that it can spit out CMakeLists.txt and compile_commands.json for IDE/LSP integration and also supports installing Conan/vcpkg libraries or even Git repos.

    set_project("myapp")
    set_languages("c++20")

    add_requires("conan::fmt/11.0.2", {alias = "fmt"})
    add_requires("vcpkg::fmt", {alias = "fmt"})
    add_requires("git://github.com/fmtlib/fmt v11.0.2", {alias = "fmt"})

    target("myapp")
        set_kind("binary")
        add_files("src/*.cpp")
        add_packages("fmt")
Then you use it like

  # Generate compile_commands.json and CMakeLists.txt
  $ xmake project -k compile_commands
  $ xmake project -k cmake

  # Build + run
  $ xmake && xmake run myapp

I would happily switch to it in a heartbeat if it was a lot more well-documented and if it supported even half of what CMake does.

As an example of what I mean, say I want to link to the FMOD library (or any library I legally can't redistribute as an SDK). Or I want to enable automatic detection on Windows where I know the library/SDK is an installer package. My solution, in CMake, is to just ask the registry. In XMake I still can't figure out how to pull this off. I know that's pretty niche, but still.

The documentation gap is the biggest hurtle. A lot of the functions/ways of doing things are poorly documented, if they are at all. Including a CMake library that isn't in any of the package managers for example. It also has some weird quirks: automatic/magic scoping (which is NOT a bonus) along with a hack "import" function instead of using native require.

All of this said, it does work well when it does work. Especially with modules.

Similar to premake I have never been a fan of the global state for defining targets. Give me an object or some handle that I call functions on/pass to functions. CMake at some point ended up somewhat right with that to going to target based defining for its stuff and since I've really learned it I have been kinda happy with it.

Agreed, xmake seems very well-thought-out, and supports the most modern use-cases (C++20 named modules, header unit modules, and `import std`, which CMake still has a lot of ceremony around). I should switch to it.

actually looks very similar to Meson [https://mesonbuild.com/], which is getting a lot of traction in FOSS [https://mesonbuild.com/Users.html]

e.g. from their docs:

  project('sdldemo', 'c',
          default_options: 'default_library=static')
  
  sdl2_dep = dependency('sdl2')
  sdl2_main_dep = dependency('sdl2main')
  
  executable('sdlprog', 'sdlprog.c',
             win_subsystem: 'windows',
             dependencies: [sdl2_dep, sdl2_main_dep])

Meson is a python layer over the ninja builder, like cmake can be. xmake is both a build tool and a package manager fast like ninja and has no DSL, the build file is just lua. It's more like cargo than meson is.

I didn't claim it was a package manager, just that it looked similar. The root post said "build tool", and that's what Meson is as well.

Other than that, both "python layer" and "over the ninja builder" are technically wrong. "python layer" is off since there is now a second implementation, Muon [https://muon.build/], in C. "over the ninja builder" is off since it can also use Visual Studio's build capabilities on Windows.

Interestingly, I'm unaware of other build-related systems that have multiple implementations, except Make (which is in fact part of the POSIX.1 standard.) Curious to know if there are any others.

I've had some experience with this but it seems to be rather slow, very niche and tbh I can't see a reason to use it over CMake.