Published: 2023-03-01
In general, one should never check in binary artifacts into Git; it is better
to retrieve them from an artifact repository or a website using http_archive().
However, sometimes convenience is more important than ideological purity.
To handle these cases, I wrote a simple workspace rule named local_archive().
http_archive() is one of the most commonly used workspace rules. Besides
downloading archives from HTTP, it also supports a number of other useful
features such:
- SHA256 validation of the downloaded file to prevent injection attacks
- Automatic extraction of the contents of the archive
- A
build_fileattribute which can be used to provide post-download Bazel build instructions - A
strip_prefixattribute, to remove a common prefix from downloaded archives post-extraction
There is no equivalent to http_archive() for locally-stored archives, so
I wrote a simple one. It is included below:
# //:local_archive.bzl
#
# local_archive(): A Bazel workspace rule which acts like http_archive() but
# for locally-stored archive files.
#
# Note that some features of http_archive() are not implemented, such as
# sha256 validation.
def _impl(repository_ctx):
repository_ctx.extract(
archive = repository_ctx.attr.src,
stripPrefix = repository_ctx.attr.strip_prefix
)
repository_ctx.file(
"BUILD.bazel",
repository_ctx.read(repository_ctx.attr.build_file)
)
local_archive = repository_rule(
implementation = _impl,
attrs = {
"src": attr.label(mandatory = True, allow_single_file = True),
"build_file": attr.label(mandatory = True, allow_single_file = True),
"sha256": attr.string(),
"strip_prefix": attr.string(),
},
)
Use it as follows:
load("//:local_archive.bzl", "local_archive")
local_archive(
name = "org_lzma_lzma",
src = "//third_party/xz:xz-5.2.3.tar.gz",
build_file = "@com_github_nelhage_rules_boost//:BUILD.lzma",
sha256 = "71928b357d0a09a12a4b4c5fafca8c31c19b0e7d3b8ebb19622e96f26dbf28cb",
strip_prefix = "xz-5.2.3",
)