簡體   English   中英

在 Bazel 項目中包含 C++ 庫

[英]Include C++ library in Bazel project

我目前正在搞亂谷歌的 Mediapipe ,它使用 Bazel 作為構建工具。 該文件夾具有以下結構:

mediapipe
    ├ mediapipe
    |   └ examples
    |        └ desktop
    |             └ hand_tracking
    |                  └ BUILD
    ├ calculators
    |   └ tensor
    |        └ tensor_to_landmarks_calculator.cc
    |        └ BUILD
    └ WORKSPACE

那里還有很多其他文件,但它們與這個問題無關。 如果您需要它們,可以在上面鏈接的 git repo 中找到它們。

我正處於可以毫無問題地構建和運行 hand_tracking 示例的階段。 現在,我想將谷物庫包含到構建中,以便我可以在tensors_to_landmarks_calculator.cc中使用#include <cereal/archives/binary.hpp> 谷物庫位於C:\\cereal ,但如果它簡化了流程,可以移動到其他位置。

基本上,我正在尋找與在 Visual Studio 中添加到Additional Include Directories的路徑的 Bazel 等效項。

假設它們處於默認狀態,我將如何修改 WORKSPACE 和 BUILD 文件以將庫包含在我的項目中?

不幸的是,這個官方文檔頁面只涵蓋了一個文件庫,並且其他實現在構建時不斷給我File could not be found錯誤。

提前致謝!

首先,您必須告訴 Bazel 工作區“外部”的代碼。 它需要知道如何找到它、如何構建它以及如何調用它等。這些被稱為遠程存儲庫。 它們可以在您的磁盤本地(在 Bazel 工作區之外),或者實際上在另一台機器或服務器上遠程,例如 github。 重要的是必須向 Bazel 描述它可以使用的足夠信息。

由於大多數第三方代碼不附帶 BUILD.bazel 文件,您可能需要自己提供一個並告訴 Bazel“使用它,就好像它是在該代碼中找到的構建文件一樣”。

對於 bazel 項目之外的本地目錄

將這樣的存儲庫規則添加到您的 WORKSPACE 文件中:

# This could go in your WORKSPACE file
# (But prefer the http_archive solution below)
new_local_repository(
    name = "cereal",
    build_file = "//third_party:cereal.BUILD.bazel",
    path = "<path-to-directory>",
)

(“new_local_repository”內置於 bazel)

在您的 Bazel WORKSPACE 區域下的某個地方,您還需要制作一個cereal.BUILD.bazel文件並將其從包中導出。 我選擇了一個名為 //third_party 的目錄,但是您可以將它放在其他任何地方,並為它命名,只要存儲庫規則為其提供適當的 bazel 標簽。)內容可能如下所示:

# contents of //third_party/cereal.BUILD.bazel
cc_library(
    name = "cereal-lib",
    srcs = glob(["**/*.hpp"]),
    includes = ["include"],
    visibility = ["//visibility:public"],
)

Bazel 會假裝這是遠程存儲庫“附帶”的 BUILD 文件,即使它實際上是您的存儲庫的本地文件。 當 Bazel 獲取此遠程存儲庫代碼時,它會將其和您提供的 BUILD 文件復制到其外部區域以進行緩存、構建等。

要使 //third_party:cereal.BUILD.bazel 成為您目錄中的有效目標,請將 BUILD.bazel 文件添加到該目錄:

# contents of //third_party/BUILD.bazel

exports_files = [
    "cereal.BUILD.bazel",
]

如果不導出它,您將無法從存儲庫規則中引用構建文件。

本地磁盤存儲庫不是很便攜,因為人們可能安裝了不同的版本並且它不是很封閉(很難與其他人共享構建的緩存),並且它要求他們將它們放在同一個地方,這種設置可以有問題。 當您混合操作系統等時,它也會失敗,如果您將其稱為“C:...”

例如,從 github 下載庫的 tarball

更好的方法是從 github 下載一個固定版本,例如,讓 Bazel 在其外部區域為您管理它:

http_archive(
    name = "cereal",
    sha256 = "329ea3e3130b026c03a4acc50e168e7daff4e6e661bc6a7dfec0d77b570851d5",
    urls = 
["https://github.com/USCiLab/cereal/archive/refs/tags/v1.3.0.tar.gz"],
    build_file = "//third_party:cereal.BUILD.bazel",
)

sha256 很重要,因為它會下載並計算它,與您指定的內容進行比較,並可以緩存它。 以后如果本地文件的sha匹配就不會重新下載了。

請注意,它再次顯示 build_file = //third_party:cereal.BUILD.bazel. ,上面 new_local_repository 中的所有相同內容都適用於此。 確保提供構建文件以供它使用,並從放置它的位置導出它。

*測試遠程存儲庫是否設置好

關於命令行問題

bazel fetch @cereal//:cereal-lib

如果我的規則不太正確,我有時必須清除它以使其重試,但“壞”版本仍然存在。

bazel clean --expunge

將刪除它,但可能是矯枉過正。

最后

我們有:

  • 定義了一個名為@cereal的遠程存儲庫
  • 在其中定義了一個名為cereal-lib的目標
  • 因此,目標是@cereal//:cereal-lib

使用它

轉到您想要包含谷物的包,並將對該存儲庫的依賴添加到構建想要使用谷物的 c++ 代碼的規則中。 也就是說,在您的情況下,導致tensor_to_landmarks_calculator.cc構建的 BUILD 規則,添加:

   deps = [
       "@cereal//:cereal-lib",
       ...
   ]

然后在你的 C++ 代碼中:

#include "cereal/cereal.hpp"

那應該這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM