Build status

Rules for building C/C++ projects using foreign build systems inside Bazel projects.

This is not an officially supported Google product (meaning, support and/or new releases may be limited.)


Documentation for all rules and providers are available here

Bazel versions compatibility

Works with Bazel after 3.4.0 without any flags.

Note that the rules may be compatible with older versions of Bazel but support may break in future changes as these older versions are not tested.


For more generalized updates, please see or checkout the release notes of current or previous releases

Building CMake projects

  • Build libraries/binaries with CMake from sources using cmake_external rule
  • Use cmake_external targets in cc_library, cc_binary targets as dependency
  • Bazel cc_toolchain parameters are used inside cmake_external build
  • See full list of cmake_external arguments below 'example'
  • cmake_external is defined in ./tools/build_defs
  • Works on Ubuntu, Mac OS and Windows(* see special notes below in Windows section) operating systems

Example: (Please see full examples in ./examples)

The example for Windows is below, in the section 'Usage on Windows'.

  • In WORKSPACE.bazel, we use a http_archive to download tarballs with the libraries we use.
  • In BUILD.bazel, we instantiate a cmake_external rule which behaves similarly to a cc_library, which can then be used in a C++ rule (cc_binary in this case).

In WORKSPACE.bazel, put

workspace(name = "rules_foreign_cc_usage_example")

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

# Rule repository, note that it's recommended to use a pinned commit to a released version of the rules
   name = "rules_foreign_cc",
   sha256 = "c2cdcf55ffaf49366725639e45dedd449b8c3fe22b54e31625eb80ce3a240f1e",
   strip_prefix = "rules_foreign_cc-0.1.0",
   url = "",

load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")

# This sets up some common toolchains for building targets. For more details, please see

    name = "all_srcs",
    srcs = glob(["**"]),
    visibility = ["//visibility:public],

# pcre source code repository
    name = "pcre",
    build_file_content = _ALL_CONTENT,
    strip_prefix = "pcre-8.43",
    urls = [
    sha256 = "0b8e7465dc5e98c757cc3650a20a7843ee4c3edf50aaf60bb33fd879690d2c73",

And in the BUILD.bazel file, put:

load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")

    name = "pcre",
    cache_entries = {
        "CMAKE_C_FLAGS": "-fPIC",
    lib_source = "@pcre//:all_srcs",
    out_static_libs = ["libpcre.a"],

then build as usual:

bazel build //:pcre

Usage on Windows

When using on Windows, you should start Bazel in MSYS2 shell, as the shell script inside cmake_external assumes this. Also, you should explicitly specify make commands and option to generate CMake crosstool file.

The default generator for CMake will be detected automatically, or you can specify it explicitly.

The tested generators: Visual Studio 15, Ninja and NMake. The extension .lib is assumed for the static libraries by default.

Example usage (see full example in ./examples/cmake_hello_world_lib): Example assumes that MS Visual Studio and Ninja are installed on the host machine, and Ninja bin directory is added to PATH.

    # expect to find ./lib/hello.lib as the result of the build
    name = "hello",
    # This option can be omitted
    generate_args = [
        "-G \"Visual Studio 15 2017\"",
        "-A Win64",
    lib_source = ":srcs",

    name = "hello_ninja",
    # expect to find ./lib/hello.lib as the result of the build
    lib_name = "hello",
    # explicitly specify the generator
    generate_args = ["-GNinja"],
    lib_source = ":srcs",

    name = "hello_nmake",
    # explicitly specify the generator
    generate_args = ["-G \"NMake Makefiles\""],
    lib_source = ":srcs",
    # expect to find ./lib/hello.lib as the result of the build
    out_static_libs = ["hello.lib"],

Design document

External C/C++ libraries rules