Bazel学习笔记(1)

本文主要过了一遍Bazel的基本概念,主要基于Bazel的官方文档


个人认为Platforms, constraints, toolchain和hermeticity对于上手Bazel不是特别重要,就不详细看了。

Workspace, packages & targets

https://bazel.build/concepts/build-ref

  • WORKSPACE
  • PACKAGES
  • BUILD
  • Targets

一个 WORKSPACE 可以有很多 PACKAGE, 每个 PACKAGE 对应一个 BUILD 文件。每个 BUILD 文件中,可定义很多 build targets 。

Target 分两类,file 和 rule。

file分为source file,就是平时写的code源代码;和生成的file,比如c++, .cc file编译后产生的binary二进制文件,或者是proto file codegen 以后生成的stub classes。

rule定义了怎么用input生成output。input可以是file,和其他rule。rule生成的artifact还是属于这个package。

Labels

https://bazel.build/concepts/labels

Label是一个target的ID。

@@myrepo//my/app/main:app_binary

@@canonical repo name vs @apparent repo name apprent repo name可以认为是在某个context (workspace/module) 中一个repo的昵称(alias)。

在当前workspace中,可以省略repo名。在相同package中,可以省略target之前的部分(workspace+package)。

BUILD文件中通过调用rule来定义一个target。每个rule都有name,和一系列的attributes。常见的attribute有integer,label,list of labels, string,list of string等等类型。

BUILD文件

可以通过load()引用extension .bzl文件中的function,rule或者常量。

load("//foo/bar:file.bzl", library_alias = "some_library")

runfiles文件夹: 有的target会把data,和其他transitive rule放在runfile文件夹里,方便部署。

Dependencies

https://bazel.build/concepts/dependencies

Declared dependency graph must be an overapproximation (superset) of actual dependency.

在当前project中,如果引用了transitive dependency中的library,必须在当前project中直接depend on,不然transitive dependency中有改动的时候,可能会break当前的project。

Type of dependencies

  • src
  • deps
  • data

filegroup, glob

filegroup(
        name = 'my_data',
        srcs = glob(['my_unittest_data/*'])
)

Visibility

Target visibility控制谁能depend当前的target。

  • //visibility:public
  • //visibility:private
  • //foo/bar:__pkg__
  • //foo/bar:__subpackages__
  • //some_pkg:my_package_group

load visibility 控制.bzl文件的vibility。

Hermeticity

类似idempotency的概念。不受host machine的影响。只要build tool,compiler,和dependencies不变,build的结果就不变。

Constraint, Platforms and Toolchain

Platform包含很多constraint。让Bazel可以支持不同的平台,(操作系统,处理器架构等等)。