Bazel 教學課程:建構 C++ 專案

回報問題 查看來源 。 。 。 。 夜間。 。 7.3 。 。 7.2 。 。 7.1 。 。 7.0 。 。 6.5

簡介

第一次使用 Bazel 嗎?開啟 Google AI 就對了!請按照這個「First Build」教學課程, 以簡化使用 Bazel 的簡介。本教學課程將定義重要詞彙 用於 Bazel 環境,並逐步引導您瞭解 Bazel 的基本概念 工作流程從您需要的工具開始,您將建構並執行 以及學習複雜性做法和原因。

雖然 Bazel 是一套建構系統 支援多語言建構,本教學課程使用 C++ 專案做為範例 ,並提供大多數語言適用的一般指南和流程。

預計完成時間:30 分鐘。

必要條件

首先請安裝 Bazel (如果尚未安裝) 本教學課程使用 Git 控管原始碼,因此如要獲得最佳結果,請安裝 Git 也是。

接著,執行 安裝在您選擇的指令列工具中:

git clone https://github.com/bazelbuild/examples

本教學課程的範例專案位於 examples/cpp-tutorial 目錄。

一起來看看其結構:

examples
└── cpp-tutorial
    ├──stage1
    │  ├── main
    │  │   ├── BUILD
    │  │   └── hello-world.cc
    │  └── MODULE.bazel
    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── MODULE.bazel
    └──stage3
       ├── main
       │   ├── BUILD
       │   ├── hello-world.cc
       │   ├── hello-greet.cc
       │   └── hello-greet.h
       ├── lib
       │   ├── BUILD
       │   ├── hello-time.cc
       │   └── hello-time.h
       └── MODULE.bazel

有三組檔案,每組都代表本教學課程中的一個階段。 在第一階段中,您會在單一套件中建構單一目標。在第二階段中 從單一套件同時建構二進位檔與程式庫。第三次,也是最後一項 階段,您將使用多個套件建立專案,並使用 有多個目標。

摘要:簡介

安裝 Bazel (和 Git) 並複製本教學課程的存放區 也都透過 Bazel 奠定了首次建構的基礎。前往下一項 這個部分定義一些字詞 workspace

開始使用

您必須先設定專案工作區,才能建立專案。工作區 目錄,用於保存專案來源檔案和 Bazel 的建構輸出內容。 還包含下列重要檔案:

  • MODULE.bazel 檔案,用來識別目錄及其內容 Bazel 工作區,位於專案目錄的根目錄 成本中心的架構您也可以在該頁面指定外部依附元件。
  • 一或多個 BUILD 檔案,用於告知 Bazel 建構專案的不同部分在 包含 BUILD 檔案的工作區是 「package」。(進一步瞭解套件 其他部分)。

如要在日後的專案中將目錄指定為 Bazel 工作區,請建立 該目錄中名為 MODULE.bazel 的空檔案。為了便於 每個階段中都會有一個 MODULE.bazel 檔案

瞭解 BUILD 檔案

BUILD 檔案包含多種不同類型的 Bazel 指示。每項 「BUILD」檔案至少需要一個 「規則」當做一組指示 讓 Bazel 知道如何建構您想要的輸出內容,例如可執行的二進位檔 或程式庫BUILD 檔案中每個建構規則的執行個體都稱為 target 並指向特定的 一組來源檔案 依附元件。單一目標可以 指向其他目標

請查看 cpp-tutorial/stage1/main 目錄中的 BUILD 檔案:

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

在我們的範例中,hello-world 目標會將 Bazel 的內建項目執行個體化 cc_binary 規則。規則 會告知 Bazel 從 hello-world.cc>沒有依附元件的來源檔案

摘要:開始使用

您現在已熟悉一些重要字詞,以及這些詞彙的用意 這個專案和 Bazel在下一節中,您將建構及測試 專案的第 1 階段。

第 1 階段:單一目標、單一套件

接下來我們要建構專案的第一部分。如需視覺參考, 專案的第 1 階段的結構如下

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

執行下列指令,移至 cpp-tutorial/stage1 目錄:

cd cpp-tutorial/stage1

接著執行:

bazel build //main:hello-world

在目標標籤中,//main: 部分是 BUILD 檔案的位置 相對於工作區的根目錄,而 hello-worldBUILD 檔案。

Bazel 會產生如下所示的內容:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s

您剛剛建構了第一個 Bazel 目標。Bazel 會將建構輸出內容放在 bazel-bin 目錄位於工作區的根目錄中。

現在請測試剛建構的二進位檔,方法如下:

bazel-bin/main/hello-world

這會產生列印的「Hello world」撰寫新的電子郵件訊息

以下是第 1 階段的依附元件圖:

hello-world 的依附元件圖會顯示具有單一來源的單一目標
檔案。

摘要:階段 1

現在您已經完成第一個版本,現在您可以使用 的結構在下一個階段中,您將提高 其他目標。

第 2 階段:多個建構目標

雖然一個目標就足以滿足小型專案的需求,而您可能想要 轉化成多個目標和套件這樣一來 漸進式建構作業,也就是說 Bazel 只會重新建構已變更的內容 即可預先建構專案的多個部分 教學課程會新增目標,接下來則會新增套件

以下是您將在第 2 階段使用的目錄:

    ├──stage2
    │  ├── main
    │  │   ├── BUILD
    │  │   ├── hello-world.cc
    │  │   ├── hello-greet.cc
    │  │   └── hello-greet.h
    │  └── MODULE.bazel

請查看 cpp-tutorial/stage2/main 目錄中的 BUILD 檔案:

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",
    ],
)

有了這個 BUILD 檔案,Bazel 會先建構 hello-greet 程式庫 (使用 Bazel 的內建 cc_library 規則),則 hello-world 二進位檔。hello-world 目標中的 deps 屬性會告訴 使用 hello-greet 程式庫建構 hello-world 所需的 Bazel 二進位檔案。

您必須先變更 請執行以下指令,切換至 cpp-tutorial/stage2 目錄:

cd ../stage2

現在您可以使用以下熟悉的指令來建構新的二進位檔:

bazel build //main:hello-world

Bazel 再次產生如下的內容:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s

您現在可以測試剛剛建構的二進位檔,此程式碼會傳回另一個「Hello world」:

bazel-bin/main/hello-world

如果您現在修改 hello-greet.cc 並重新建構專案,則只有 Bazel 就會重新編譯該檔案

查看依附元件圖表時,您會發現 hello-world 依附 額外輸入名為 hello-greet 的輸入內容:

`hello-world` 的依附元件圖會顯示之後的依附元件變更
修改檔案內容

摘要:階段 2

您現在已建立具有兩個目標的專案。hello-world 目標版本 一個來源檔案,並依附另一個目標 (//main:hello-greet),而 建立兩個額外的來源檔案在下一節中, 然後新增其他套件

第 3 階段:多個套件

下一個階段加入另一層小工具,並使用 管理多個套件查看 Pod 的結構和內容 cpp-tutorial/stage3 目錄:

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

可以看到現在有兩個子目錄,且每個子目錄都包含 BUILD 檔案。因此,在 Bazel 中,工作區現在包含兩個套件:libmain

請看看 lib/BUILD 檔案:

cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)

main/BUILD 檔案中:

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",
        "//lib:hello-time",
    ],
)

主要套件中的 hello-world 目標取決於 hello-time 目標 在 lib 套件中 (因此目標標籤 //lib:hello-time) - Bazel 知道 透過 deps 屬性達成這個目的您可以在依附元件中看到這點 圖表:

`hello-world` 的依附元件圖顯示主套件中的目標方式
取決於 `lib` 中的目標
套件。

為了讓建構成功,您需要在 lib/BUILD 中進行 //lib:hello-time 目標 使用瀏覽權限屬性在 main/BUILD 中的目標明確顯示。 這是因為根據預設,系統只會向同一個帳戶的其他指定目標 BUILD 檔案。Bazel 會使用目標瀏覽權限防止程式庫等問題 包含洩漏至公用 API 的實作詳細資料。

接著建構這個專案的最終版本。切換至 cpp-tutorial/stage3 執行以下命令:

cd  ../stage3

再次執行下列指令:

bazel build //main:hello-world

Bazel 會產生如下所示的內容:

INFO: Found 1 target...
Target //main:hello-world up-to-date:
  bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s

現在請測試本教學課程的最後一個二進位檔,看看最後的 Hello world 訊息:

bazel-bin/main/hello-world

摘要:階段 3

您現在已將專案建構為兩個套件,其中包含三個目標,並瞭解 掌握依附元件 可在專案中使用 Bazel 執行下一節將說明如何繼續 Bazel 的歷程。

後續步驟

您已經使用 Bazel 完成第一個基本建構作業,不過這只是 。以下是一些繼續透過 Bazel 學習的資源:

祝您建構愉快!