• 正文
  • 相关推荐
申请入驻 产业图谱

Bazel Bzlmod本地BCR镜像搭建教程:配置本地仓库解决编译外网依赖超时

5小时前
130
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

上篇文章,介绍了Bazel的安装以及hello world程序的测试,在初次测试时遇到网络问题,上篇文章采取的是临时规避措施,本篇继续来探究,如何通过本地仓库配置,解决编译时的网络访问问题。

上次遇到的网络问题,涉及到了Bazel的Bzlmod和BCR概念。

1 Bzlmod与BCR

Bzlmod 是 Bazel 5.0 中引入的新外部依赖项系统 的代号。

Bazel Central Registry(BCR),是Bzlmod 用来查找模块元信息的注册表,在项目的 MODULE.bazel 写模块名 + 版本,Bazel 自动去 BCR 查询元信息,再下载源码包。

BCR底层是一个 Git 仓库,其目录结构:

modules/
  rules_cc/
    0.0.1/
      MODULE.bazel      # 模块本身的依赖声明
      source.json       # 源码下载地址 + sha256哈希
      metadata.json
      presubmit.yml     # BCR CI校验脚本

核心两类信息:

模块元数据:这个模块叫什么、版本列表、它又依赖哪些其他模块

源码地址 + 校验哈希:告诉 Bazel 去哪里下载这个库的 tar 包,以及文件 sha256,防止被篡改

注意使用BCR获取外部依赖,涉及两层下载:

① 查询注册表元信息:访问 registry(bcr.bazel.build)拿 metadata /source.json

② 下载第三方源码压缩包:source.json 里写的 github tar 地址

2 还原上次测试的一些操作

最外层重新加上MODEL.bazel

bazel_dep(name = "rules_cc", version = "0.0.17")

然后在main/BUILD中增加load这句

load("@rules_cc//cc:cc_binary.bzl", "cc_binary")

cc_binary(
    name = "hello",
    srcs = ["hello.cpp"],
)

3 创建本地BCR

由于官网的BCR地址在国内不方便访问,那就将其下载到本地进行访问,并且我们可以下载其国内镜像。

3.1 下载BCR仓库源码

官方BCR地址的https://bcr.bazel.build,这里使用一个国内镜像,避免下载时的网络问题

git clone https://gitcode.com/GitHub_Trending/ba/bazel-central-registry

3.2 配置源码镜像

xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ cat bazel_registry.json 
{
    "mirrors": []
}
xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ vi bazel_registry.json 
xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ cat bazel_registry.json 
{
    "mirrors": [
      "https://mirror.ghproxy.com/"
    ]
}
xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ 

原理:BCR 里面每个模块的 source.json 里写的原始地址是https://github.com/xxx/xxx.tar.gz,Bazel 会自动替换成https://mirror.ghproxy.com/github.com/xxx/xxx.tar.gz,走国内 ghproxy 代理下载源码包。

ghproxy 是一个在线反向代理服务,专门中转 github 文件下载请求。 它不是固定镜像仓库,是一个中转代理:请求过来,ghproxy 去 github 拉文件,然后转发给你。

ghproxy 是公共在线代理,也有缺点:

固定域名 mirror.ghproxy.com,但是公共服务,有限流、不稳定每次下载,本质还是 ghproxy 去 github 拿,不是预先全量缓存好的静态镜像

3.3 测试

项目中创建.bazelrc,之前去我们刚才创建的本地BCR中去查询依赖包的信息

# 优先使用本地克隆的 BCR,后面可以加官方作为兜底
common --registry=file:///home/xxpcb/myTest/Bazel/local_repo/bazel-central-registry/
# common --registry=https://bcr.bazel.build

注意:file:// 后面是绝对路径,Ubuntu 下格式 file:///home/xxx/xxx(三个斜杠)

然后进行编译测试,可以看到会通过ghproxy 去 github 拉rules_cc、platforms这些文件,因为本地BCR只是在第一步避免了访问官网BCR,然下载具体的依赖包,还是访问github,所以还会超时

最终也是报错。

4 创建本地依赖包

下面就进行第二部,把需要的依赖包也先手动下载下来,然后作为本地仓库,让本地BCR给出的依赖包的地址指向本地仓库,这样就不需要访问外网了。

4.1 下载所需的依赖

进入本地BCR仓库,查看对应的版本,先来项目中需要用到的rules_cc

cat modules/rules_cc/0.0.17/source.json 

如下

xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ cat modules/rules_cc/0.0.17/source.json 
{
    "integrity": "sha256-q8YF3YUPgTuzcAS3fbIBBqGTEalrLaHJK3idpSnSj+E=",
    "strip_prefix": "rules_cc-0.0.17",
    "url": "https://github.com/bazelbuild/rules_cc/releases/download/0.0.17/rules_cc-0.0.17.tar.gz",
    "patches": {
        "module_dot_bazel_version.patch": "sha256-sfVrLZhaiHSPIY77QupwdEJksH2dHNAaq9lFTB60OYI="
    },
    "patch_strip": 1
}
xxpcb@xxpcb-ubuntu20:~/myTest/Bazel/local_repo/bazel-central-registry$ 

下载:https://github.com/bazelbuild/rules_cc/releases/download/0.0.17/rules_cc-0.0.17.tar.gz,试了在Windows浏览器可以直接下载

4.2 创建本地依赖仓库镜像

注意到,刚才的本地BCR,是一个本地目录(bazel-central-registry),接下来的外部依赖,是另一个本地目录(bcr_archive)。

为了简短路径的长度,我把两个本地仓库的目录都移动到了用户目录,也就是~,我的是/home/xxpcb/

Bazel 镜像替换规则:

    • 原始 url:

https://github.com/bazelbuild/rules_cc/archive/refs/tags/0.0.17.tar.gz

    • mirror 前缀:

file:///home/xxpcb/local_repo/bcr_archive/

    • 拼接后路径:

file:///home/xxpcb/local_repo/bcr_archive/https://github.com/bazelbuild/rules_cc/archive/refs/tags/0.0.17.tar.gz

创建目录

cd /home/xxpcb/local_repo/bcr_archive
mkdir -p https://github.com/bazelbuild/rules_cc/archive/refs/tags/

4.3 测试

修改.bazelrc为对应的BCR地址

# 优先使用本地克隆的 BCR,后面可以加官方作为兜底
common --registry=file:///home/xxpcb/local_repo/bazel-central-registry/
# common --registry=https://bcr.bazel.build

# Bzlmod lock文件策略,全局生效
common --lockfile_mode=refresh

修改bazel-central-registry/bazel_registry.json

{
  "mirrors": [
    "file:///home/xxpcb/local_repo/bcr_archive/"
  ]
}

可以看到除了rules_cc本身,还有其它依赖也需要下载,那就继续配置本地仓库。

4.4 其它依赖

xxpcb@xxpcb-ubuntu20:~/local_repo/bazel-central-registry$ cat modules/protobuf/27.0/source.json 
{
    "integrity": "sha256-PhFI2wkP8hImwYiO85+nvHeQBCviH/Qon9Ic4XNfNFU=",
    "strip_prefix": "protobuf-27.0",
    "url": "https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.zip"
}
xxpcb@xxpcb-ubuntu20:~/local_repo/bazel-central-registry$ 

也可以在编译的时候带上 --nobiuld参数,不编译出可执行程序,只观察打印需要哪些依赖:

把剩余的依赖也查询下具体的压缩包,然后手动下载

xxpcb@xxpcb-ubuntu20:~/local_repo/bazel-central-registry$ cat modules/rules_license/0.0.7/source.json 
{
    "url": "https://github.com/bazelbuild/rules_license/releases/download/0.0.7/rules_license-0.0.7.tar.gz",
    "integrity": "sha256-RTHezLkTY5ww5cdRKgVNXYdWmNrrddjPkPKEN1/nw2A="
}
xxpcb@xxpcb-ubuntu20:~/local_repo/bazel-central-registry$ cat modules/rules_python/0.22.1/source.json 
{
    "integrity": "sha256-pWQP3dS+sD6MH95e1xYMC6a9R359BIZhwwwGk2om/WM=",
    "strip_prefix": "rules_python-0.22.1",
    "url": "https://github.com/bazelbuild/rules_python/releases/download/0.22.1/rules_python-0.22.1.tar.gz",
    "patches": {
        "module_dot_bazel_version.patch": "sha256-3+VLDH9gYDzNI4eOW7mABC/LKxh1xqF6NhacLbNTucs="
    },
    "patch_strip": 1
}
xxpcb@xxpcb-ubuntu20:~/local_repo/bazel-central-registry$ 

需要的外部依赖,都配置到本地仓库中后,是这样:

4.5 最终测试

最后可以正常编译通过了,编译时用到的依赖都从本地仓库下载。

5 总结

本篇介绍了Bazel中Bzlmod与BCR的概念,通过部署本地仓库,来避免编译时网络访问不畅的问题。

相关推荐

控制科学与工程硕士,日常分享单片机、嵌入式、C/C++、Linux等学习经验干货~