Published: 2023-03-08
This blog post explains how to use a custom C++ toolchain based on clang 12 with libc++-12 in Bazel on Ubuntu 20.04.
There are many reasons why one many not want to use the default C++ compiler in Bazel:
- The default compiler shipped with your distribution might be old and you want to use a new one
- You want to ensure that a specific version of a compiler is used
- You want to use a different C++ standard library (e.g. libc++ instead of libstdc++)
The instructions at Bazel Tutorial: Configure C++ Toolchains are an excellent starting point. Here’s how I got them working for clang 12 with libc++-12 on Ubuntu 20.04:
- Install the necessary packages with
sudo apt install clang-12 libc++-12-dev libc++abi-12-dev - Create the file
//toolchain:clang12_cc_toolchain_config.bzlwith the following contents:
# //toolchain:clang12_cc_toolchain_config.bzl
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
load(
"@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
"feature",
"flag_group",
"flag_set",
"tool_path",
)
def _impl(ctx):
tool_paths = [
tool_path(
name = "gcc",
path = "/usr/bin/clang-12",
),
tool_path(
name = "ld",
path = "/usr/bin/ld",
),
tool_path(
name = "ar",
path = "/usr/bin/ar",
),
tool_path(
name = "cpp",
path = "/usr/bin/clang-cpp-12",
),
tool_path(
name = "gcov",
path = "/usr/bin/gcov",
),
tool_path(
name = "nm",
path = "/usr/bin/nm",
),
tool_path(
name = "objdump",
path = "/usr/bin/objdump",
),
tool_path(
name = "strip",
path = "/usr/bin/strip",
),
]
features = [
feature(
# We prefer libc++ to libstdc++
name = "use_libc++_as_stdlib",
enabled = True,
flag_sets = [
flag_set(
actions = [
ACTION_NAMES.cpp_compile,
],
flag_groups = ([
flag_group(
flags = [
"-stdlib=libc++",
],
),
]),
),
flag_set(
actions = [
ACTION_NAMES.cpp_link_executable,
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
],
flag_groups = ([
flag_group(
flags = [
"-lc++",
],
),
]),
),
],
),
]
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
features = features,
cxx_builtin_include_directories = [
"/usr/lib/llvm-12/include",
# On some machines the include files are in 12.0.0; others 12.0.1...
# we include both to be safe
"/usr/lib/llvm-12/lib/clang/12.0.0/include",
"/usr/lib/llvm-12/lib/clang/12.0.1/include",
"/usr/include",
"/usr/local/include",
],
toolchain_identifier = "clang12-toolchain",
host_system_name = "local",
target_system_name = "local",
target_cpu = "k8",
target_libc = "unknown",
compiler = "clang",
abi_version = "unknown",
abi_libc_version = "unknown",
tool_paths = tool_paths,
)
clang12_cc_toolchain_config = rule(
implementation = _impl,
attrs = {},
provides = [CcToolchainConfigInfo],
)
- Create a
//toolchain:BUILD.bazelwith the following contents:
# //toolchain:BUILD.bazel
load(":clang12_cc_toolchain_config.bzl", "clang12_cc_toolchain_config")
filegroup(name = "empty")
clang12_cc_toolchain_config(name = "clang12_toolchain_config")
cc_toolchain(
name = "clang12_k8_toolchain",
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
linker_files = ":empty",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
toolchain_config = ":clang12_toolchain_config",
toolchain_identifier = "clang12-toolchain",
)
cc_toolchain_suite(
name = "clang12_suite",
toolchains = {
"k8": ":clang12_k8_toolchain",
},
)
- Modify
//.bazelrcto use our clang 12 toolchain:
# ~/.bazelrc
# Build C++ binaries using clang-12 toolchain
build --crosstool_top=//toolchain:clang12_suite