Bazel client

Bazel is a “fast, scalable, multi-language and extensible build system” that supports remote build execution using the remote execution API (REAPI) v2 since its 0.17 release.

Configuration

Bazel accepts many options that can either be specified as command line arguments when invoking the bazel tool or stored in a .bazelrc configuration file. In order to activate remote build execution, the bazel build subcommand needs to be given specific build options, including:

  • --remote_executor: remote execution endpoint’s location, {host}:{port}.

  • --remote_instance_name: remote execution instance’s name.

  • --spawn_strategy: action execution method.

Spawn strategies need to be set to remote for remote execution.

As an example, in order to activate remote execution on the main instance of the remote execution server available at controller.grid.build on port 50051 you should amend your .bazelrc with:

build --spawn_strategy=remote --remote_executor=grpc://controller.grid.build:50051 --remote_instance_name=main

Example build

The bazel-examples repository contains example Bazel workspaces that can be used for testing purpose. We’ll focus here on instructions on how to build the stage3 CPP example running Bazel and BuildGrid on your local machine, compiling the C++ source code using host-tools.

First, you need to checkout the bazel-examples repository sources:

git clone https://github.com/bazelbuild/examples.git bazel-examples

Next, change the current directory to the Bazel workspace root:

cd bazel-examples/cpp-tutorial/stage3

Hint

All the commands in the instructions below are expected to be executed from that root directory (the stage3 example workspace’s root directory).

Before running Bazel and building the example workspace, you’ll have to setup and run a BuildGrid server and bot. A minimal server’s configuration is given below, paste it in a server.yml file in the root directory:

server:
  - !channel
    address: localhost:50051
    insecure-mode: true

connections:
  - !sql-connection &sql
    connection-string: sqlite:///./example.db
    automigrate: yes
    connection-timeout: 15

storages:
  - !lru-storage &main-storage
    size: 512MB

caches:
  - !lru-action-cache &main-action
    storage: *main-storage
    max-cached-refs: 256
    allow-updates: true

schedulers:
  - !sql-scheduler &scheduler
    sql: *sql
    storage: *main-storage
    action-cache: *main-action
    poll-interval: 0.5
    max-execution-timeout: 7200

instances:
  - name: main

    services:
      - !action-cache
        cache: *main-action

      - !execution
        scheduler: *scheduler

      - !cas
        storage: *main-storage

      - !bytestream
        storage: *main-storage

This defines a single main server instance implementing a ContentAddressableStorage (CAS) + ByteStream service together with an Execution + ActionCache service, both using the same in-memory storage. You can then start the BuildGrid server daemon using that configuration by running:

bgd server start server.yml

In order to perform the actual build work, you need to attach a worker bot to that server for that main instance. Once you’ve make sure that your machine has gcc installed, run:

buildbox-casd --cas-remote=http://localhost:50051 --bind=127.0.0.1:50011 ~/casd &
buildbox-worker --buildbox-run=buildbox-run-hosttools --bots-remote=http://localhost:50051 \
   --cas-remote=http://127.0.0.1:50011 --request-timeout=30 my_bot

The BuildGrid server is now ready to accept jobs and execute them. Bazel needs some configuration in order to run remote builds. Below are the minimal build options you should use, paste them in a .bazelrc file in the root directory:

build --spawn_strategy=remote --remote_executor=grpc://localhost:50051 --remote_instance_name=main

This activates Bazel’s remote execution mode and points to the main remote execution server instance at localhost:50051.

You can finally have Bazel to build the example workspace by running:

bazel build //main:hello-world

You can verify that the example has been successfully built by running the generated executable. Simply invoke:

./bazel-bin/main/hello-world