bazel教程_初学木工必备工具

bazel教程_初学木工必备工具bazel工具是Google内部构建工具Blaze的开源实现,属于编译打包工具,和maven、ant等类似

bazel教程_初学木工必备工具"

bazel工具是Google内部构建工具Blaze的开源实现,属于编译打包工具,和maven、ant等类似。
构建系统时,程序员一般写一个buildfile文件来描述系统,通常buildfile命名为BUILD。

cc_library(
    name = "hdmap_input",
    srcs = ["hdmap_input.cc"],
    hdrs = ["hdmap_input.h"],
    deps = [
        "//modules/common/math:geometry",
        "//modules/map/hdmap",
        # For personal convenience, some dependencies are omitted here.
        ......
        "//modules/perception/lib/config_manager",
    ],
)

cc_test(
    name = "hdmap_input_test",
    size = "small",
    srcs = ["hdmap_input_test.cc"],
    deps = [
        ":hdmap_input",
        "@com_google_googletest//:gtest_main",
        ......
        "//modules/perception/lib/config_manager",
    ],
)

在Bazel中,BUILD文件定义了targets。上面的两个targets分别是cc_library和cc_test。每个target对应着Bazel能够创建的一种制品(artifact)。
其中library能够生成被其他library或者others所使用的内容,test能够生产测试library或者其他的文件。
每个target都有一个name属性,方便它在命令行和其他target中被引用。src属性是必须被编译的相关源文件,用来生成对应的target artifact。deps属性是前置必须先构建或链接的依赖。【依赖关系可以限制在当前的packege以内(例如,hdmap_input_test依赖:hdmap_input),也可以是在同一个源代码层级中的不同package(例如,hdmap_input_test依赖于//modules/perception/lib/config_manager),或者源代码层级之外的第三方artifact(例如,hdmap_input_test依赖于@com_google_googletest//:gtest_main)。】

每个源代码层级(source hierarchy)都被称为一个workspace,并由根目录下的一个WORKSPACE文件来标示。

和Ant一样,用户也需要使用bazel的命令行工具来进行构建。例如,为了构建hdmap_input这个target,用户需要执行:

bazel build :hdmap_input

在首次运行上面的命令的时候,bazel工具会执行下面工作:
(1)解析当前workspace中的每一个BUILD文件,创建各个artifact之间的依赖关系图;
(2)用上面创建的图来决定hdmap_input的依赖转换关系,即hdmap_input所依赖的每个target,及每个target依赖的其他target,如此递归;
(3)根据具体的定义,按顺序构建或下载每一个依赖。bazel工具在这里首先会构建没有任何依赖的target,并保持跟踪对于每个target来说还有哪些依赖需要构建。一旦一个target的所有依赖都已经构建好了以后,bazel就开始构建该target。该过程持续到hdmap_input的每一个依赖都被构建完成。
(4)链接所有上一步中所生成的依赖,构建hdmap_input来生成最后的可执行二进制文件。

bazel的其他相关技巧
  • 对工具的依赖

很多构建都依赖于安装在自己机器上的各种工具,由于工具版本和安装环境等因素,实现跨机器的构建就会变得比较困难。如果项目还使用了不同的语言,并针对不同平台进行构建或编译,而每个平台要求略有差异的工具来完成相似工作,这个问题就更加明显。(这里涉及到两个问题:环境依赖平台针对性。)

bazel处理第一个问题的方式是把工具作为target所依赖的一部分。当前workspace中每个cc_library依赖于一个编译器,但也可以在workspace层面进行配置。每次当bazel构建一个library的时候,它首先检查特定的编译器是否在已知位置存在,如果没有的话首先下载。和其他依赖一样,如果编译器发生变化,所有依赖于它的artifact都需要重建。bazel中定义的每一类target都是用同样的策略来声明它需要运行的工具,确保无论什么样的环境下bazel都能够正确初始化。

bazel解决第二个平台独立性问题的方式是使用工具链。targets并不直接依赖于工具本身,而是依赖于工具链的类型。一个工具链包括一组工具和其他相关属性,用于定义某个类型的target如何在特定平台上构建。workspace可以根据主机和目标平台定义所使用的特定工具链。

  • 扩展构建系统

bazel允许通过自定义规则(custom rules)来扩展所支持的target类型。
要定义一个bazel的rule,首先要定义rule需要的input(以BUILD文件中传递的参数形式)和该rule所生成的output。并且还要定义该rule所要生成的actions。每个action同样也要声明input和output,运行一个特定可执行文件或在文件中写入特定字符串,并能够通过input/output连接到其他的action。这也意味着在bazel里面,action是最底层的可编辑单元(lowest-level composable unit)–只要一个action只使用它所声明的input/output,它就能做任何它想做的事情,而bazel则会负责对action进行规划安排并在合适的时候缓存其执行结果。

#########################################

bazel常用命令

#########################################
首先要有一个workspace,即WORKSPACE文件(每个bazel项目对应一个WORKSPACE文件。注意在bazel中,WORKSPACE指的是一个包括了单个或多个项目所有源文件的目录,然后在这个目录下要放一个WORKSPACE文件)。
其次要有一个BUILD文件,其描述了构建输出及依赖。

使用bazel构建程序
构建一个目标

输入bazel build,后跟要构建的目标。

$ bazel build //foo

发出构建 //foo 的命令后,会看到类似于以下内容的输出:

INFO: Analyzed target //foo:foo (14 packages loaded, 48 targets configured).
INFO: Found 1 target...
Target //foo:foo up-to-date:
  bazel-bin/foo/foo
INFO: Elapsed time: 9.905s, Critical Path: 3.25s
INFO: Build completed successfully, 6 total actions
构建多个目标

bazel允许通过多种方式指定要构建的目标,这些统称为“目标模式”。

// 开头的所有目标模式都将相对于当前工作区workspace进行解析。

//foo/bar:wiz 只有一个目标 //foo/bar:wiz
//foo/bar 等同于//foo/bar:bar
//foo/bar:all 软件包foo/bar中的所有规则目标
//foo/… foo目录下所有软件包中的所有规则目标
//foo/…:all foo目录下所有软件包中的所有规则目标
//foo/…: * foo目录下所有软件包中的所有目标(规则和文件)
//foo/…:all-targets foo目录下所有软件包中的所有目标(规则和文件)
//… 工作区中所有软件包的目标,这不包括外部代码库中的目标
//…:all 顶级软件包中的所有目标(如果workspace的根目录存在BUILD文件)

不以 // 开头的目标模式相对于当前工作目录进行解析。

:foo 等同于//foo:foo
bar:wiz 等同于//foo/bar:wiz
bar/wiz 等同于:### 如果foo/bar/wiz是软件包,则为//foo/bar/wiz:wiz ### 如果foo/bar是软件包,则为//foo/bar:wiz ### 否则为//foo:bar/wiz
bar:all 等同于//foo/bar:all
:all 等同于//foo:all
…:all 等同于//foo/…:all
等同于//foo/…:all
bar/…:all 等同于//foo/bar/…:all

foo/... 是package是上方的通配符,表示以递归方式在 foo 目录下(针对软件包路径的所有根目录)的所有软件包。
:all 是目标上方的通配符,用于匹配软件包中的所有规则。
这两种字符可以组合使用,如在 foo/...:all 中一样。当同时使用这两个通配符时,这可以简化为 foo/...

此外, :* (或 :all-targets)是与匹配的软件包中的每个目标(包括通常不由任何规则构建的文件)匹配的通配符。

这意味着 :* 表示 :all 的超集。:all 通配符用于典型构建。

bazel还支持使用斜杠代替标签语法所需的冒号;在使用Bash文件名扩展时,这通常很方便。例如,foo/bar/wiz 等同于 //foo/bar:wiz (如果有软件包 foo/bar)或 //foo:bar/wiz (如果存在软件包 foo)。

许多bazel命令都接受目标模式列表作为参数,并且它们都遵循前缀否定运算符 - 。这可用于从上述参数指定的集合中减去一组目标。(注意:这意味着顺序很重要。)例如,

$ bazel build foo/... bar/...

指“在 foo 下构建所有目标,在 bar 下构建所有目标”,而

$ bazel build -- foo/... -foo/bar/...

指“构建 foo 下的所有目标,但不知 foo/bar 下”。(其中 -- 参数是必需的,可以防止以 - 开头的后续参数被解释为其他选项。)
需要注意的是,以这种方式减去目标时,并不能保证它们不会被构建,因为它们可能是未减去的目标的依赖项。

参考:
https://zhuanlan.zhihu.com/p/262497747
https://bazel.google.cn/versions/6.1.0/run/build?hl=fr&authuser=19#getting-help

今天的文章bazel教程_初学木工必备工具分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83438.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注