Bazel工具编译和构建C++项目学习笔记

MirrorYuChen
MirrorYuChen
发布于 2024-12-09 / 27 阅读
0
0

Bazel工具编译和构建C++项目学习笔记

1.Bazel安装

# 1.linux
>> sudo ./bazel-7.2.0-installer-linux-x86_64.sh
# 2.windows
# (1) 新建一个文件夹,下载exe文件bazel-7.2.0-windows-x86_64.exe
# (2) 将下载的exe文件拷贝到对应路径下,并将名字改为bazel.exe
# (3) 将该路径添加到系统环境变量中
# 3.查看版本
>> bazel --version
bazel 7.2.0

2.入门示例

  • (1) 新建工程,根目录创建空文件 MODULE.bazel,将当前目录标识为 Bazel工作区;
  • (2) 创建文件夹 main,并在文件夹下添加源码 hello-world.cc,及构建规则文件 BUILD,工程结构如下:
├── MODULE.bazel
└── main
    ├── BUILD
    └── hello-world.cc
  • (3) 给 hello-world.cc文件添加源码内容:
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 17:46:22
 * @Contact: 2458006466@qq.com
 * @Description: hello world
 */
#include <ctime>
#include <cstring>
#include <iostream>

std::string Hello(const std::string &who) {
  return "Hello, " + who;
}

void getTimestamp() {
  std::time_t result = std::time(nullptr);
  std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char *argv[]) {
  std::string who = "world";
  if (argc > 1) {
    who = argv[1];
  }
  std::cout << Hello(who) << std::endl;
  getTimestamp();

  return 0;
}
  • (4) 向 BUILD文件中添加编译规则:
cc_binary(
  name = "hello-world",
  srcs = ["hello-world.cc"],
)
  • (5) 编译运行:
# 1.编译
>> 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.126s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
# 2.运行
>> ./bazel-bin/main/hello-world
Hello, world
Mon Dec  9 18:02:06 2024

3.多目标构建

  • (1) 将 Hello函数的声明和实现分别放在 hello.hhello.cc中:
// hello.h
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 18:17:03
 * @Contact: 2458006466@qq.com
 * @Description: Hello
 */
#pragma once

#include <string>

std::string Hello(const std::string &who);
// hello.cc
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 18:17:08
 * @Contact: 2458006466@qq.com
 * @Description: Hello
 */
#include "hello.h"

std::string Hello(const std::string &who) {
  return "Hello, " + who;
}
  • (2) 修改 hello-world.cc文件内容:
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 17:46:22
 * @Contact: 2458006466@qq.com
 * @Description: hello world
 */
#include <ctime>
#include <cstring>
#include <iostream>

#include "hello.h"

void getTimestamp() {
  std::time_t result = std::time(nullptr);
  std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char *argv[]) {
  std::string who = "world";
  if (argc > 1) {
    who = argv[1];
  }
  std::cout << Hello(who) << std::endl;
  getTimestamp();

  return 0;
}
  • (3) 修改构建规则 BUILD文件:
cc_library(
  name = "Hello",
  srcs = ["hello.cc"],
  hdrs = ["hello.h"],
)

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

​ 这里Bazel首先会构建 Hello库(使用Bazel内置的 cc_library规则),然后再构建 hello-world二进制文件。hello-world目标中的 deps属性会告知Bazel构建过程中需要依赖 Hello库才能成功构建出 hello-world二进制文件。

  • (4) 编译运行:
# 1.编译
>> bazel build //main:hello-world
INFO: Analyzed target //main:hello-world (82 packages loaded, 389 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.293s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
# 2.运行
>> ./bazel-bin/main/hello-world
Hello, world
Mon Dec  9 18:23:31 2024

4.多软件包

  • (1) 在项目根目录创建一个目录 lib,并创建 timestamp.htimestamp.ccBUILD三个文件;
  • (2) 添加源文件及编译规则:

​ 这里主要不同之处在于 visibility = ["//main:__pkg__"],表示该包对于 main路径下的包可见,这样 main路径下包就可以链接到当前编译生成的 Timestamp包。

// timestamp.h
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 18:51:42
 * @Contact: 2458006466@qq.com
 * @Description: timestamp
 */
#pragma once

#include <ctime>
#include <cstring>

void getTimestamp();

// timestamp.cc
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 18:51:47
 * @Contact: 2458006466@qq.com
 * @Description: timestamp
 */
#include "timestamp.h"
#include <iostream>

void getTimestamp() {
  std::time_t result = std::time(nullptr);
  std::cout << std::asctime(std::localtime(&result));
}
// BUILD
cc_library(
  name = "Timestamp",
  srcs = ["timestamp.cc"],
  hdrs = ["timestamp.h"],
  visibility = ["//main:__pkg__"],
)
  • (3) 修改 main文件夹下编译规则及源码:

​ 编译规则主要修改点为:"//lib:Timestamp",这个表示二进制文件的编译过程依赖于 lib路径下 Timestamp

// BUILD
cc_library(
  name = "Hello",
  srcs = ["hello.cc"],
  hdrs = ["hello.h"],
)

cc_binary(
  name = "hello-world",
  srcs = ["hello-world.cc"],
  deps = [
    ":Hello",
    "//lib:Timestamp"
  ],
)
// hello-world.cc
/*
 * @Author: chenjingyu
 * @Date: 2024-12-09 17:46:22
 * @Contact: 2458006466@qq.com
 * @Description: hello world
 */
#include <iostream>

#include "main/hello.h"
#include "lib/timestamp.h"

int main(int argc, char *argv[]) {
  std::string who = "world";
  if (argc > 1) {
    who = argv[1];
  }
  std::cout << Hello(who) << std::endl;
  getTimestamp();

  return 0;
}
  • (4) 编译运行:
# 1.编译
bazel build //main:hello-world
INFO: Analyzed target //main:hello-world (0 packages loaded, 5 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.428s, Critical Path: 0.33s
INFO: 6 processes: 3 internal, 3 linux-sandbox.
INFO: Build completed successfully, 6 total actions
# 2.运行
>> ./bazel-bin/main/hello-world
Hello, world
Mon Dec  9 18:59:21 2024

5.参考资料


评论