簡單介紹如何使用Bazel構建Golang程式
導讀 | 這篇文章主要為大家介紹瞭如何使用Bazel構建Golang程式例項詳解,有需要的朋友可以借鑑參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪 |
在這篇簡短的文章中,我們將介紹如何將 Golang 與 Bazel 構建系統結合使用。
具體來說,我們將討論三個場景:
- 從頭開始一個 Golang 專案;
- 將一個現有的 Golang 專案轉換為 Bazel 構建;
- 以及將一個第三方 Golang 專案引入到您的 Bazel 構建系統。
讓我們從將 Go 與 Bazel 結合使用的基礎知識開始。
為此,我們需要從 github.com/bazelbuild/… 獲取 Go 語言的官方構建規則。
在配置部分,您會發現:我們需要將以下這段 Starlark 語言程式碼,放入名為 WORKSPACE 的配置檔案裡面:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", sha256 = "8e968b5fcea1d2d64071872b12737bbb5514524ee5f0a4f54f5920266c261acb", urls = [ " " ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") go_rules_dependencies() go_register_toolchains(version = "1.16.5")
讓我們逐步瞭解這段程式碼所做的事情。
首先,我們使用load指令來載入並提取新功能,以在 Bazel 檔案當中能夠使用該功能。我們呼叫了兩次load指令,第一次用於匯入下載 HTTP 程式碼庫的能力,第二次則是從剛下載的程式碼庫中載入特定於 Go 的 。
對於匯入本身,我們需要提供一個匯入名稱。通常的命名方案是:逆反域名,後面跟名稱空間和專案名稱;並需將/和.全部都轉換為下劃線_。例如:github.com/user/project變成com_github_user_project。io_bazel_rules_go這個專案由於是Bazel官方專案中的一部分,所以它使用的是bazel.io而不是github.com。
如果您並不熟悉 Bazel,那麼,您需要了解到:實際的構建配置是透過BUILD檔案完成的。我們可以將 Go 視為任何其他語言,並使用遵循相同結構的規則:go_binary、go_library和go_test。我在我的 Github 上準備了一個最小化的例子:github.com/HappyCerber…。您會注意到,我們需要從匯入的io_bazel_rules_go程式碼庫中載入這些規則,以使其在BUILD檔案中可用。
現在我們知道,從頭全新開始是很容易。但是,如果您已經有一個 Golang 專案,並且需要將其轉換為 使用 Bazel 構建怎麼辦?為此,我們需要使用 Bazel 官方專案中提供的另一個工具 Gazelle ( github.com/bazelbuild/… )。
為了演示,我將使用一個第三方專案 ( github.com/aler9/rtsp-… ),我目前正在為即將到來的系統設計課程修改該專案。
首先,我們需要建立一個WORKSPACE檔案,並從 Gazelle 程式碼庫的設定部分複製貼上程式碼。
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "io_bazel_rules_go", sha256 = "8e968b5fcea1d2d64071872b12737bbb5514524ee5f0a4f54f5920266c261acb", urls = [ " " ], ) http_archive( name = "bazel_gazelle", sha256 = "62ca106be173579c0a167deb23358fdfe71ffa1e4cfdddf5582af26520f1c66f", urls = [ " " ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") go_rules_dependencies() go_register_toolchains(version = "1.16.5") gazelle_dependencies()
您會注意到,上述程式碼也匯入了上一節中所提到的規則。
現在,要真正執行 Gazelle,我們需要將以下程式碼新增到我們的主BUILD檔案中:
load("@bazel_gazelle//:def.bzl", "gazelle") # gazelle:prefix github.com/aler9/rtsp-simple-server gazelle(name = "gazelle")
gazelle:prefix註釋後面的路徑是整個專案所使用的 Go 匯入路徑。例如,main.go中有以下包的匯入:
import ( "os" "github.com/aler9/rtsp-simple-server/internal/core" )
至此,我們終於可以真正執行Gazelle,讓它BUILD為我們的專案生成檔案了。
bazel run //:gazelle
之後,我們應該BUILD自動生成專案的所有檔案:
git status On branch main Your branch is up to date with 'origin/main'. Untracked files: (use "git add..." to include in what will be committed) BUILD WORKSPACE bazel-bin bazel-out bazel-test bazel-testlogs internal/aac/BUILD.bazel internal/conf/BUILD.bazel internal/confenv/BUILD.bazel internal/confwatcher/BUILD.bazel internal/core/BUILD.bazel internal/externalcmd/BUILD.bazel internal/h264/BUILD.bazel internal/hls/BUILD.bazel internal/logger/BUILD.bazel internal/rlimit/BUILD.bazel internal/rtcpsenderset/BUILD.bazel internal/rtmp/BUILD.bazel nothing added to commit but untracked files present (use "git add" to track)
但是,如果您嘗試使用bazel build //... 構建專案,實際上您會看到許多關於未定義程式碼庫的錯誤。這是因為我們仍然缺少專案依賴項的定義。然而,Gazelle 連這件事也可以為我們辦好(to_macro引數是可選的):
bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=deps.bzl%go_dependencies
此命令將生成一個檔名為deps.bzl的新檔案(如果我們在WORKSPACE中有使用repository_macro指令定義過,那麼我們省略該to_macro指令),載入該檔案,以匯入構建專案所需的所有程式碼庫。
load("@bazel_gazelle//:deps.bzl", "go_repository") def go_dependencies(): go_repository( name = "com_github_alecthomas_template", importpath = "github.com/alecthomas/template", sum = "h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=", version = "v0.0.0-20190718012654-fb15b899a751", ) go_repository( name = "com_github_alecthomas_units", importpath = "github.com/alecthomas/units", sum = "h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=", version = "v0.0.0-20190924025748-f65c72e2690d", ) go_repository( name = "com_github_aler9_gortsplib", importpath = "github.com/aler9/gortsplib", sum = "h1:Bf0hzdN1jUWsb5Mzezq1pd18EIBeKXxk5clIpHZJ1Lk=", version = "v0.0.0-20210724151831-dae5a1f04033", ) go_repository( ...
在這個程式碼庫裡,我實際上遇到了一個小問題。構建仍然是失敗的,因為它匯入的org_golang_x_tools被錯誤地推斷為依賴項(透過從deps.bzl中刪除它來修復這個問題)。您可以在我的專案分支:github.com/HappyCerber…上看到rtsp-simple-server的最終結果。
您可以在後續繼續使用 Gazelle 來管理依賴項,這也是您可以將程式碼庫引入基於 Bazel 的專案而無需實際轉換它的方法:
bazel run //:gazelle -- update-repos github.com/some/repo
您可能會遇到的最後一個問題是密封測試。如果您看到測試因訪問被拒絕、檔案未找到或操作不允許失敗而失敗,那是因為 Bazel 強制執行密封測試。這意味著每個測試都必須完全獨立並且獨立於任何其他測試。
對於單元測試,任何檔案都需要作為測試的依賴項提供並透過執行檔案機制訪問(github.com/bazelbuild/…)。
環境變數中提供了每個測試的臨時目錄,您將使用TEST_TMPDIR而不是傳統的os.TempDir()函式。
密封整合和系統測試需要從一開始就仔細設計,因此轉換現有的此類測試可能很棘手。遺憾的是,我在這裡沒有放之四海而皆準的建議。
雖然將您的測試轉換為密封測試可能很煩人,但這是一項值得的努力,它將為您帶來更好的測試可重複性和更低的易碎性。
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2938192/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- jQuery建構函式簡單介紹jQuery函式
- js Date()建構函式簡單介紹JS函式
- SVG程式碼構成簡單介紹SVG
- javascript建構函式的繼承簡單介紹JavaScript函式繼承
- javascript非建構函式繼承簡單介紹JavaScript函式繼承
- vue-cli快速構建專案簡單介紹Vue
- Maven簡單介紹——必要的Java管理與構建MavenJava
- 如何除錯javascript程式碼簡單介紹除錯JavaScript
- 簡單介紹Golang列印複雜結構體的兩種方法Golang結構體
- html文件結構簡單介紹HTML
- python內建函式的簡單使用和介紹Python函式
- CSS程式碼重構與優化簡單介紹CSS優化
- 如何學習javascript簡單介紹JavaScript
- javascript如何操作iframe簡單介紹JavaScript
- javascript如何實現模組程式設計簡單介紹JavaScript程式設計
- groovy 程式語言簡單介紹
- [轉]:如何快速構建一個簡單的程式
- js如何阻止表單提交簡單介紹JS
- 簡單介紹nginx 變數使用Nginx變數
- webstorm簡單介紹,webstrom基本使用WebORM
- [譯] 如何使用原生 JavaScript 構建簡單的 Chrome 擴充套件程式JavaScriptChrome套件
- C++移動建構函式以及move語句簡單介紹C++函式
- jQuery構造物件例項簡單介紹jQuery物件
- javascript程式碼規範簡單介紹JavaScript
- 簡單介紹nginx反向代理及使用Nginx
- POP簡單介紹與使用實踐
- SVG簡單介紹SVG
- HTML簡單介紹HTML
- ActiveMQ簡單介紹MQ
- HTML 簡單介紹HTML
- JavaScript 簡單介紹JavaScript
- CSS 簡單介紹CSS
- SCSS 簡單介紹CSS
- UICollectionView 簡單介紹UIView
- css簡單介紹CSS
- 簡單介紹Golang切片刪除指定元素的三種方法Golang
- 如何編寫高效率額css程式碼簡單介紹CSS
- 簡單介紹架構設計的原則!架構