bazel 安装和使用

1. 安装

seivl@seivl-Default-string:~$ bazel --version
bazel 4.0.0

2. 使用

使用Bazel编译项目

其中 examples/cpp-tutorial 目录下包含了这么些文件:

seivl@seivl-Default-string:~/examples/cpp-tutorial$ tree -L 3
.
├── README.md
├── stage1
│   ├── main
│   │   ├── BUILD
│   │   └── hello-world.cc
│   ├── README.md
│   └── WORKSPACE
├── stage2
│   ├── main
│   │   ├── BUILD
│   │   ├── hello-greet.cc
│   │   ├── hello-greet.h
│   │   └── hello-world.cc
│   ├── README.md
│   └── WORKSPACE
└── stage3
    ├── lib
    │   ├── BUILD
    │   ├── hello-time.cc
    │   └── hello-time.h
    ├── main
    │   ├── BUILD
    │   ├── hello-greet.cc
    │   ├── hello-greet.h
    │   └── hello-world.cc
    ├── README.md
    └── WORKSPACE

stage1 来举例:

seivl@seivl-Default-string:~/examples/cpp-tutorial/stage1$ tree -L 2
.
├── main
│   ├── BUILD
│   └── hello-world.cc
├── README.md
└── WORKSPACE

WORKSPACE

  • 存放名为 WORKSPACE 的文件的目录,是整个工程的根目录。换言之,整个工程的根目录由 WORKSPACE 来标识。整个工程的根目录也被叫做 workspace

  • WORKSPACE 文件为空即可

BUILD

在 workspace下,考虑每一个子目录:如果存放了名为 BUILD 的文件,那么这个目录就是一个 package,意思是一个包。

BUILD 文件内容:它的内容包括设定的编译 target,比如 cc_binary 表示一个可执行文件,cc_library 表示一个库;每个 target 里又包括 name 等字段:

扫描二维码关注公众号,回复: 13386270 查看本文章
  • name 自己定义就好
cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)
 
cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)

1. 例子a:单个target 编译

先看一下 cpp-tutorial/stage1/main/BUILD 文件:

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

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)

进入到 cpp-tutorial/stage1目录下

在工程根目录,也就是包含 WORKSPACE 文件的那个目录,执行然后运行以下指令

执行 bazel 构建

sudo bazel build //main:hello-world

结果:

seivl@seivl-Default-string:~/examples/cpp-tutorial/stage1$ sudo bazel build //main:hello-world
INFO: Analyzed target //main:hello-world (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.150s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action

看一下此时的目录,生成了一些文件:

seivl@seivl-Default-string:~/examples/cpp-tutorial/stage1$ tree -L 1
.
├── bazel-bin
├── bazel-out
├── bazel-stage1
├── bazel-testlogs 
├── main
├── README.md
└── WORKSPACE

表示让 bazel 去构建 main 这个 package 下的 hello-world 这一 target

随后,会在当前 workspace_下,生成 bazel-bin bazel-out bazel-stage1 bazel-testlogs 这几个文件

然后运行:

bazel-bin/main/hello-world

结果

world
Hello world
Mon May 10 21:46:23 2021
  • 关系
    在这里插入图片描述

2. 例子b: 多个 target 的编译

├── stage2
 ├── main
 │   ├── BUILD
 │   ├── hello-greet.cc
 │   ├── hello-greet.h
 │   └── hello-world.cc
 ├── README.md
 └── WORKSPACE

进入 stage2 看一下 BUILD 文件

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

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)

bazel 首先编译了 hello-greet 这个库(利用Bazel内置的cc_library编译指令),然后编译 hello-world 这个二进制文件。hello-world 这个 targetdeps 属性告诉 bazel,要构建 hello-world 这个二进制文件需要 hello-greet 这个库。

编译一下

sudo bazel build //main:hello-world
seivl@seivl-Default-string:~/examples/cpp-tutorial/stage2$ sudo bazel build //main:hello-world
[sudo] seivl 的密码: 
Starting local Bazel server and connecting to it...
INFO: Analyzed target //main:hello-world (15 packages loaded, 55 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 5.027s, Critical Path: 0.64s
INFO: 7 processes: 4 internal, 3 processwrapper-sandbox.
INFO: Build completed successfully, 7 total actions
seivl@seivl-Default-string:~/examples/cpp-tutorial/stage2$ tree -L 2.
├── bazel-bin 
├── bazel-out 
├── bazel-stage2 
├── bazel-testlogs
├── main
│   ├── BUILD
│   ├── hello-greet.cc
│   ├── hello-greet.h
│   └── hello-world.cc
├── README.md
└── WORKSPACE

运行:

bazel-bin/main/hello-world

结果:

world
Hello world
Mon May 10 22:23:47 2021
  • 关系
    在这里插入图片描述

3. 例子c: 多个 package 的编译

└── stage3
 ├── lib
 │   ├── BUILD
 │   ├── hello-time.cc
 │   └── hello-time.h
 ├── main
 │   ├── BUILD
 │   ├── hello-greet.cc
 │   ├── hello-greet.h
 │   └── hello-world.cc
 ├── README.md
 └── WORKSPACE

现在有两个子目录了,每个子目录中都包含了 BUILD 文件

因此,对于 bazel 来说,整个工作区现在就包含了两个 package:lib 和 main

  • lib 的 BUILD
load("@rules_cc//cc:defs.bzl", "cc_library")

cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)
  • main 的 BUILD
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time",
    ],
)

可以看出 hello-world 这个 main package 中的 target 依赖于 lib package 中的 hello-time target即target label为://lib:hello-time

bazel 是通过 deps 这个属性知道自己的依赖项的。那么现在依赖图就变成了下图的样子:
在这里插入图片描述

  • ps:注意到 lib/BUILD 文件中 将 hello-time 这个 target 显式可见了(通过visibility属性)。

  • 这是因为默认情况下,targets 只对同一个 BUILD文件里的其他 targets 可见

编译一下:

sudo bazel build //main:hello-world
seivl@seivl-Default-string:~/examples/cpp-tutorial/stage3$ sudo bazel build //main:hello-world
Starting local Bazel server and connecting to it...
INFO: Analyzed target //main:hello-world (16 packages loaded, 58 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 5.268s, Critical Path: 0.63s
INFO: 8 processes: 4 internal, 4 processwrapper-sandbox.
INFO: Build completed successfully, 8 total actions

运行结果:

seivl@seivl-Default-string:~/examples/cpp-tutorial/stage3$ bazel-bin/main/hello-world
Hello world
Mon May 10 22:33:54 2021

三. 参考

猜你喜欢

转载自blog.csdn.net/qq_35632833/article/details/116600640