Skylark remote repositories let you create custom external repositories using Skylark. This not only enables creating rules for custom package systems such as PyPi but also generating a repository to reflect the toolchain installed on the workstation Bazel is running on. We explain here how we implemented auto-configuration for the C++ toolchain.
Crosstool: a compiler capable of building for a certain architecture, which can be different from the host architecture (e.g., gcc running on Linux and building for Raspberry Pi).
C++ toolchains are configured in Bazel using a crosstool target and a CROSSTOOL file.
This crosstool target (:default_toolchain) is the first step in moving the contents of the CROSSTOOL file entirely into BUILD file rules. The CROSSTOOL file defines where to find the C++ compiler, its include directories and also the various flag to use at each compilation step.
When your C++ compiler is not in the standard location, then this static CROSSTOOL file cannot find it. To cope with the variety of installation out there, we created a cc_configure
Skylark repository rule that will generates a @local_config_cc//tools/cpp
package containing a generated CROSSTOOL file based on the information we gathered from the operating system.
The cc_configure
rule is actually a macro wrapping the cc_autoconf
enforcing the local_config_cc
name for the repository. The implementation of the cc_autoconf
rule does the following step:
cpu_value
using the repository_ctx.os.name
attribute.repository_ctx.which
and the CC
environment variable with repository_ctx.os.environ
.repository_ctx.which
.CROSSTOOL
file, testing flags against the detected compiler using repository_ctx.execute
. We also detect the include directories with repository_ctx.execute
.repository_ctx.template
.So using the function provided by repository_ctx
, we can discover the binaries on the system, what version they are, and which options they support, then generate a configuration to match the local C++ toolchain.
When creating a Skylark remote repository, a few things should be taken in considerations:
bazel clean --expunge
. We are thinking of further command to force re-run that loading phase for a specific remote repository (#974).sha256
argument of the repository_ctx.download
method.*_library
or *_binary
). If you create a package rule, a good name would probably be xxx_package
(e.g., pypi_package
). If you create an autoconfiguration rule, xxx_configure
is probably the best name (e.g. cc_configure
).