必须掌握的Bazel基础和关键概念

Bazel用于构建大型的项目, 无论是本地运行,还是跑在CI上,对于编译效率的提升是巨大的。我们之前的项目是用CMake构建的,后面转用Bazel,编译和运行CI的效率会提升十倍。

Bazel 的核心知识点很多,但有一些是 必须掌握的基础和关键概念,包括 Bazel 构建阶段、依赖管理、构建规则、缓存机制等。以下是一个 系统化的基础知识清单,帮助你理解 Bazel 的核心原理。

1. Bazel 的三大构建阶段

Bazel 运行时分为 三个关键阶段

① 加载阶段(Loading Phase)

  • 解析 WORKSPACEBUILD 文件。
  • 解析 BUILD 文件中的 构建规则(cc_library、cc_binary、py_binary等)
  • 计算 目标依赖关系(Dependency Graph)。

② 分析阶段(Analysis Phase)

  • 解析 依赖关系,生成 构建执行计划(Action Graph)
  • 处理 规则扩展(如 select()config_settings())。

③ 执行阶段(Execution Phase)

  • 实际执行构建命令(编译、链接、生成二进制文件)。
  • 使用 缓存和并行执行 来加速构建。

2. Bazel 关键文件

WORKSPACE 文件

  • 定义 Bazel 项目的根目录
  • 导入外部依赖(如 http_archive()local_repository())。
  • 每个 Bazel 项目只能有一个 WORKSPACE 文件

BUILD 文件

  • 定义 构建目标(如 cc_binarypy_library)。
  • 类似 Makefile,但声明式(声明依赖关系,Bazel 处理构建逻辑)。
  • 关键构建规则:
    cc_library(
        name = "mylib",
        srcs = ["mylib.cc"],
        hdrs = ["mylib.h"],
        deps = ["//utils:helpers"],  # 依赖 utils 目录下的 helpers 库
    )
    
    cc_binary(
        name = "myapp",
        srcs = ["main.cc"],
        deps = [":mylib"],  # 依赖当前 BUILD 文件中的 mylib
    )
    

.bazelrc 配置文件

  • 定义 默认构建选项,如 --copt(编译优化)、--compilation_mode 等。
  • 示例:
    build --copt=-O2  # 默认使用 -O2 进行优化
    build --compilation_mode=opt  # 默认使用 opt 模式
    test --test_output=errors  # 仅在测试失败时显示日志
    

3. Bazel 重要概念

 3.1bazel中的  repository, workspace, package, target 的概念:

   1. Repository(代码仓库)
  • Bazel 中的 repository 指的是一个 独立的代码仓库,可以是本地目录,也可以是远程仓库。
  • 每个 Bazel 项目都会有一个主 repository(@ 代表当前 repo),可以通过 WORKSPACE 文件定义外部 repository。
  • 例如:
    http_archive(
        name = "rules_cc",
        urls = ["https://github.com/bazelbuild/rules_cc/archive/main.zip"],
        strip_prefix = "rules_cc-main",
    )
    这里 rules_cc 就是一个外部 repository。
   2. Workspace(工作空间)
  • Bazel 项目的根目录,包含 WORKSPACE 文件。
  • WORKSPACE 文件定义了 外部依赖,并告诉 Bazel 这是一个独立的 Bazel 项目。
  • 示例
    workspace(name = "my_project")
    
    http_archive(
        name = "googletest",
        urls = ["https://github.com/google/googletest/archive/release-1.11.0.zip"],
        strip_prefix = "googletest-release-1.11.0",
    )
  • 特点
    • 运行 bazel info workspace 可以查看当前 workspace 的路径。
    • 每个 Bazel 构建都会在 workspace 目录内进行。
   3. Package(包)
  • 每个包含 BUILD 文件的目录都是一个 package
  • package 名称WORKSPACE 目录的相对路径决定。
  • 示例
    my_project/      # WORKSPACE 根目录
    ├── WORKSPACE
    ├── src/
    │   ├── BUILD  # 这个目录是一个 package
    │   ├── main.cc
    │   ├── utils/
    │   │   ├── BUILD  # utils 也是一个 package
    │   │   ├── math.cc
    
    • src/ 是一个 package,因为它有 BUILD 文件。
    • src/utils/ 也是一个 package,因为它有自己的 BUILD 文件。
4. Target(构建目标)
  • BUILD 文件中的每个可构建单元 , 比如是自己定义的 rule 或者是 macro,如 cc_librarycc_binarypy_binary,都被称为一个 target
  • target 的唯一标识
    //package:target_name
    
    例如:
    cc_library(
        name = "math_lib",
        srcs = ["math.cc"],
    )
    
    • //src/utils:math_lib 就是 math_lib 这个 target 的完整路径。

3.2. Bazel 依赖管理

  • //package:target 语法
    • 例://src:my_lib 代表 src/BUILD 文件中的 my_lib 目标。
  • 外部依赖
    • 通过 WORKSPACE 文件定义,如:
      http_archive(
          name = "googletest",
          urls = ["https://github.com/google/googletest/archive/release-1.11.0.zip"],
          strip_prefix = "googletest-release-1.11.0",
      )
      

  • 跨目录依赖
    • 依赖 //utils:math_lib
      deps = ["//utils:math_lib"]
      

3.3. bazel 的主要构建规则

Bazel 提供了一系列内置规则来支持不同类型的构建目标,主要分为 C++、Python、Java、Shell、测试 等类别。以下是常见的规则:

  1. C++ 规则(C++ 编译 & 链接)
  • cc_library:定义一个 C++ 静态或共享库。
  • cc_binary:定义一个可执行的 C++ 二进制文件。
  • cc_test:定义一个 C++ 测试目标。

示例:

cc_library(
    name = "math_lib",
    srcs = ["math.cc"],
    hdrs = ["math.h"],
    deps = ["//utils:helpers"],
)

cc_binary(
    name = "main_app",
    srcs = ["main.cc"],
    deps = [":math_lib"],
)

cc_test(
    name = "math_test",
    srcs = ["math_test.cc"],
    deps = [":math_lib"],
)
  2. Python 规则(Python 脚本 & 库)
  • py_library:定义一个 Python 库。
  • py_binary:定义一个 Python 可执行文件。
  • py_test:定义一个 Python 测试。

示例:

py_library(
    name = "utils",
    srcs = ["utils.py"],
)

py_binary(
    name = "app",
    srcs = ["app.py"],
    deps = [":utils"],
)

py_test(
    name = "utils_test",
    srcs = ["test_utils.py"],
    deps = [":utils"],
)
  3. Java 规则(Java 构建 & 运行)
  • java_library:定义 Java 代码库。
  • java_binary:定义 Java 可执行文件(JAR)。
  • java_test:定义 Java 测试。

示例:

java_library(
    name = "utils",
    srcs = ["Utils.java"],
)

java_binary(
    name = "app",
    main_class = "com.example.Main",
    deps = [":utils"],
)

java_test(
    name = "utils_test",
    srcs = ["UtilsTest.java"],
    deps = [":utils"],
)
  4. Shell 脚本规则
  • sh_library:定义 Shell 脚本库。
  • sh_binary:定义 Shell 可执行脚本。
  • sh_test:定义 Shell 测试脚本。

示例:

sh_binary(
    name = "deploy_script",
    srcs = ["deploy.sh"],
)
  5. 测试规则

Bazel 内置 test 规则,支持 C++、Python、Java、Shell 等语言的测试目标。

  • cc_testpy_testjava_testsh_test
  • 运行测试:
    bazel test //src:math_test
    
  6. 通用规则
  • filegroup:定义一组文件,方便管理。
  • genrule:自定义 Shell 命令生成文件(适用于代码生成)。

示例:

genrule(
    name = "generate_version",
    outs = ["version.txt"],
    cmd = "echo '1.0.0' > $@",
)

3.4. 构建模式

  • fastbuild(默认):最快编译,不优化。
  • opt:用于 生产环境(相当于 -O2)。
  • dbg:用于 调试(带调试符号)。

切换编译模式:

bazel build --compilation_mode=dbg //src:app

3.5. Bazel 的缓存机制

  • Sandbox(沙盒隔离):每个构建任务在独立的环境中运行,避免污染。
  • Remote Cache(远程缓存):可以存储已构建的对象,加速 CI/CD 构建。
  • Incremental Build(增量构建):Bazel 只重新编译 变更部分,提高效率。

4. Bazel 关键命令

命令作用
bazel build //target构建目标
bazel run //target运行目标
bazel test //target运行测试
bazel clean清理构建缓存
bazel query查询依赖关系
bazel fetch //target预下载外部依赖
bazel shutdown停止 Bazel 服务器

5. 进阶知识

select() 实现条件依赖

  • select() 允许 基于不同条件选择依赖
    cc_library(
        name = "mylib",
        srcs = ["mylib.cc"],
        hdrs = ["mylib.h"],
        deps = select({
            "//conditions:default": [],
            "//config:use_advanced": ["//advanced:lib"],
        }),
    )
    

    • bazel build --define use_advanced=1 时使用 advanced:lib,否则为空。

config_setting() 结合 select()

  • config_setting() 用于定义条件
    config_setting(
        name = "enable_advanced",
        values = {"define": "use_advanced=1"},
    )
    

bazel query 分析依赖

  • 查询某个 target 的所有依赖:
    bazel query "deps(//src:app)"
    
  • 仅查询直接依赖:
    bazel query "kind(cc_library, deps(//src:app))"
    


6. 重点总结

关键知识

说明
Bazel 三阶段加载(解析 BUILD)、分析(生成 DAG)、执行(编译 & 运行)
BUILD 文件声明目标、依赖
WORKSPACE 文件定义 Bazel 项目,导入外部依赖
编译模式fastbuild(默认)、opt(优化)、dbg(调试)
缓存机制沙盒、远程缓存、增量构建
关键命令

buildruntestquery

Bazel 官方文档: https://bazel.build/extending

--------------------------------------------------------------------------------------------------------------------------------

若有新的知识, 会逐渐添加...........

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值