Separating builds for different configs with Bazel


Welcome to the next pikoTutorial !

Let’s consider a simple project with the following structure:

project/
├── .bazelrc
├── BUILD
├── main.cpp
├── WORKSPACE

The main function has 2 compile switches:

#include <iostream>

int main(int argc, char** argv)
{
#ifdef FEATURE_1_ENABLED
    std::cout << "Hello from feature 1 code!" << std::endl;
#endif
#ifdef FEATURE_2_ENABLED
    std::cout << "Hello from feature 2 code!" << std::endl;
#endif
}

And we have 2 separate Bazel configurations including these switches:

build:feature_1 --compilation_mode=dbg
build:feature_1 --copt=-DFEATURE_1_ENABLED

build:feature_2 --compilation_mode=opt
build:feature_2 --copt=-DFEATURE_2_ENABLED

When we build the application with the following command:

bazel build --config=feature_1 //:my_app

I can run the application by invoking:

./bazel-bin/my_app

But as soon as I build the second configuration of the application with command:

bazel build --config=feature_2 //:my_app

I lost my previous binary because the build artifacts have been overwritten. A solution for that is separation of build directories with --symlink_prefix option added in the .bazelrc file:

build:feature_1 --compilation_mode=dbg
build:feature_1 --copt=-DFEATURE_1_ENABLED
build:feature_1 --symlink_prefix=./build/feature_1/

build:feature_2 --compilation_mode=opt
build:feature_2 --copt=-DFEATURE_2_ENABLED
build:feature_2 --symlink_prefix=./build/feature_2/

From now on, at every point of time, you can run the first version of the application with command:

./build/feature_1/bin/my_app

And the second version with command:

./build/feature_2/bin/my_app

They will no longer be overwritten.