我的编程空间,编程开发者的网络收藏夹
学习永远不晚

从零学习构造系统之bazel示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

从零学习构造系统之bazel示例详解

什么是bazel

Bazel 是一款与 Make、Maven 和 Gradle 类似的开源构建和测试工具。 它使用人类可读懂的高级 build 语言。Bazel 支持使用多种语言的项目,并针对多个平台构建输出。Bazel 支持跨多个代码库和大量用户的大量代码库。

Bazel的基本概念

WORKSPACE file

在构建项目之前,我们需要先设置工作区,工作区的作用是存储项目的源文件和Bazel的构建输出的目录,其中WORKSPACE file就是将目录及其内容标识为Bazel工作区的文件,需要位于项目目录结构的根目录下,该文件可以为空,但是通常包含从网络或者本地文件系统中提取其他依赖项的外部代码库声明。

BUILD file

一个项目中包含一个或多个BUILD file,BUILD主要用于告知Bazel如何构建项目,工作区包含一个BUILD文件的目录就是一个软件包。在之前的文章提到过,Bazel是基于工件的构建系统,而工件就可以理解为Bazel根据Build文件中的编译规则编译该目录下的文件形成的,软件包可以包含子软件包或包含BUILD文件的子目录,从而形成软件包的层次。

BUILD文件中包含了一些适用于Bazel的不同类型的指令,每个BUILD文件都需要包含至少一条规则(如cc_library)作为一组指令,以指示Bazel如何构建所需要的输出,例如可执行文件或库。BUILD文件中的每一个build规则实例都称为目标,并指向一组特定的源文件和依赖项,一个目标也可以指向其他目标。以下就是一个简单的BUILD文件的例子。

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

在本示例中,hello-world 目标会实例化 Bazel 的内置 cc_binary rule。该规则会告知 Bazel 从 hello-world.cc 源文件构建不含依赖项的独立可执行文件。

Bazel的C++事例

该例子是Bazel官方提供的,github地址为git clone github.com/bazelbuild/…

单个目标,单个软件包

我们从最简单的例子开始,例子只包含一个源文件,需要将改源文件构建成一个可执行文件,其文件目录如下。

examples
└── cpp-tutorial
    └──stage1
       ├── main
       │   ├── BUILD
       │   └── hello-world.cc
       └── WORKSPACE

BUILD文件内容如下

load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
    name = "hello-world",
    class="lazy" data-srcs = ["hello-world.cc"],
)

然后进入该目录cpp-tutorial/stage1,运行以下命令构建

bazel build //main:hello-world

会打印以下信息表示编译成功

Starting local Bazel server and connecting to it...
INFO: Analyzed target //main:hello-world (37 packages loaded, 255 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 28.089s, Critical Path: 2.78s
INFO: 6 processes: 4 internal, 2 darwin-sandbox.
INFO: Build completed successfully, 6 total actions

然后可以使用以下命令测试,会打印Hello world

bazel-bin/main/hello-world

其依赖关系如下

单个软件包,多个目标

虽然单个目标足以满足小型项目的需求,在实际的开发过程中可能需要将较大的项目拆分为多个目标和软件包。这样可以实现快速增量构建(即 Bazel 仅重建更改的内容,并通过一次性构建项目的多个部分来加快构建速度。在教程的这一阶段,您将添加目标,然后添加软件包。

下面的BUILD文件会告诉Bazel先构建hello-greet库(使用Bazel内置的cc_library)然后构建hello-world二进制文件,其中的deps属性告诉Bazel构建hello-world需要hello-greet库。

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_library(
    name = "hello-greet",
    class="lazy" data-srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)
cc_binary(
    name = "hello-world",
    class="lazy" data-srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
    ],
)

编译情况如下

INFO: Analyzed target //main:hello-world (36 packages loaded, 258 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 15.548s, Critical Path: 2.39s
INFO: 8 processes: 4 internal, 4 darwin-sandbox.
INFO: Build completed successfully, 8 total actions

如果现在修改 hello-greet.cc 并重新构建项目,Bazel 只会重新编译该文件,编译结果如下(通过-s选项可以打印具体编译过程)

INFO: Analyzed target //main:hello-world (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
SUBCOMMAND: # //main:hello-greet [action 'Compiling main/hello-greet.cc', configuration: a42135a42aad3da7e3af209ce54745fb0d0306dc29e1f3dc84d7d58372421fc9, execution platform: @local_config_platform//:host]
(cd /private/var/tmp/_bazel_qiming/e4d33fbb5ee1f924b3cb079f19abf4eb/execroot/__main__ && \
  exec env - \
    APPLE_SDK_PLATFORM=MacOSX \
    APPLE_SDK_VERSION_OVERRIDE=13.1 \
    PATH=/Users/qiming/Library/Caches/bazelisk/downloads/bazelbuild/bazel-6.0.0-darwin-x86_64/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin \
    XCODE_VERSION_OVERRIDE=14.2.0.14C18 \
    ZERO_AR_DATE=1 \
  external/local_config_cc/wrapped_clang_pp '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -O0 -DDEBUG '-std=c++11' 'DEBUG_PREFIX_MAP_PWD=.' -iquote . -iquote bazel-out/darwin-fastbuild/bin -MD -MF bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.d '-DBAZEL_CURRENT_REPOSITORY=""' '-frandom-seed=bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.o' -isysroot __BAZEL_XCODE_SDKROOT__ -F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks -F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks -no-canonical-prefixes -pthread -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -target x86_64-apple-macosx13.1 -c main/hello-greet.cc -o bazel-out/darwin-fastbuild/bin/main/_objs/hello-greet/hello-greet.o)
# Configuration: a42135a42aad3da7e3af209ce54745fb0d0306dc29e1f3dc84d7d58372421fc9
# Execution platform: @local_config_platform//:host
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.750s, Critical Path: 0.58s
INFO: 2 processes: 1 internal, 1 darwin-sandbox.
INFO: Build completed successfully, 2 total actions

其中依赖如下图

多个软件包,多个目标

在包含多个软件包的情况下又该如何编译呢?其结构如下:

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

lib目录下的BUILD文件如下

load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
    name = "hello-time",
    class="lazy" data-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",
    class="lazy" data-srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)
cc_binary(
    name = "hello-world",
    class="lazy" data-srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time",
    ],
)

主软件包中的 hello-world 目标依赖于 lib 软件包中的 hello-time 目标(因此是目标标签 //lib:hello-time)- Bazel 通过 deps 属性知道这一点。依赖项图中反映了这一点:

为了顺利构建,请使用可见性属性使 lib/BUILD 中的 //lib:hello-time 目标明确对 main/BUILD 中的目标可见。这是因为默认情况下,目标仅对同一 BUILD 文件中的其他目标可见。Bazel 使用目标可见性来防止出现包含实现细节的库泄露到公共 API 等问题。

最后

这篇文章主要介绍了构造系统bazel的简单使用,更多关于bazel构造系统的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

从零学习构造系统之bazel示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

从零学习构造系统之bazel示例详解

这篇文章主要为大家介绍了从零学习构造系统之bazel示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-07

从零开始学习Node.js系列教程之设置HTTP头的方法示例

本文实例讲述了Node.js设置HTTP头的方法。分享给大家供大家参考,具体如下: server.js//basic server的配置文件 var port = 3000; var server = require('./basicser
2022-06-04

从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例

本文实例讲述了Node.js基于connect和express框架的多页面实现数学运算。分享给大家供大家参考,具体如下: 1、使用connect框架 .use方法用于绑定中间件到connect服务器,它会配置一系列在接到请求时调用的中间件模
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录