Configuring Bazel Build With GNU C/C++ on Windows
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
After installing NPM, you can open some terminal in Windows (cmd.exe or PowerShell) and execute the following command:
npm install -g @bazel/bazelisk
After installing, check the version through the following command (first execution must force bazel to update):
bazel --version
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
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
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/
Open VSCode, and in left Extensions menu, install extensions for C/C++ and Bazel.
The VSCode will require the installation of Buildifier. Download the buildifier.exe through the link: https://github.com/bazelbuild/buildtools/releases
In this tutorial, the buildifier.exe was placed at C:\mingw64\bin, together with GNU C/C++ compiler (to avoid further 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
For some strange reason, the message “spawn bazel ENOENT” may appear (see image below).
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).
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
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 …
To execute code, use command: bazel run :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”)
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:
To solve this problem, copy the content from C:\mingw64 inside C:\msys64
Finally, toolchain GNU C/C++ must work (see image below):
We finish the tutorial with a screen from VSCode and everything working correctly:
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”.