[英]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.