Giter Club home page Giter Club logo

bazel_rules_cc_toolchain's Introduction

rules_cc_toolchain

CI

An opinionated hermetic host toolchain for Bazel and C++. Currently this toolchain supports;

  • Completely sandboxed linux builds (i.e. no system deps).
  • Code coverage and combined lcov reports e.g. bazel coverage //...
  • Static analysis (with clang-tidy). Read the docs here.

The toolchain is modular enough that you should be able to BYO;

  • Compiler and runtime
  • libc
  • libc++ / libc++abi
  • Startup libraries (e.g. crt1.o)
  • Injected toolchain headers and libs

Getting Started

Add the following to your workspace file;

# WORKSPACE
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

# Set up host hermetic host toolchain.
git_repository(
    name = "rules_cc_toolchain",
    commit = "dd9265e3ce0daa444911040430bd716076869b34",
    remote = "https://github.com/silvergasp/rules_cc_toolchain.git",
)

load("@rules_cc_toolchain//:rules_cc_toolchain_deps.bzl", "rules_cc_toolchain_deps")

rules_cc_toolchain_deps()

load("@rules_cc_toolchain//cc_toolchain:cc_toolchain.bzl", "register_cc_toolchains")

register_cc_toolchains()

and the following to your '.bazelrc';

# Enforce strict checks of deprecated toolchain api.
build --incompatible_require_linker_input_cc_api

# Use new cc toolchain resolution api
build --incompatible_enable_cc_toolchain_resolution

# Code coverage support
coverage --combined_report=lcov
coverage --experimental_use_llvm_covmap
coverage --experimental_generate_llvm_lcov
coverage --incompatible_cc_coverage

Defaults and config

This repository provides a set of sane defaults to make up a complete toolchain. By default;

Library Provider
libc Debian stretch sysroot (GNU glibc6)
libc++ LLVM 12.0.0 libc++
libc++abi LLVM 12.0.0 libc++abi
libunwind Debian stretch sysroot (GNU gcc6 compiler runtime)
Startup Libraries Debian stretch libcrt (GNU glibc6)

This can be viewed in more detail by inspecting //config/config:BUILD.bazel.

Bring your own system libraries (Advanced)

This toolchain supports bringing your own precompiled system libraries. Implementing this can be somewhat complicated and it is unlikely that we will support specific combinations of libraries on request, although PR's here are welcome.

An example of how you might include your own version of libc++ is shown below.

Add a third_party dependency directory for your libc++ build definitions.

mkdir third_party
touch third_party/clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04.BUILD

Add the following to your WORKSPACE file.

# WORKSPACE
http_archive(
    name = "clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04",
    build_file = "//third_party:clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04.BUILD",
    sha256 = "9694f4df031c614dbe59b8431f94c68631971ad44173eecc1ea1a9e8ee27b2a3",
    strip_prefix = "clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04",
    url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz",
)

From here you will need to add in your definitions that specify the library files that are provided by this implementation of libc++.

# third_party:clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04.BUILD
load(
    "@rules_cc_toolchain//cc_toolchain:cc_toolchain_import.bzl",
    "cc_toolchain_import",
)

cc_toolchain_import(
    name = "llvm_libcxx",
    # All the headers to be included with this library
    hdrs = glob(["include/c++/v1/**"]),
    # It is common for a library e.g. libc++.so to actually just be a linker
    # script that points to a different library as is the case here where,
    # 'lib/libc++.so' is a linker script that points to 'lib/libc++.so.1'. 
    # This is done so that dynamic linker can ensure that it is linking 
    # against a compatible version of the library ABI (in this case version 1).
    additional_libs = [
        "lib/libc++.so.1",
    ],
    includes = ["include/c++/v1"],

    # NOTE: If one of static_library or shared_library is omitted this toolchain
    # will default to the other. This is useful if you want to static link a 
    # particular library. It is also possible to omit both static_library and 
    # shared_library, creating a header only toolchain lib.
    # Use with statically linkage.
    static_library = "lib/libc++.a",
    # Use with shared linkage.
    shared_library = "lib/libc++.so",

    # This is a usefult sanity check to say that this library can only be 
    # targetted at Linux on an x86 machine.
    target_compatible_with = select({
        "@platforms//os:linux": ["@platforms//cpu:x86_64"],
        "//conditions:default": ["@platforms//:incompatible"],
    }),

    # Here we make sure that this target is visible from the configuration layer.
    visibility = ["@rules_cc_toolchain_config//:__pkg__"],

    # This version of libc++ depends on libc and libunwind, by specifying the
    # dependency on the configuration layer rather than directly on the imported
    # library itself we can ensure that we can swap out the version of libc with
    # little effort. 
    deps = [
        "@rules_cc_toolchain_config//:libc",
        "@rules_cc_toolchain_config//:libunwind",
    ],
)

Now we can test the new toolchain to ensure that it functions correctly.

bazel coverage @rules_cc_toolchain//tests/... \
 --@rules_cc_toolchain_config//:libc++=@clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04//:llvm_libcxx

NOTE: While the toolchain itself is hermetic the runtime linkage is not in this example you will need to make sure that you have a recent version of LLVMs libc++ installed on your system. If you would like to make sure that your runtime is hermetic use the static linking mode in Bazel, or simply omit the shared_library attribute to disable shared linkage for that specific library.

You can also opt to make these changes permanent by overriding the rules_cc_toolchain_config repository. e.g.

Copy this repositories config/rules_cc_toolchain_config.BUILD to your own repository. You can now update the build_setting_default for libc++ to point to your implementation. To make this change final you can make use of the

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

http_archive(
    name = "clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04",
    build_file = "//third_party:clang_llvm_12_00_x86_64_linux_gnu_ubuntu_16_04.BUILD",
    sha256 = "9694f4df031c614dbe59b8431f94c68631971ad44173eecc1ea1a9e8ee27b2a3",
    strip_prefix = "clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04",
    url = "https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz",
)

# Set up host hermetic host toolchain.
git_repository(
    name = "rules_cc_toolchain",
    commit = "dd9265e3ce0daa444911040430bd716076869b34",
    remote = "https://github.com/silvergasp/rules_cc_toolchain.git",
)

# (NEW)
load("@rules_cc_toolchain//config:rules_cc_toolchain_config_repository.bzl", 
    "rules_cc_toolchain_config")

# (NEW) Must be called before rules_cc_toolchain_deps.
rules_cc_toolchain_config(
    name = "rules_cc_toolchain_config",
    build_file = "//config:rules_cc_toolchain_config.BUILD",
)

load("@rules_cc_toolchain//:rules_cc_toolchain_deps.bzl", "rules_cc_toolchain_deps")

rules_cc_toolchain_deps()

load("@rules_cc_toolchain//cc_toolchain:cc_toolchain.bzl", "register_cc_toolchains")

register_cc_toolchains() 

bazel_rules_cc_toolchain's People

Contributors

dcnick3 avatar renovate-bot avatar silvergasp avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.