Configuring Bazel Build With GNU C/C++ on Windows

Igor Machado
The Startup
Published in
5 min readNov 14, 2020

The Bazel Build system was originated from Google, being released afterward to the general public as open-source. It is important for languages such as C/C++ that depend on compile/linking phases, which often depend on other third-party projects/libraries. In this article, we demonstrate how to configure Bazel on Windows to compile and execute codes written in C/C++ (with GNU toolchain).

Note 1: The files/installers used in this tutorial are available at: https://github.com/igormcoelho-learning/config-bazel-c-cpp-gnu-windows

Note 2: If you want to practice directly via GitHub Classroom, follow this invitation: https://classroom.github.com/a/4cxjjKP7

To make the process even simpler, we propose installing Bazel through NPM packages (if you already have NPM/node.js installed in Windows, feel free to skip this step).

To install NPM and node.js, visit website https://node.js, or follow the direct link to version 14.15.0 LTS: https://nodejs.org/dist/v14.15.0/node-v14.15.0-x64.msi

Instalação do Node.js (não é necessário instalar o Chocolatey)

After installing NPM, you can open some terminal in Windows (cmd.exe or PowerShell) and execute the following command:

npm install -g @bazel/bazelisk
Installing Bazel through bazelisk repository

After installing, check the version through the following command (first execution must force bazel to update):

bazel --version
Version 3.7.0 in Bazel

Nice! Bazel is already installed in your system.

Now let’s check the integration of Bazel with GNU toolchain GNU for C/C++. To download MinGW, in case you don’t have it, you can find on website: http://mingw.org/download/installer

Instalação do MinGW (toolchain compilação C/C++ do GNU)
Basic packages for C/C++ (MinGW installation)
Do not forget to click: Installation -> Apply Changes

Now, C/C++ compiler from GNU must be available. To check it, open a new terminal (cmd.exe or PowerShell) and type the command:

g++ --version
installed g++ (version 8.1.0)

To test Bazel with C/C++, we consider Visual Studio Code, an open-source IDE quite popular these days (in 2020). Download at: https://code.visualstudio.com/

VSCode installation (in Portuguese)

Open VSCode, and in left Extensions menu, install extensions for C/C++ and Bazel.

Installing C/C++ extension and Bazel BUILD at VSCode IDE

The VSCode will require the installation of Buildifier. Download the buildifier.exe through the link: https://github.com/bazelbuild/buildtools/releases

VSCode Bazel extension requires Buildifier

In this tutorial, the buildifier.exe was placed at C:\mingw64\bin, together with GNU C/C++ compiler (to avoid further PATH configurations).

buildifier.exe placed together with C/C++ toolchain (prevents extra PATH configurations)

Now, it’s time to test the integrations.

Now we test again the versions for bazel and g++, now directly at VSCode. Curiously, bazel complained of some UnauthorizedAccess (g++ was executed without any issue). To circumvent this issue, open VSCode as Administrator, and inside some terminal (Terminal -> New Terminal) execute the following command:

Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy RemoteSigned

For some strange reason, the message “spawn bazel ENOENT” may appear (see image below).

Error: spawn bazel ENOENT

To fix it, download the binary executable bazel-3.7.0-windows-x86_64.exe directly from Bazel source: https://github.com/bazelbuild/bazel/releases

Important: file must be renamed as bazel.exe and put in directory C:\mingw64\bin (to prevent further modifications on PATH).

bazel.exe placed at C:\mingw64\bin (to prevent PATH modifications)

A working example of bazel with GNU C++ can be seen below.

Create a file named olamundo.cpp with the following content (note that “Ola Mundo” is “Hello World” in Portuguese):

#include<iostream>int main(){std::cout << "Ola mundo!" << std::endl;return 0;}

To compile code with g++, execute:

g++ olamundo.cpp -o ola.exe
Compiling with g++ at VSCode

To build with bazel in a similar way, it is necessary to create a file named BUILD.bazel with the following content:

load("@rules_cc//cc:defs.bzl", "cc_binary")package(default_visibility = ["//visibility:public"],)cc_binary(name = "ola",srcs = ["olamundo.cpp"])

It is also necessary to create a file named WORKSPACE.bazel in the root of your project:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

To build, click at corresponding option BAZEL BUILD TARGETS (with right click on “build”) or execute command: bazel build …

bazel build …

To execute code, use command: bazel run :ola

Output “ola mundo” through command bazel build :ola

Note that executables were stored inside folder bazel-bin.

Everything working so far, but an important detail is missing… up to now, we have used MSVC compiler, as it can be seen on logs for “bazel build …” (after command “bazel clean”)

Using compiler MSVC (as standard)

To use GNU C/C++ toolchain, it is necessary to create a file named .bazelrc with the following content:

build --compiler=mingw-gcc

To see the available toolchains:

bazel query @local_config_cc//:toolchain --output=build

Download MSYS2 in https://www.msys2.org, or by direct link: https://repo.msys2.org/distrib/x86_64/msys2-x86_64-20200903.exe

For some reason, the content of C:\msys64\mingw64\bin was empty. This created an error in bazel build:

Error in bazel build, due to empty directory C:\msys64\mingw64\bin

To solve this problem, copy the content from C:\mingw64 inside C:\msys64

copy folder mingw64 and paste it inside folder msys64

Finally, toolchain GNU C/C++ must work (see image below):

bazel build working with GNU C/C++ toolchain

We finish the tutorial with a screen from VSCode and everything working correctly:

VSCode with bazel and GNU C/C++ toolchain on Windows

The path may have been a little tortuous, and maybe there are more direct ways to make this work… anyway, our goal was hopefully fulfilled!

Feel free to comment, see you next time ;)

P.S.: An important advice from Fellipe Pessanha (in comments): avoid whitespaces in file names and in file paths when dealing with bazel. So, instead of having “hello world.cpp”, try “hello-world.cpp”.

--

--