UBUNTU bazel编译C++文件

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

【UBUNTU】bazel编译C++文件bazel的写法_剑客无名的博客-CSDN博客

  bazel:为非bazel项目指定本地BUILD文件 - 知乎

  bazel c++ 编译入门 - 简书

一. bazel工作目录

项目
├── main(源代码所在文件夹)
│   ├── BUILD
│   └── print.cpp
└── WORKSPACE

WORKSPACE用不上的话内容可以为空只象征着工作空间的主目录所在。 

二. BUILD文件的编写

一本地单bazel工程

1. 单目录

① 单源文件

例如只有一个print.cpp文件正常情况下我们使用g++ print.cpp -o print.o来编译代码。当使用bazel编译BUILD文件

load("@rules_cc//cc:defs.bzl", "cc_binary")
cc_binary(
    name = "print",
    srcs = ["print.cpp"],
)

1load语句指加载bazel的相关扩展包 第一个参数代表扩展包的位置第二个参数表示扩展包中的规则、函数、常量字符串、列表等。

上面的语句作用为加载@rules_cc//cc:defs.bzl并添加其中定义的符号cc_binary到当前环境。

规则的类型比如此例的cc_binary一般以编程语言为前缀例如ccjava。后缀通常有 *_binary 用于构建目标语言的可执行文件

*_test 用于自动化测试其目标是可执行文件如果测试通过应该退出0

*_library 用于构建目标语言的库

WORKSPACE加载扩展.bzl规则

  • local_repository
  • new_local_repository
  • git_repository
  • new_git_repository
  • http_archive
  • http_file

其中local_repository与new_local_repository可以不执行load其余的必须执行load

  • git_repositoryload("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
  • new_git_repositoryload("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
  • http_archiveload("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  • http_fileload("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")

2编译命令  bazel build //main:print
其中//表示WORKSPACE所在的工作目录main为工作目录下的main文件夹print为main文件夹中被编译的对象文件即cc_binary下面的name。

注bazel run //main:print 指定编译并执行packagemain下的targetprint。

② 多源文件

// 文件夹的结构如下
├── main
│   ├── BUILD
│   ├── main.cpp
│   ├── print.cpp
│   └── print.h
└── WORKSPACE

 BUILD文件

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_library(
    name = "print",
    srcs = ["print.cpp"],
    hdrs = ["print.h"],
)
cc_binary(
    name = "main",
    srcs = ["main.cpp"],
    deps = [
        "//main:print",
    ],
)

load中加入的规则有cc_binary和cc_library其中cc_library用来编译头文件。

在cc_binary中加入了deps构建的可执行文件依赖于main文件夹下的print即cc_library中的name。

2. 多目录

├── libmain源文件依赖于此文件夹下的count.h
│   ├── BUILD
│   ├── count.cpp
│   └── count.h
├── main
│   ├── BUILD
│   └── main.cpp
└── WORKSPACE

lib文件夹下的BUILD文件

load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library(
    name = "count",
    srcs = ["count.cpp"],
    hdrs = ["count.h"],
    visibility = ["//main:__pkg__"],
)

要使count对main文件夹下的文件可见需要在./lib/BUILD文件中添加属性visibility值为//main:__pkg__

main文件夹下的BUILD文件

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_binary(
    name = "main",
    srcs = ["main.cc"],
    deps = [
        "//lib:count",
    ],
)

因为要依赖于lib文件夹中的count所以要加入deps来表示可执行文件需要依赖于lib文件夹中的count。lib与main在同个WORKSPACE下所以是deps = ["//lib:count", ]

而非deps = ["@lib:count", ]

注:

1当需要加入编译选项如-std=c++11等的时候

.
├── main
│   ├── BUILD
│   ├── main.cpp
│   ├── ThreadPool.cpp
│   └── ThreadPool.h
└── WORKSPACE

BUILD文件 

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_library(
    name = "ThreadPool",
    srcs = ["TC_ThreadPool.cpp"],
    hdrs = ["TC_ThreadPool.h"],
)
cc_binary(
    name = "main",
    srcs = ["main.cpp"],
    deps = [
        ":ThreadPool",
    ],
    linkopts = ["-lpthread", "-std=c++11"],
)

因为编译时需要多线程以及C++11的支持所以在编译target对应的cc_binary中加入了linkopts只需要在其中放置编译选项即可。

二本地多bazel工程

本地不同bazel工程之间的依赖

.
├── sub1
│   ├── src
│   │   ├── BUILD
│   │   └── main.cc
│   └── WORKSPACE
└── sub2
    ├── lib
    │   ├── BUILD
    │   └── print.h
    └── WORKSPACE

sub1/WORKSPACE

local_repository(
  name = "sub2",
  path = "../sub2",
)

sub1/src/BUILD

cc_binary(
  name = "hello-bazel",
  srcs = ["main.cc"],
  deps = [
    "@sub2//lib:print",
  ],
)

sub2与sub1不在同个WORKSPACE下所以是deps = ["@sub2//lib:print", ]

而非deps = ["//sub2:",]

sub2/lib/BUILD

cc_library(
  name = "print",
  hdrs = ["print.h"],
  visibility = ["//visibility:public"],
)

本地含非bazel工程

.
├── sub1
│   ├── src
│   │   ├── BUILD
│   │   └── main.cc
│   ├── sub2.BUILD
│   └── WORKSPACE
└── sub2
    └── lib
        └── print.h

sub1/WORKSPACE指向非bazel工程

new_local_repository(
  name = "sub2",
  path = "../sub2",
  build_file = "sub2.BUILD",
)

sub1/src/BUILD执行函数

cc_binary(
  name = "hello-bazel",
  srcs = ["main.cc"],
  deps = [
    "@sub2//:print",
  ],
)

sub1/sub2.BUILD指向非bazel工程库函数

cc_library(
  name = "print",
  hdrs = glob(["lib/**"]),
  visibility = ["//visibility:public"],
)

四远程bazel工程

.
├── BUILD
├── main.cc
└── WORKSPACE

WORKSPACE

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "gtest",
    sha256 = "9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb",
    strip_prefix = "googletest-release-1.10.0",
    urls = [
         "https://apollo-system.cdn.bcebos.com/archive/6.0/release-1.10.0.tar.gz",
         "https://github.com/google/googletest/archive/release-1.10.0.tar.gz",
   ],
)

BUILD

cc_test(
    name = "gtest",
    srcs = ["main.cc"],
    copts = ["-Iexternal/gtest/include"],
    deps = [
        "@gtest//:gtest_main",
    ],
)

五远程非bazel工程

.
├── BUILD
├── gtest.BUILD
├── main.cc
└── WORKSPACE

BUILD

cc_test(
    name = "gtest",
    srcs = ["main.cc"],
    copts = ["-Iexternal/gtest/include"],
    deps = [
    "@gtest//:main",
    ],
)

gtest.BUILD

cc_library(
    name = "main",
    srcs = glob(
        ["src/*.cc"],
        exclude = ["src/gtest-all.cc"]
    ),
    hdrs = glob([
        "include/**/*.h",
        "src/*.h"
    ]),
    copts = ["-Iexternal/gtest/include"],
    linkopts = ["-pthread"],
    visibility = ["//visibility:public"],
)

WORKSPACE

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "gtest",
    url = "https://github.com/google/googletest/archive/release-1.7.0.zip",
    sha256 = "b58cb7547a28b2c718d1e38aee18a3659c9e3ff52440297e965f5edffe34b6d0",
    build_file = "@//:gtest.BUILD",
    strip_prefix = "googletest-release-1.7.0",
)

全局配置

针对每个target我们可以采用copts参数来配置编译参数但是如果有些参数需要全局配置时通过copts就比较麻烦。针对这种场景bazel提供了一个方案在根目录创建.bazelrc文件比如配置c++11作为c++标准。

build --copt=-std=c++11

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++Ubuntu