Using a Pigweed module in an existing Bazel project#

This guide explains how to start using a Pigweed module in your existing Bazel-based C or C++ project. We’ll assume you’re familiar with the build system at the level of the Bazel tutorial.

Add Pigweed as a WORKSPACE dependency#

Add Pigweed as a git_repository in your WORKSPACE:

  name = "pigweed",
  commit = "c00e9e430addee0c8add16c32eb6d8ab94189b9e",
  remote = "",

(You can find the latest tip-of-tree commit in the History tab in CodeSearch.)

If you manage your dependencies as submodules, you can add Pigweed as a submodule, too, and then add it to the WORKSPACE as a local_repository:

  name = "pigweed",
  path = "third_party/pigweed",

We don’t yet publish releases that could be pulled in using http_archive.

We don’t support bzlmod yet. See

If either of these limitations is important to you, please reach out to us on chat.

Use Pigweed in your project#

Let’s say you want to use pw::Vector from pw_containers, our embedded-friendly replacement for std::vector.

  1. Include the header you want in your code:

    #include "pw_containers/vector.h"
  2. Look at the module’s build file to figure out which build target you need to provide the header and implementation. For pw_containers/vector.h, it’s //pw_containers:vector.

  3. Add this target to the deps of your cc_library or cc_binary:

      name = "my_library",
      srcs  = [""],
      hdrs = ["my_library.h"],
      deps = [
        "@pigweed//pw_containers:vector",  # <-- The new dependency
  4. Add a dependency on @pigweed//pw_build:default_link_extra_lib to your final binary target. See Libraries required at linktime for a discussion of why this is necessary, and what the alternatives are.

      name = "my_binary",
      srcs  = [""],
      deps = [
        "@pigweed//pw_build:default_link_extra_lib",  # <-- The new dependency

Configure backends for facades you depend on#

Pigweed makes extensive use of Facades and backends, and any module you choose to use will likely have a transitive dependency on some facade (typically pw_assert or pw_log). Continuing with our example, pw::Vector depends on pw_assert.

In Bazel, facades already have a default backend (implementation) that works for host builds (builds targeting your local development machine). But to build a binary for your embedded target, you’ll need to select a suitable backend yourself.

Fortunately, the default backend for pw_assert is pw_assert_basic, which is a suitable place to start for most embedded targets, too. But it depends on pw_sys_io, another facade for which you will have to choose a backend yourself.

The simplest way to do so is to set the corresponding label flag when invoking Bazel. For example, to use the pw_sys_io_baremetal_stm32f429 backend for pw_sys_io provided in upstream Pigweed:

$ bazel build \
    --@pigweed//targets/pw_sys_io_backend=@pigweed//pw_sys_io_baremetal_stm32f429 \

You can also define backends within your own project. (If Pigweed doesn’t include a pw_sys_io backend suitable for your embedded platform, that’s what you should do now.) See Facades and backends tutorial for a tutorial that dives deeper into facade configuration with Bazel.