Linux下Bazel的简单使用

Bazel是谷歌推出的一套编译系统,这是官网,Github地址https://github.com/bazelbuild/bazel。官方描述其优点如下,
在这里插入图片描述
我觉得最大优点是支持多语言吧,Java,C++,Go等等都是原生支持,一套系统可以编译多个语言。下面就看下如何简单使用,本文使用Debian10,Ubuntu也是一样。


一 安装

首先要在系统中添加Bazel的apt repository,

sudo apt install curl gnupg
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

然后更新一下,

sudo apt update

最后是安装,

sudo apt install bazel

也可以指定安装版本,本文写作时,其最新release版本是4.0.0,

sudo apt install bazel-4.0.0

如果安装时指定了版本,还需要创建一个软连接来连接一下,这样就可以在命令行使用bazel了

sudo ln -s /usr/bin/bazel-4.0.0 /usr/bin/bazel

最后看一下版本,以确认是否安装成功,

bazel --version  # 4.0.0

二 使用

1. 简单例子

先来一个helloworld的例子,执行下面命令去创建工程,

mkdir -p stage1/main
touch stage1/WORKSPACE
touch stage1/main/hello.cpp
touch stage1/main/BUILD

最后结构如下,
在这里插入图片描述

hello.cpp内容如下,

#include <iostream>

int main(void)
{
    std::cout << "hello world\n";
    return 0;
}

BUILD内容如下,

cc_binary(
    name = "hello_world",
    srcs = ["hello.cpp"],
)

PS:name表示生成的目标bin名称,srcs指示需要使用的源码文件

然后切到stage1目录下,执行以下命令,

bazel build //main:hello_world

PS:main就是main目录,后面冒号跟着目标bin名称

输出如下,
在这里插入图片描述
生成的bin在上图中红线表示的位置,可以运行一下,
在这里插入图片描述
bazel运行时会生成一些辅助文件,
在这里插入图片描述
如果想删掉它们,可以使用bazel的clean命令,

bazel clean
2. 生成库并链接

现在有个程序,编译时需要其它库文件,而这个库文件也是同时生成的。

先执行下面命令去创建工程,

mkdir -p stage2/main
touch stage2/WORKSPACE
touch stage2/main/BUILD
touch stage2/main/hello.cpp stage2/main/mylib.cpp stage2/main/mylib.h

最后结构如下,
在这里插入图片描述
mylib.h内容如下,

#ifndef _MY_LIB_H_
#define _MY_LIB_H_

int func(int data);

#endif

mylib.cpp内容如下,

#include "mylib.h"

int func(int data)
{
    return data*2;
}

hello.cpp内容如下,

#include <iostream>
#include "mylib.h"

int main(void)
{
    int ret = func(100);
    std::cout << "ret: " << ret << "\n";
    return 0;
}

BUILD内容如下,

cc_library(
    name = "mylib",
    srcs = ["mylib.cpp"],
    hdrs = ["mylib.h"],
)

cc_binary(
    name = "hello_world",
    srcs = ["hello.cpp"],
    deps = [
        ":mylib",
    ],
)

cd到stage2目录下,使用下面命令进行编译,

bazel build //main:hello_world

输出如下,
在这里插入图片描述
但是生成的库不知道在哪里…

3. 多个package

生成bin和生成库放在2个目录,然后每个都有对应的BUILD文件进行编译控制,bin依赖库。

首先执行下面命令去创建工程,

mkdir -p stage3/main
mkdir -p stage3/lib
touch stage3/WORKSPACE
touch stage3/main/BUILD
touch stage3/lib/BUILD

然后把上节的hello.cpp拷贝到stage3/main/下,mylib.h和mylib.cpp拷贝到stage3/lib/下,最后结构如下,
在这里插入图片描述
lib/BUILD内容如下,

cc_library(
    name = "mylib",
    srcs = ["mylib.cpp"],
    hdrs = ["mylib.h"],
    visibility = ["//main:__pkg__"],
)

PS:visibility的值表示这个库可以让main目录下的package使用

main/BUILD内容如下,

cc_binary(
    name = "hello_world",
    srcs = ["hello.cpp"],
    copts = ["-Ilib"],
    deps = [
        "//lib:mylib",
    ],
)

执行下面命令进行编译,

bazel build //main:hello_world

不需要生成lib也可以正常编译,如果想单独生成库,就执行,

bazel build //lib:mylib

三 小结

用起来还行,不过本人用惯了CMake,Bazel有点不适应,可能用多了就会习惯吧。