# 编译器Bazel 谷歌开源编译器Bazel,运作原理为:加载BUILD与目标相关的文件,编译器分析输入及其依赖关系,应用指定的构建规则,并生成action图。最后对输入执行构建操作,生成最终可执行文件。Bazel在GitHub上的开源地址:https://github.com/bazelbuild/bazel,竟然主要是Java开发的。 优点: - 构建快。支持增量编译, 对依赖关系进行了优化,从而支持并发执行。 - 可构建多种语言。bazel可用来构建Java、C++、Android、IOS等语言,支持Windows、Linux和macOS等不同的平台。 - 可伸缩。可处理任意大小的代码库,可处理多个库,也可以处理单个库。 - 可扩展。使用bazel扩展语言可支持新语言和新平台。 ## 安装 参考官方手册:https://docs.bazel.build/versions/5.1.0/install-ubuntu.html 一、使用apt源安装 这个可能源在国外,在添加apt源时会有问题,所以不如用编译好的安装包的形式进行安装,见方式二。 ```bash ###下面使用apt安装 #安装一些必要的工具 sudo apt install apt-transport-https curl gnupg #添加Bazel分发URI仓库源 curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg sudo mv bazel.gpg /etc/apt/trusted.gpg.d/ echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list #安装和更新Bazel sudo apt update && sudo apt install bazel ``` 二、使用编译好的二进制包方式安装 各种安装包可以在官方开源的GitHub仓库获取:https://github.com/bazelbuild/bazel/releases。尽量选择最新,所以我选择5.1.1版本下的installer安装包进行安装。 ```bash ##用二进制编译包安装需要一些依赖,下面先安装这些依赖,如果机器上已经安装过滤,就不用执行安装依赖的步骤 #bazel需要C++编译器,unzip和zip工具 sudo apt install g++ unzip zip #bazel需要jdk,因为它主要是java开发的 #如果是Ubuntu16.04的默认使用jdk8 sudo apt-get install openjdk-8-jdk #如果是Ubuntu18.04的默认使用jdk11 sudo apt-get install openjdk-11-jdk #下载二进制安装包 wget https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-installer-linux-x86_64.sh #添加执行权限 chmod +x bazel-5.1.1-installer-linux-x86_64.sh #执行安装 ./bazel-5.1.1-installer-linux-x86_64.sh --user #该--user标志将 Bazel 安装到$HOME/bin系统上的目录并将.bazelrc路径设置为$HOME/.bazelrc. 使用该--help命令查看其他安装选项。 #设置环境变量 #如果使用上述--user标志运行 Bazel 安装程序,则 Bazel 可执行文件将安装在您的$HOME/bin目录中。那么需要将这个目录添加到环境变量中 export PATH="$PATH:$HOME/bin" #添加到~/.bashrc中使其持久化 ##如果不想用user模式安装 ##先查看一下安装的选项 ./bazel-5.1.1-installer-linux-x86_64.sh --help #用管理员安装 sudo ./bazel-5.1.1-installer-linux-x86_64.sh #这样就安装好了bazel,现在查询一下版本 bazel --version #输出: bazel 5.1.1 ``` ## 使用 使用Bazel编译项目,这里有编译C++的三个例子,https://github.com/bazelbuild/examples/。 **WORKSPACE** - 存放名为 `WORKSPACE` 的文件的目录,是整个工程的根目录。换言之,整个工程的根目录由 `WORKSPACE` 来标识。整个工程的根目录也被叫做 workspace。 - 大部分情况下 `WORKSPACE` 文件为空。 **BUILD** 在 workspace下,考虑每一个子目录:如果存放了名为 BUILD 的文件,那么这个目录就是一个 package,意思是一个包。 BUILD 文件内容:它的内容包括设定的编译 target,比如 cc_binary 表示一个可执行文件,cc_library 表示一个库;每个 target 里又包括 name 等字段。 ``` 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默认编译生成文件会在工程目录下链接到用户的.cache目录下,所以不是太让人舒服。不如CMake等工具直接来的舒服点。