Cmkr – a modern build system based on CMake and TOML
github.com
github.com
Any system like CMake that wraps boatloads of complexity is going to have unexpected interactions and inscrutable failures.
The question for any developer who doesn't want to become a build system guru is whether they can take a happy path far from any gotcha's.
That's when people start defining conventions to solve classes of problems: follow this template to do X, and you'll be fine.
The value of Cmkr lies in being about to define those conventions and happy paths. I should be able to inspect their templates, and if one fits, I'm good to go.
Even nicer would the ability to retrofit my build to a known-working template.
But Cmkr only presents the "beginners" template repo as an aside, and says nothing about whether these templates are tested for various projects on various systems.
By not explicitly identifying the problem it's trying to solve, Cmkr seems to have bumped up against a solution accidentally, and doesn't give me confidence. I believe that could be easily remedied.
Turn on all warnings? Yeah, just check if your CC is MSVC or else and set the flag!
Turn on sanitizers? Yeah, just include this 2000 line piece of CMake macro that checks your CC and turns on flags!
Find a package? Yeah, just write a FindFooCMake macro file that spells out the exact files to find in the filesystem and parses a header with more macro magic to determine the version. Maybe we decide to ship this shitty macro file with the default distribution later on and cause more conflicts and distress. By the way, we now have a superior C++ namespace inspired way of defining packages that we mix and match with the old stuff in our default distribution.
Can't you just use pkg-config files like everyone else? Yeah, just make sure to include another 3000 line CMake macro if you specifically want us to use pkg-config.
Cross compile my program for a different architecture? Of course CMake supports that, as long as you write a toolchain file that spells out the exact CC, CXX, sysroot, ... and all other things that could even get a maximally minimal Makefile to trivially cross compile. Make sure to force-overwrite some of the useless autoconfig inspired tests CMake will perform on your toolchain because they are broken with whatever cross compiler you are trying to use.
So while CMake does nothing to help with common things, their "CMakeCache" is the most powerful proof for "nothing is more complicated in programming than caching" the world has ever seen.
https://cmake.org/cmake/help/latest/command/find_package.htm...
Sure, there are like 100 pages of useless details in there, but at least they didn’t waste space by explaining what side effects invoking it for a given package will have, or how to find out what package names your system recognizes.
Also, they didn’t complicate stuff by defining any naming conventions around what variables finding a package will set up.
The CMake DSL is utter garbage. From my understanding, this converts TOML that follows the same/similar naming as CMake commands/options to CMake DSL. Allowing for total compatibility with CMake while avoiding the pain of actually interacting directly with a CMakeLists.txt.
Most people agree that CMake is not a good option but the only real option. I'd happily put lipstick on this pig.
1. read the GNU Make manual 2. Write a tiny build system with Make or use any of the precanned ones. I use this: https://github.com/dkogan/mrbuild/ but there are many others
In any case, learning how to actually use Make is a prerequisite to having an opinion here.
4. Follow its advice until you hit the end of where it is useful. (i.e., you can no longer count the number of $ escapes in your own code).
If you truly need a lot of complexity, you can end up with unreadable Makefiles, as you say. Most projects don't need a lot of build logic, though. I have lots of projects using mrbuild, and their builds are clear and easily maintainable. If you truly need a lot more, then Make might not be the best choice. And you can do much better than cmake
It's great that it's self-bootstrapping, though. I thought they would have you install both this tool and CMake in order to build the project on end-user's machines.
I want something that is declarative and extensible at its core, and not an after-the-fact bandaid that tries to fix what's broken beyond repair.
SOURCES += ['a.cpp', 'b.cpp']
if CONFIG['OS'] == 'WINNT':
SOURCES += ['win.cpp']
elif CONFIG['OS'] == 'OSX':
SOURCES += ['osx.cpp']
else:
SOURCES += ['unix.cpp']
I like that it uses the Python language rather than coming up with its own DSL for handling conditionality or things where you need to do loops, and by splitting up the steps in the way that it does, it keeps the build system fairly declarative. But don't look under the hood, because the things under the hood are fiendishly complex and it's way too complicated to be usable for a simple project.Is there a build system where one would point to a one source file and it would find its way around the whole thing? Things it wouldn't be able to deduce would be given as a comment or some preprocessor fluff. Basically implementing module system. Or maybe I did not think it through too much.
Just my two cents but most of my time spent with build systems isn't on the basics. Most of my time is spent scripting things: probing for dependencies, build hooks, packaging, code signing, and other misc tasks. Right now cmkr doesn't appear to support scripting. I'm unsure a declarative language like TOML will suffice. Might I recommend you research premake which is a build system based on Lua. Lua is a good choice because of its scripting flexibility.
I almost think there's no way to make a good build system...without making it far harder when you need to do something slightly different. Rust has a simple build system, but it really depends on the package manager, and custom build setup is a build script in Rust...so the build system has to build the build script...