Skip to content
/ cpp Public template

Template for starting a Bazel project with C & C++

Notifications You must be signed in to change notification settings

bazel-starters/cpp

Repository files navigation

C/C++ Bazel Starter

# This is executable Markdown that's tested on CI.
# How is that possible? See https://gist.github.com/bwoods/1c25cb7723a06a076c2152a2781d4d49
set -o errexit -o nounset -o xtrace
alias ~~~=":<<'~~~sh'";:<<'~~~sh'

This repo includes:

  • 🧱 Latest version of Bazel and dependencies
  • 📦 Curated bazelrc flags via [bazelrc-preset.bzl]
  • 🧰 Developer environment setup with [bazel_env.bzl]
  • 🎨 clang-format and clang-tidy, using rules_lint
  • ✅ Pre-commit hooks for automatic linting and formatting

Note

You can customize languages and features with the interactive wizard in the aspect init command. init is an alternative to this starter repo, which was generated using the 'cpp' preset. See https://docs.aspect.build/cli/overview

Setup dev environment

First, we recommend you setup a Bazel-based developer environment with direnv.

  1. install https://direnv.net/docs/installation.html
  2. run direnv allow and follow the prompts to bazel run //tools:bazel_env

This isn't strictly required, but the commands which follow assume that needed tools are on the PATH, so skipping direnv means you're responsible for installing them yourself.

Try it out

To start with, let's get the simplest possible program to execute.

Lets create an application that prints “hello world” to the standard out:

mkdir src
>src/hello.c cat <<EOF
#include <stdio.h>

int main(int argc, char const *argv[])
{
    printf("hello world!");
    return 0;
}
EOF

Next run the BUILD file generator to produce a cc_binary target:

bazel run gazelle

You can now run the program to see the output.

bazel run src:hello

Add a dependency

Many libraries already have BUILD files in the Bazel Central Registry (BCR). For example, we can search for the libmagic, and find that it’s there:

https://registry.bazel.build/modules/libmagic

To install it, just add to MODULE.bazel

echo 'bazel_dep(name = "libmagic", version = "5.46.bcr.4")' >> MODULE.bazel

Let's add another program src/magic.c that depends on libmagic:

>src/magic.c cat <<EOF
#include <stdio.h>
#include <stdlib.h>
#include <magic.h>

int main(int argc, char *argv[]) {
    // Check if filename is provided
    if (argc != (int)2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return 1;
    }

    // Initialize magic handle
    magic_t magic = magic_open(MAGIC_MIME_TYPE);
    if (magic == NULL) {
        fprintf(stderr, "Failed to initialize libmagic\n");
        return 1;
    }

    // Load magic database
    if (magic_load(magic, NULL) != 0) {
        fprintf(stderr, "Cannot load magic database: %s\n", magic_error(magic));
        magic_close(magic);
        return 1;
    }

    // Get MIME type
    const char *mime_type = magic_file(magic, argv[1]);
    if (mime_type == NULL) {
        fprintf(stderr, "Error determining MIME type: %s\n", magic_error(magic));
        magic_close(magic);
        return 1;
    }

    // Print result
    printf("MIME type: %s\n", mime_type);

    // Cleanup
    magic_close(magic);
    return 0;
}
EOF

Now re-generate the BUILD file:

bazel run gazelle

If we run the program now, we find that it fails with Cannot load magic database: Size of '/usr/share/file/magic.mgc' 7273344 is not a multiple of 432 this is because it has a runtime dependency on locating a file it expects to be part of the operating system distribution.

We can set the 'MAGIC' environment variable to a Bazel-managed path instead:

buildozer 'add data @libmagic//:magic.mgc' src:magic
buildozer 'dict_set env MAGIC:"$(rootpath\ @libmagic//:magic.mgc)"' src:magic

Now running the program produces expected output:

output=$(bazel run src:magic $PWD/BUILD)
[ "$output" = "MIME type: text/plain" ] || {
    echo >&2 "Wanted output 'MIME type: text/plain' but got '${output}'"
    exit 1
}

Linting

FIXME(alexeagle): aspect-build/rules_lint#703 for cpp aspect lint

About

Template for starting a Bazel project with C & C++

Topics

Resources

Stars

Watchers

Forks