I found myself still using simple Makefiles on top of CMake presets, for things like:
- having default generators for each platform without making a different preset for each platform
- setting the number of jobs to the number of cores on the machine
- invoking a configure preset automatically if its binary dir doesn’t exist when the user invokes a build preset
- invoking a build preset with a certain target specified, so I don’t have to write another preset to do that
- simple
cleanoperations
Make provided all the functionality I need on Unix, but it’s not very portable to Windows, and it was more code to maintain than I would’ve liked.
So I decided to write a little tool that is specially tuned for these kinds of use cases:
bake is a simple command line utility that invokes cmake presets. The syntax is bake <kind>[<name>], where kind is config, build, or test, and name is the name of a non-hidden preset of the corresponding kind in the working directory’s CMakePresets.json.
It works with absolutely no configuration at all – you can just use the bake <kind>[<name>] syntax and it should give you sensible defaults. But if you wish, it also accepts a barebones configuration file called a Bakefile:
-
It’s a series of sections containing options
-
Lines starting with
#and empty lines are ignored -
Lines starting with
*or-are options in a section -
All other lines start a new section
Valid sections are:
- Generators: specify CMake generators to be used on Mac, Windows, and Linux
- Aliases: specify a set of one-word aliases for other actions, for example
all: build[all]means you can typebake allinstead ofbake build[all]. For aliases of build presets, you can also use an arrow->to specify a certain target, for exampleonlyOne: build[all] -> target1meansbake onlyOnewill expand tocmake --build --preset all --target target1. - Clean: a set of files or directories, relative to the Bakefile directory, that will be removed when
bake cleanis invoked.bake cleanalso traverses all subdirectories recursively, and for any subdir containing a Bakefile, evaluates those clean commands as well. - Wipe: similar to clean, but intended for wiping persistent caches, like fetched sources of dependencies.
- Logs: If specified, names a directory relative to the Bakefile directory where bake will write logs of all cmake config and test runs. This logs directory is automatically removed by
bake clean.
All sections are optional, and you can use bake without writing a Bakefile by sticking with the bake <kind>[<name>] syntax.
Example Bakefile:
Generators:
* Mac: Xcode
* Windows: Visual Studio 16 2019
* Linux: Ninja
Aliases:
* config: config[default]
* all: build[all]
* ios: build[ios]
* plugins: build[all] -> ALL_PLUGINS
* apps: build[all] -> ALL_APPS
* tests: test[all]
Clean:
* Builds/
Wipe:
* Cache/
Logs:
* logs
The entire goal here is to be lightweight, self documenting, and cross platform.
I hope someone finds this useful – any suggestions and feedback are welcome, and the code is completely free to use in any capacity!