Introducing bake 2.3: Windows, Recursive builds & more

Sander Mertens
6 min readFeb 18, 2019

In the month and a half that has passed since bake’s initial release in January, an incredible number of things have changed. The latest 2.3 release of bake contained over 200 commits, over one third of the total number of commits in the bake repository! It was the most complex and time consuming release to date which involved multiple people, a huge platform port, an overhaul of the package store, and tons of improvements and new features that will make building C and C++ projects effortless!

Without further ado, let’s take a look at what bake has been up to.

Windows support. This is no doubt the headline feature of bake 2.3. It took multiple people a whole month to port bake’s modest codebase to Windows.

Bake’s Windows port natively invokes the visual studio compiler, unlike tools like CMake or premake (which generate Visual Studio project files). This lets you use any editor you like, just as you would on Linux and MacOS.

Templates. A template is a bake project that contains boiler plate code which can be used as a starting point for new projects. Working with templates in bake is super easy. This command creates a new template:

$ bake new my_template --template

You can then directly use that template when you create a new project like so:

$ bake new my_app -t my_template

Template projects can use bake’s template functions, which you may have seen already in the project.json files. This example shows how you can use bake’s template functions in code:

#include <include/${id base}.h>int main(int argc, char *argv[]) {
printf("Hello ${id}!\n");
return 0;
}

You can create different templates for different languages under the same name, so that bake automatically selects the right template based on the language of the project that you’re creating.

Recursive builds. Have you ever been in a situation where a project had a large dependency tree, and you were working on multiple of those dependencies at the same time? If that is the case, recursive building is going to change your life (at least the coding part of it). With recursive builds, you can build the entire dependency tree of your project, with a single command.

The feature builds upon bake’s capability to automatically discover projects, and build them in the right order based on their dependencies. Recursive building goes one step further, as bake will build the entire dependency tree, regardless of whether dependencies are discoverable from where bake was invoked.

Sounds complicated right? Fortunately it is really simple to use. To build your project and all of its dependencies, simply add -r to your build command:

$ bake my_app -r
[ build] package example_package => 'src/example_package'
[ 100%] main.c
[ build] application example => 'example'
[ 100%] main.c

The cool thing is that it works not just for builds, but other commands as well:

$ bake clean example -r
[ clean] package example_package => 'src/example_package'
[ clean] application example => 'example'

Another useful application of recursive building is when you are working with multiple build configurations. Bake doesn’t mix binaries between say, debug builds and release builds. If you wanted a release mode version of your application, you had to manually build all dependencies in release as well.

No more with recursive building. Simply rebuild your application and its dependencies like this:

$ bake example -r --cfg release

Running applications. Bake can automatically run the right binary for application projects, like this:

$ bake run example

This is much easier than manually typing the path to the generated binary all the time. Furthermore, because projects are stored in the bake environment, bake can run any project from any location!.

The run command automatically builds the project before it runs it, which ensures that what you run is always the latest version of your code. Recursive building has been automatically enabled for the run command, so to run the latest version of your project with all its dependencies, simply do:

$ bake run example --cfg release

Bake has an interactive mode, which monitors your project for any changes in its source files, and automatically rebuilds and restarts your application when a change is detected. Interactive mode can be enabled simply by adding --interactive to your command:

$ bake run example --interactive

We’re really excited about the potential capabilities of this feature, so expect some cool things down the road!

Precompiled headers. When a project contains many source files, and each source file includes a similar set of header files, a lot of the compilation time is spent on parsing the header files. For large projects, this can significantly increase build times. The solution to this problem is precompiled headers, which requires a project to have a main header file that each source file includes, which contains all of the common project includes.

In bake, projects are already structured in a way where each project has a single main header file that includes all of the projects dependencies, and other public header files. Bake 2.3 automatically precompiles this header, which for some projects has resulted in build times that are twice as fast!

For now, precompiled headers is only enabled when using clang, with support for gcc and msvc on the roadmap. The good thing about this feature? You have to do absolutely nothing to enable it, as bake automatically does this in the background. You may notice projects build quite a bit faster with 2.3!

Improved bake list. Bake list is a command that inspects the bake environment and shows you all projects currently installed. It has been available since bake’s initial release, but got a big overhaul in 2.3. Here is an example of the output of bake list in 2.3:

$ bake listListing projects for platform:
* x64-Darwin
Packages & Applications:
C bake.lang.c => all
C bake.lang.cpp => all
P bake.util => all
A example => [release, debug]
P example_package => [release, debug]
C sdl2 => all
C sfml2 => all
Templates:
T sdl2.basic => [cpp, c]
T reflecs.basic => [c]
Summary:
applications: 1, packages: 6, templates: 2

If for some reason something is wrong with a project, this will also show up:

P  example_package => !missing binary!

If you have many projects with errors in your environment and you want to keep things clean, you can simply run this command:

$ bake cleanup

This removes any projects with errors from the environment. Like bake uninstall, bake cleanup won’t actually delete your source code from disk (of course!), it will just remove its data from the bake environment.

Bake environment. This is more of a topic for bake developers, but since it got such a major overhaul in the latest version, I wanted to shine a little light on it, as the redesign provides us with a powerful platform for new features like recursive builds, and lays the foundation for cross compilation.

The bake environment is the place where bake stores all of its metadata. It is usually located in ~/bake and contains the project.json files of projects, together with the source code location, include files, binaries and much more.

In previous versions, bake stored all of the projects information in directories identified by the operating system, CPU architecture and build configuration. That caused packages to become undiscoverable when using a different configuration, which was not intuitive. In the new design, data that is shared across platforms is stored in a common location, whereas data specific to a platform (like binaries) are stored in a platform-specific location.

Together with this redesign, the API that manages the bake environment was also overhauled. In previous versions the management of the bake environment was scattered across files, whereas now all of the intelligence is concentrated in a single, coherent API. This API is at the core of bake, and its redesign will make it a lot easier to build new features.

Bake has come a long way in a short time, and there are no signs of slowing down! We have been fortunate enough to receive great feedback and pull requests from the community on features they would like to see and we have been, and are working hard on realizing them. And, since we are fervent bake users ourselves, we have our own wishlist of things that will take bake beyond what you thought a build system could do... stay tuned!

Thanks for reading! If you want to check out bake, the GitHub repository is here: https://github.com/SanderMertens/bake. If you like what you see, consider giving it a star, or better yet, help us make bake better by contributing issues and pull requests!

--

--

Sander Mertens

Author of Flecs, an Entity Component System for C and C++