เนื่องจากข้อบกพร่องของ WORKSPACE Bzlmod กำลังจะแทนที่ระบบ WORKSPACE แบบเดิม ระบบจะปิดใช้ไฟล์ WORKSPACE โดยค่าเริ่มต้นใน Bazel 8 (ปลายปี 2024) และจะนำออกใน Bazel 9 (ปลายปี 2025) คำแนะนำนี้จะช่วยคุณย้ายข้อมูลโปรเจ็กต์ไปยัง Bzlmod และวาง WORKSPACE สำหรับการดึงข้อมูลทรัพยากร Dependency ภายนอก
WORKSPACE เทียบกับ Bzlmod
WORKSPACE และ Bzlmod ของ Bazel มีฟีเจอร์ที่คล้ายกันแต่ไวยากรณ์ต่างกัน ส่วนนี้จะอธิบายวิธีย้ายข้อมูลจากฟังก์ชันการทำงานบางอย่างของ WORKSPACE ไปยัง Bzlmod
กำหนดรูทของพื้นที่ทํางาน Bazel
ไฟล์ WORKSPACE จะทําเครื่องหมายรูทแหล่งที่มาของโปรเจ็กต์ Bazel โดยหน้าที่นี้จะแทนที่ด้วย MODULE.bazel ใน Bazel เวอร์ชัน 6.3 ขึ้นไป เมื่อใช้ Bazel เวอร์ชันก่อน 6.3 ไฟล์ WORKSPACE
หรือ WORKSPACE.bazel
ควรยังอยู่ที่รูทของเวิร์กスペース โดยอาจมีความคิดเห็นอย่างเช่น
WORKSPACE
# This file marks the root of the Bazel workspace. # See MODULE.bazel for external dependencies setup.
เปิดใช้ Bzlmod ใน bazelrc
.bazelrc
ช่วยให้คุณตั้งค่า Flag ที่มีผลทุกครั้งที่คุณเรียกใช้ Bazel หากต้องการเปิดใช้ Bzlmod ให้ใช้ Flag --enable_bzlmod
และนำไปใช้กับคำสั่ง common
เพื่อให้มีผลกับทุกคำสั่ง
.bazelrc
# Enable Bzlmod for every Bazel command common --enable_bzlmod
ระบุชื่อที่เก็บสำหรับพื้นที่ทำงาน
WORKSPACE
ใช้ฟังก์ชัน
workspace
เพื่อระบุชื่อที่เก็บสำหรับพื้นที่ทำงานของคุณ ซึ่งช่วยให้อ้างอิงเป้าหมาย//foo:bar
ในพื้นที่ทํางานเป็น@<workspace name>//foo:bar
ได้ หากไม่ได้ระบุไว้ ชื่อที่เก็บข้อมูลเริ่มต้นสำหรับที่ทำงานของคุณจะเป็น__main__
## WORKSPACE workspace(name = "com_foo_bar")
Bzlmod
ขอแนะนำให้อ้างอิงเป้าหมายในพื้นที่ทำงานเดียวกันด้วยไวยากรณ์
//foo:bar
ที่ไม่มี@<repo name>
แต่หากต้องการใช้ไวยากรณ์เดิม ก็ใช้ชื่อโมดูลที่ระบุโดยฟังก์ชันmodule
เป็นชื่อที่เก็บได้ หากชื่อโมดูลแตกต่างจากชื่อที่เก็บที่จำเป็น คุณใช้แอตทริบิวต์repo_name
ของฟังก์ชันmodule
เพื่อลบล้างชื่อที่เก็บได้## MODULE.bazel module( name = "bar", repo_name = "com_foo_bar", )
ดึงข้อมูล Dependency ภายนอกเป็นโมดูล Bazel
หาก Dependency เป็นโปรเจ็กต์ Bazel คุณควรใช้ Dependency ดังกล่าวเป็นโมดูล Bazel ได้เมื่อโปรเจ็กต์ดังกล่าวใช้ Bzlmod ด้วย
พื้นที่ทำงาน
ใน Workspace เป็นเรื่องปกติที่จะใช้กฎที่เก็บ
http_archive
หรือgit_repository
เพื่อดาวน์โหลดแหล่งที่มาของโปรเจ็กต์ Bazel## WORKSPACE load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "bazel_skylib", urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"], sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa", ) load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") bazel_skylib_workspace() http_archive( name = "rules_java", urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"], sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a", ) load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains") rules_java_dependencies() rules_java_toolchains()
ดังที่คุณเห็น นี่เป็นรูปแบบทั่วไปที่ผู้ใช้ต้องโหลดข้อกําหนดเบื้องต้นแบบเปลี่ยนผ่านจากมาโครของข้อกําหนดเบื้องต้น สมมติว่าทั้ง
bazel_skylib
และrules_java
ขึ้นอยู่กับplatform
ลำดับของมาโครจะเป็นตัวกำหนดเวอร์ชันที่แน่นอนของplatform
ที่ต้องพึ่งพาBzlmod
เมื่อใช้ Bzlmod ตราบใดที่ข้อกำหนดของคุณมีอยู่ใน Bazel Central Registry หรือ Bazel registry ที่กำหนดเอง คุณก็ใช้ข้อกำหนดนั้นได้โดยง่ายด้วยคำสั่ง
bazel_dep
## MODULE.bazel bazel_dep(name = "bazel_skylib", version = "1.4.2") bazel_dep(name = "rules_java", version = "6.1.1")
Bzlmod จะแก้ไขการพึ่งพาโมดูล Bazel แบบทรานซิทีฟโดยใช้อัลกอริทึม MVS ดังนั้น ระบบจะเลือก
platform
เวอร์ชันสูงสุดที่จำเป็นโดยอัตโนมัติ
ลบล้างการขึ้นต่อกันเป็นโมดูล Bazel
ในฐานะโมดูลรูท คุณสามารถลบล้างการพึ่งพาโมดูล Bazel ได้หลายวิธี
โปรดอ่านข้อมูลเพิ่มเติมที่ส่วนการลบล้าง
คุณดูตัวอย่างการใช้งานได้ในที่เก็บตัวอย่าง
ดึงข้อมูลทรัพยากร Dependency ภายนอกด้วยส่วนขยายโมดูล
หากทรัพยากร Dependency ไม่ใช่โปรเจ็กต์ Bazel หรือยังไม่พร้อมใช้งานในรีจิสทรี Bazel ใดๆ คุณสามารถนําเข้าโดยใช้ use_repo_rule
หรือส่วนขยายของข้อบังคับ
WORKSPACE
ดาวน์โหลดไฟล์โดยใช้กฎที่เก็บ
http_file
## WORKSPACE load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
Bzlmod
เมื่อใช้ Bzlmod คุณจะใช้คำสั่ง
use_repo_rule
ในไฟล์ MODULE.bazel เพื่อสร้างอินสแตนซ์ repos ได้โดยตรง โดยทำดังนี้## MODULE.bazel http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
การดำเนินการนี้ทำงานอยู่เบื้องหลังโดยใช้ส่วนขยายโมดูล หากต้องการใช้ตรรกะที่ซับซ้อนกว่าการเรียกใช้กฎของ repo คุณยังติดตั้งใช้งานส่วนขยายโมดูลด้วยตนเองได้ด้วย คุณจะต้องย้ายคำจำกัดความไปไว้ในไฟล์
.bzl
ซึ่งช่วยให้คุณแชร์คำจำกัดความระหว่าง WORKSPACE และ Bzlmod ในระหว่างที่มีการย้ายข้อมูลได้## repositories.bzl load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") def my_data_dependency(): http_file( name = "data_file", url = "http://example.com/file", sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", )
ใช้ส่วนขยายโมดูลเพื่อโหลดมาโครการอ้างอิง คุณจะกำหนดมาโครดังกล่าวในไฟล์
.bzl
เดียวกันก็ได้ แต่หากต้องการรักษาความเข้ากันได้กับ Bazel เวอร์ชันเก่า ควรกำหนดในไฟล์.bzl
แยกต่างหาก## extensions.bzl load("//:repositories.bzl", "my_data_dependency") def _non_module_dependencies_impl(_ctx): my_data_dependency() non_module_dependencies = module_extension( implementation = _non_module_dependencies_impl, )
หากต้องการทำให้ที่เก็บปรากฏแก่โปรเจ็กต์รูท คุณควรประกาศการใช้ส่วนขยายโมดูลและที่เก็บในไฟล์ MODULE.bazel
## MODULE.bazel non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies") use_repo(non_module_dependencies, "data_file")
แก้ไขข้อขัดแย้งของทรัพยากรภายนอกด้วยส่วนขยายโมดูล
โปรเจ็กต์จะมีมาโครที่แนะนำที่เก็บภายนอกตามอินพุตจากผู้โทรได้ แต่จะเกิดอะไรขึ้นหากมีผู้เรียกใช้หลายรายในกราฟความเกี่ยวข้องและทําให้เกิดข้อขัดแย้ง
สมมติว่าโปรเจ็กต์ foo
มีมาโครต่อไปนี้ซึ่งใช้ version
เป็นอาร์กิวเมนต์
## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
http_file(
name = "data_file",
url = "http://example.com/file-%s" % version,
# Omitting the "sha256" attribute for simplicity
)
WORKSPACE
เมื่อใช้ WORKSPACE คุณจะโหลดมาโครจาก
@foo
และระบุเวอร์ชันของข้อมูลที่ต้องพึ่งพาที่ต้องการได้ สมมติว่าคุณมี@bar
รายการอื่น ซึ่งก็ขึ้นอยู่กับ@foo
ด้วย แต่ต้องใช้ข้อมูล Dependency เวอร์ชันอื่น## WORKSPACE # Introduce @foo and @bar. ... load("@foo//:repositories.bzl", "data_deps") data_deps(version = "2.0") load("@bar//:repositories.bzl", "bar_deps") bar_deps() # -> which calls data_deps(version = "3.0")
ในกรณีนี้ ผู้ใช้ปลายทางต้องปรับลำดับของมาโครใน Workspace อย่างระมัดระวังเพื่อให้ได้เวอร์ชันที่ต้องการ ปัญหานี้เป็นหนึ่งในปัญหาที่ใหญ่ที่สุดของ Workspace เนื่องจากไม่มีวิธีแก้ปัญหาการพึ่งพาอย่างสมเหตุสมผล
Bzlmod
เมื่อใช้ Bzlmod ผู้เขียนโปรเจ็กต์
foo
จะใช้ส่วนขยายโมดูลเพื่อแก้ไขข้อขัดแย้งได้ ตัวอย่างเช่น สมมติว่าการเลือกเวอร์ชันสูงสุดของข้อมูลที่ต้องพึ่งพาในโมดูล Bazel ทั้งหมดนั้นเหมาะสมเสมอ## extensions.bzl in foo load("//:repositories.bzl", "data_deps") data = tag_class(attrs={"version": attr.string()}) def _data_deps_extension_impl(module_ctx): # Select the maximal required version in the dependency graph. version = "1.0" for mod in module_ctx.modules: for data in mod.tags.data: version = max(version, data.version) data_deps(version) data_deps_extension = module_extension( implementation = _data_deps_extension_impl, tag_classes = {"data": data}, )
## MODULE.bazel in bar bazel_dep(name = "foo", version = "1.0") foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension") foo_data_deps.data(version = "3.0") use_repo(foo_data_deps, "data_file")
## MODULE.bazel in root module bazel_dep(name = "foo", version = "1.0") bazel_dep(name = "bar", version = "1.0") foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension") foo_data_deps.data(version = "2.0") use_repo(foo_data_deps, "data_file")
ในกรณีนี้ โมดูลรูทต้องใช้ข้อมูลเวอร์ชัน
2.0
ในขณะที่การขึ้นต่อกันbar
ต้องใช้3.0
ส่วนขยายโมดูลในfoo
สามารถแก้ไขข้อขัดแย้งนี้ได้อย่างถูกต้องและเลือกเวอร์ชัน3.0
โดยอัตโนมัติสำหรับข้อมูลที่เกี่ยวข้อง
รวมตัวจัดการแพ็กเกจของบุคคลที่สาม
ในส่วนสุดท้าย เนื่องจากส่วนขยายโมดูลมีวิธีเก็บรวบรวมข้อมูลจากกราฟทรัพยากร Dependency จะใช้ตรรกะที่กำหนดเองเพื่อแก้ไขการขึ้นต่อกันและกฎที่เก็บการเรียกใช้เพื่อแนะนำที่เก็บภายนอก ซึ่งเป็นวิธีที่ยอดเยี่ยมสำหรับผู้เขียนกฎในการปรับปรุงชุดกฎที่ผสานรวมเครื่องมือจัดการแพ็กเกจสำหรับบางภาษา
โปรดอ่านหน้าส่วนขยายโมดูลเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ส่วนขยายโมดูล
ต่อไปนี้คือรายการชุดกฎที่ใช้ Bzlmod เพื่อดึงข้อมูลพึ่งพาจากเครื่องมือจัดการแพ็กเกจต่างๆ อยู่แล้ว
ตัวอย่างขั้นต่ำที่ผสานรวมตัวจัดการแพ็กเกจเทียมจะมีอยู่ในที่เก็บ examples
ตรวจหา Toolchain ในเครื่องโฮสต์
เมื่อกฎการสร้าง Bazel ต้องตรวจหาว่ามี Toolchain ใดบ้างที่ใช้ได้บนเครื่องโฮสต์ กฎดังกล่าวจะใช้กฎของที่เก็บเพื่อตรวจสอบเครื่องโฮสต์และสร้างข้อมูล Toolchain เป็นที่เก็บข้อมูลภายนอก
WORKSPACE
ตรวจหาเครื่องมือเชนของ Shell ตามกฎที่เก็บต่อไปนี้
## local_config_sh.bzl def _sh_config_rule_impl(repository_ctx): sh_path = get_sh_path_from_env("SH_BIN_PATH") if not sh_path: sh_path = detect_sh_from_path() if not sh_path: sh_path = "/shell/binary/not/found" repository_ctx.file("BUILD", """ load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain") sh_toolchain( name = "local_sh", path = "{sh_path}", visibility = ["//visibility:public"], ) toolchain( name = "local_sh_toolchain", toolchain = ":local_sh", toolchain_type = "@bazel_tools//tools/sh:toolchain_type", ) """.format(sh_path = sh_path)) sh_config_rule = repository_rule( environ = ["SH_BIN_PATH"], local = True, implementation = _sh_config_rule_impl, )
คุณโหลดกฎที่เก็บได้ใน WORKSPACE
## WORKSPACE load("//:local_config_sh.bzl", "sh_config_rule") sh_config_rule(name = "local_config_sh")
Bzlmod
เมื่อใช้ Bzlmod คุณจะแนะนำที่เก็บเดียวกันนี้ได้โดยใช้ส่วนขยายโมดูล ซึ่งคล้ายกับการแนะนำที่เก็บ
@data_file
ในส่วนสุดท้าย## local_config_sh_extension.bzl load("//:local_config_sh.bzl", "sh_config_rule") sh_config_extension = module_extension( implementation = lambda ctx: sh_config_rule(name = "local_config_sh"), )
จากนั้นใช้นามสกุลในไฟล์ MODULE.bazel
## MODULE.bazel sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension") use_repo(sh_config_ext, "local_config_sh")
ลงทะเบียนเครื่องมือและแพลตฟอร์มการดำเนินการ
หลังจากส่วนสุดท้าย หลังจากแนะนำข้อมูล Toolchain ของที่เก็บ (เช่น local_config_sh
) คุณอาจต้องการลงทะเบียน Toolchain
WORKSPACE
เมื่อใช้ WORKSPACE คุณจะลงทะเบียนเครื่องมือทางเทคนิคได้ดังนี้
คุณสามารถลงทะเบียนเครื่องมือชุดค่าผสมในไฟล์
.bzl
และโหลดมาโครในไฟล์ WORKSPACE## local_config_sh.bzl def sh_configure(): sh_config_rule(name = "local_config_sh") native.register_toolchains("@local_config_sh//:local_sh_toolchain")
## WORKSPACE load("//:local_config_sh.bzl", "sh_configure") sh_configure()
หรือลงทะเบียนเครื่องมือทางเทคนิคในไฟล์ WORKSPACE โดยตรง
## WORKSPACE load("//:local_config_sh.bzl", "sh_config_rule") sh_config_rule(name = "local_config_sh") register_toolchains("@local_config_sh//:local_sh_toolchain")
Bzlmod
เมื่อใช้ Bzlmod แล้ว API ของ
register_toolchains
และregister_execution_platforms
จะพร้อมใช้งานในไฟล์ MODULE.bazel เท่านั้น คุณเรียกใช้native.register_toolchains
ในส่วนขยายโมดูลไม่ได้## MODULE.bazel sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension") use_repo(sh_config_ext, "local_config_sh") register_toolchains("@local_config_sh//:local_sh_toolchain")
เครื่องมือและแพลตฟอร์มการเรียกใช้ที่ลงทะเบียนใน WORKSPACE
,
WORKSPACE.bzlmod
และไฟล์ MODULE.bazel
ของโมดูล Bazel แต่ละรายการจะเป็นไปตามลําดับความสําคัญนี้ (จากสูงไปต่ำ) ในระหว่างการเลือกเครื่องมือ
- Toolchains และแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์
MODULE.bazel
ของโมดูลรูท - เครื่องมือและแพลตฟอร์มการเรียกใช้ที่ลงทะเบียนในไฟล์
WORKSPACE
หรือWORKSPACE.bzlmod
- เครื่องมือและแพลตฟอร์มการดําเนินการที่ลงทะเบียนโดยโมดูลที่เป็นทรัพยากร Dependency (แบบเปลี่ยนผ่าน) ของโมดูลรูท
- เมื่อไม่ได้ใช้
WORKSPACE.bzlmod
: เครื่องมือทางเทคนิคที่ลงทะเบียนในWORKSPACE
ส่วนต่อท้าย
แนะนำที่เก็บข้อมูลในเครื่อง
คุณอาจต้องแนะนำทรัพยากร Dependency เป็นที่เก็บภายในเครื่องเมื่อต้องการทรัพยากร Dependency ในเวอร์ชันในเครื่องสำหรับการแก้ไขข้อบกพร่อง หรือหากต้องการรวมไดเรกทอรีในพื้นที่ทำงานเป็นที่เก็บภายนอก
WORKSPACE
การใช้ WORKSPACE ทำได้ตามกฎที่เก็บในเครื่อง 2 ข้อ ได้แก่
local_repository
และnew_local_repository
## WORKSPACE local_repository( name = "rules_java", path = "/Users/bazel_user/workspace/rules_java", )
Bzlmod
เมื่อใช้ Bzlmod คุณจะใช้
local_path_override
เพื่อลบล้างโมดูลด้วยเส้นทางภายในได้## MODULE.bazel bazel_dep(name = "rules_java") local_path_override( module_name = "rules_java", path = "/Users/bazel_user/workspace/rules_java", )
นอกจากนี้ คุณยังใช้ที่เก็บข้อมูลในเครื่องที่มีส่วนขยายของโมดูลได้ด้วย อย่างไรก็ตาม คุณจะเรียก
native.local_repository
ในส่วนขยายโมดูลไม่ได้ เรากําลังพยายามเปลี่ยนกฎของที่เก็บข้อมูลเดิมทั้งหมดให้เป็น Starlark (ดูความคืบหน้าที่ #18285) จากนั้นคุณจะเรียกใช้ Starlarklocal_repository
ที่เกี่ยวข้องได้ในโมดูลหรือส่วนขยาย นอกจากนี้ คุณยังใช้กฎที่กําหนดเองของที่เก็บlocal_repository
ได้ง่ายๆ หากปัญหานี้ทําให้คุณไม่สามารถดำเนินการต่อได้
เชื่อมโยงเป้าหมาย
กฎ bind
ใน WORKSPACE เลิกใช้งานแล้วและไม่รองรับใน Bzlmod ซึ่งเปิดตัวเพื่อตั้งชื่อแทนให้กับเป้าหมายในแพ็กเกจ //external
พิเศษ ผู้ใช้ทุกคนที่อาศัยข้อมูลนี้ควรย้ายข้อมูล
เช่น หากคุณมีผู้ติดตาม
## WORKSPACE
bind(
name = "openssl",
actual = "@my-ssl//src:openssl-lib",
)
ซึ่งช่วยให้เป้าหมายอื่นๆ ขึ้นอยู่กับ //external:openssl
ได้ คุณย้ายข้อมูลออกจากวิธีนี้ได้โดยทำดังนี้
แทนที่การใช้งาน
//external:openssl
ทั้งหมดด้วย@my-ssl//src:openssl-lib
หรือใช้กฎบิลด์
alias
กําหนดเป้าหมายต่อไปนี้ในแพ็กเกจ (เช่น
//third_party
)## third_party/BUILD alias( name = "openssl", actual = "@my-ssl//src:openssl-lib", )
แทนที่การใช้งาน
//external:openssl
ทั้งหมดด้วย//third_party:openssl
การดึงข้อมูลกับการซิงค์
ระบบจะใช้คำสั่ง "ดึงข้อมูล" และ "ซิงค์" เพื่อดาวน์โหลดที่เก็บข้อมูลภายนอกไว้ในเครื่องและอัปเดตอยู่เสมอ และบางครั้งก็เพื่ออนุญาตให้สร้างแบบออฟไลน์โดยใช้ Flag --nofetch
หลังจากดึงข้อมูลรีพอสิทั้งหมดที่จําเป็นสําหรับการสร้าง
WORKSPACE
การซิงค์จะดึงข้อมูลแบบบังคับสำหรับที่เก็บข้อมูลทั้งหมดหรือสำหรับชุดที่เก็บข้อมูลที่กําหนดค่าไว้โดยเฉพาะ ส่วนการดึงข้อมูลจะใช้เฉพาะเพื่อดึงข้อมูลเป้าหมายที่เฉพาะเจาะจง
Bzlmod
คำสั่งซิงค์ใช้ไม่ได้แล้ว แต่การดึงข้อมูลมีตัวเลือกต่างๆ คุณสามารถดึงข้อมูลเป้าหมาย พื้นที่เก็บข้อมูล ชุดที่กําหนดค่าไว้ หรือที่เก็บข้อมูลทั้งหมดที่เกี่ยวข้องกับการแก้ไขข้อกําหนดของทรัพยากรและส่วนขยายของโมดูล ระบบจะแคชผลการดึงข้อมูลไว้ และหากต้องการบังคับให้ดึงข้อมูล คุณต้องใส่ตัวเลือก
--force
ไว้ในกระบวนการดึงข้อมูล
การย้ายข้อมูล
ส่วนนี้จะให้ข้อมูลและคำแนะนำที่เป็นประโยชน์สำหรับกระบวนการย้ายข้อมูล Bzlmod
ทราบทรัพยากร Dependency ใน WORKSPACE
ขั้นตอนแรกของการย้ายข้อมูลคือการทําความเข้าใจรายการที่ต้องใช้ การระบุการพึ่งพาที่แน่นอนในไฟล์ WORKSPACE อาจเป็นเรื่องยาก เนื่องจากระบบมักจะโหลดการพึ่งพาแบบทรานซิทีฟด้วยมาโคร *_deps
ตรวจสอบทรัพยากรภายนอกด้วยไฟล์ที่แก้ไขแล้วของพื้นที่ทำงาน
โชคดีที่ Flag
--experimental_repository_resolved_file
ช่วยคุณได้ โดยพื้นฐานแล้ว Flag นี้จะสร้าง "ไฟล์ล็อก" ของข้อกำหนดภายนอกทั้งหมดที่ดึงข้อมูลในคำสั่ง Bazel รายการล่าสุด ดูรายละเอียดเพิ่มเติมได้ในบล็อกโพสต์นี้
โดยใช้งานได้ 2 วิธีดังนี้
เพื่อดึงข้อมูลของ Dependency ภายนอกที่จําเป็นสําหรับการสร้างเป้าหมายบางอย่าง
bazel clean --expunge bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
เพื่อดึงข้อมูลของทรัพยากร Dependency ภายนอกทั้งหมดที่กำหนดไว้ในไฟล์ WORKSPACE
bazel clean --expunge bazel sync --experimental_repository_resolved_file=resolved.bzl
เมื่อใช้คำสั่ง
bazel sync
คุณจะดึงข้อมูล Dependency ทั้งหมดที่กําหนดไว้ในไฟล์ WORKSPACE ได้ ซึ่งรวมถึงรายการต่อไปนี้- การใช้งาน
bind
- การใช้งาน
register_toolchains
และregister_execution_platforms
อย่างไรก็ตาม หากโปรเจ็กต์เป็นแบบข้ามแพลตฟอร์ม การซิงค์ Bazel อาจใช้งานไม่ได้ในบางแพลตฟอร์ม เนื่องจากกฎของที่เก็บข้อมูลบางรายการอาจทำงานได้อย่างถูกต้องในแพลตฟอร์มที่รองรับเท่านั้น
- การใช้งาน
หลังจากเรียกใช้คําสั่งแล้ว คุณควรมีข้อมูลของข้อกําหนดภายนอกในไฟล์ resolved.bzl
ตรวจสอบทรัพยากร Dependency ภายนอกด้วย bazel query
นอกจากนี้ คุณยังทราบว่า bazel query
สามารถใช้ในการตรวจสอบกฎของที่เก็บได้ด้วย
bazel query --output=build //external:<repo name>
แม้ว่าจะสะดวกและรวดเร็วกว่ามาก แต่การค้นหา Bazel อาจแสดงข้อมูลที่ไม่ถูกต้องเกี่ยวกับเวอร์ชันของข้อกำหนดภายนอก ดังนั้นโปรดใช้ด้วยความระมัดระวัง การค้นหาและตรวจสอบการพึ่งพาภายนอกด้วย Bzlmod จะดำเนินการได้ด้วยคำสั่งย่อยใหม่
ทรัพยากร Dependency เริ่มต้นในตัว
หากตรวจสอบไฟล์ที่ --experimental_repository_resolved_file
สร้างขึ้น คุณจะเห็นรายการที่ขึ้นต่อกันจำนวนมากที่ไม่ได้กำหนดไว้ใน WORKSPACE
นั่นเป็นเพราะ Bazel เพิ่มคำนำหน้าและคำต่อท้ายให้กับเนื้อหาไฟล์ WORKSPACE ของผู้ใช้เพื่อแทรกทรัพยากร Dependency เริ่มต้นบางส่วน ซึ่งมักกำหนดโดยกฎของระบบ (เช่น @bazel_tools
, @platforms
และ @remote_java_tools
) เมื่อใช้ Bzlmod ทรัพยากร Dependency เหล่านี้จะเริ่มใช้ด้วยโมดูลในตัว bazel_tools
ซึ่งเป็นทรัพยากร Dependency เริ่มต้นสําหรับโมดูล Bazel ทั้งหมด
โหมดผสมสำหรับการย้ายข้อมูลทีละน้อย
Bzlmod และ WORKSPACE สามารถทํางานร่วมกันได้ ซึ่งช่วยให้การย้ายข้อมูลทรัพยากรจากไฟล์ WORKSPACE ไปยัง Bzlmod เป็นกระบวนการที่ค่อยเป็นค่อยไป
WORKSPACE.bzlmod
ในระหว่างการย้ายข้อมูล ผู้ใช้ Bazel อาจต้องสลับระหว่างบิลด์ที่เปิดใช้และไม่เปิดใช้ Bzlmod มีการใช้การรองรับ WORKSPACE.bzlmod เพื่อให้กระบวนการราบรื่นขึ้น
WORKSPACE.bzlmod มีไวยากรณ์เดียวกันกับ WORKSPACE เมื่อเปิดใช้ Bzlmod หากมีไฟล์ WORKSPACE.bzlmod ที่รูทของพื้นที่ทำงานด้วย ระบบจะดำเนินการดังนี้
WORKSPACE.bzlmod
จะมีผลและระบบจะไม่สนใจเนื้อหาของWORKSPACE
- ไม่มีการเพิ่มคำนำหน้าหรือคำต่อท้ายลงในไฟล์ WORKSPACE.bzlmod
การใช้ไฟล์ WORKSPACE.bzlmod จะช่วยให้การย้ายข้อมูลง่ายขึ้นเนื่องจากเหตุผลต่อไปนี้
- เมื่อปิดใช้ Bzlmod ระบบจะกลับไปใช้การดึงข้อมูล Dependency จากไฟล์ WORKSPACE เดิม
- เมื่อเปิดใช้ Bzlmod คุณจะติดตามรายการ Dependency ที่เหลือที่ต้องย้ายข้อมูลด้วย WORKSPACE.bzlmod ได้ดียิ่งขึ้น
ระดับการเข้าถึงที่เก็บ
Bzlmod ควบคุมได้ว่าจะให้ที่เก็บอื่นใดแสดงจากที่เก็บหนึ่งๆ ดูรายละเอียดเพิ่มเติมได้ที่ชื่อและรายละเอียดของที่เก็บ
ต่อไปนี้เป็นข้อมูลสรุประดับการเข้าถึงที่เก็บจากที่เก็บประเภทต่างๆ เมื่อพิจารณาพื้นที่ทำงานด้วย
จากที่เก็บหลัก | จากที่เก็บโมดูล Bazel | จากที่เก็บส่วนขยายโมดูล | จากที่เก็บของ WORKSPACE | |
---|---|---|---|---|
ที่เก็บหลัก | แสดง | หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรง | หากโมดูลรูทเป็นโมดูลที่ต้องพึ่งพาโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล | แสดง |
ที่เก็บโมดูล Bazel | Dependency โดยตรง | การเพิ่มขึ้นของเส้นตรง | โมดูลที่โฮสต์ส่วนขยายของโมดูลนั้นๆ | โมดูลที่โมดูลรูทใช้โดยตรง |
ที่เก็บส่วนขยายโมดูล | การเพิ่มขึ้นของเส้นตรง | Dependency โดยตรง | Dependency โดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล + รีพอสิทั้งหมดที่สร้างขึ้นโดยส่วนขยายโมดูลเดียวกัน | โมดูลที่โมดูลรูทใช้โดยตรง |
Repo ของ Workspace | มองเห็นทั้งหมด | ไม่แสดง | ไม่แสดง | มองเห็นทั้งหมด |
กระบวนการย้ายข้อมูล
กระบวนการย้ายข้อมูล Bzlmod ทั่วไปอาจมีลักษณะดังนี้
- ทำความเข้าใจทรัพยากร Dependency ที่คุณมีใน WORKSPACE
- เพิ่มไฟล์ MODULE.bazel ที่ว่างเปล่าที่รูทของโปรเจ็กต์
- เพิ่มไฟล์ WORKSPACE.bzlmod ที่ว่างเปล่าเพื่อลบล้างเนื้อหาไฟล์ WORKSPACE
- สร้างเป้าหมายโดยเปิดใช้ Bzlmod แล้วตรวจสอบว่าไม่มีที่เก็บใด
- ตรวจสอบคำจำกัดความของที่เก็บที่หายไปในไฟล์ทรัพยากร Dependency ที่ได้รับการแก้ไขแล้ว
- แนะนำทรัพยากร Dependency ที่ขาดหายไปในฐานะโมดูล Bazel ผ่านส่วนขยายโมดูล หรือปล่อยไว้ใน WORKSPACE.bzlmod เพื่อย้ายข้อมูลในภายหลัง
- กลับไปที่ 4 และทำซ้ำจนกว่าทรัพยากร Dependency ทั้งหมดจะพร้อมใช้งาน
เครื่องมือย้ายข้อมูล
มีสคริปต์ตัวช่วยสำหรับการย้ายข้อมูล Bzlmod แบบอินเทอร์แอกทีฟที่จะช่วยคุณเริ่มต้นใช้งาน
สคริปต์จะทําสิ่งต่อไปนี้
- สร้างและแยกวิเคราะห์ไฟล์ที่แก้ไขแล้วของ WORKSPACE
- พิมพ์ข้อมูลพื้นที่เก็บข้อมูลจากไฟล์ที่แก้ไขแล้วในรูปแบบที่มนุษย์อ่านได้
- เรียกใช้คําสั่ง bazel build, ตรวจหาข้อความแสดงข้อผิดพลาดที่รู้จัก และแนะนําวิธีย้ายข้อมูล
- ตรวจสอบว่ารายการที่เกี่ยวข้องมีอยู่ใน BCR อยู่แล้วหรือไม่
- เพิ่มทรัพยากร Dependency ไปยังไฟล์ MODULE.bazel
- เพิ่มข้อกําหนดผ่านส่วนขยายโมดูล
- เพิ่มข้อกำหนดในไฟล์ WORKSPACE.bzlmod
หากต้องการใช้ ให้ตรวจสอบว่าคุณได้ติดตั้ง Bazel เวอร์ชันล่าสุดแล้ว และเรียกใช้คำสั่งต่อไปนี้
git clone https://github.com/bazelbuild/bazel-central-registry.git
cd <your workspace root>
<BCR repo root>/tools/migrate_to_bzlmod.py -t <your build targets>
เผยแพร่โมดูล Bazel
หากโปรเจ็กต์ Bazel ของคุณเป็นข้อกำหนดของโปรเจ็กต์อื่นๆ คุณสามารถเผยแพร่โปรเจ็กต์ใน Bazel Central Registry
หากต้องการตรวจสอบโปรเจ็กต์ใน BCR คุณจะต้องมี URL ของที่เก็บถาวรต้นทางของโปรเจ็กต์ โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อสร้างที่เก็บถาวรของแหล่งที่มา
ตรวจสอบว่าไฟล์เก็บถาวรชี้ไปยังเวอร์ชันที่เจาะจง
BCR ยอมรับเฉพาะที่เก็บซอร์สโค้ดที่มีเวอร์ชัน เนื่องจาก Bzlmod จำเป็นต้องทำการเปรียบเทียบเวอร์ชันระหว่างการแก้ไขข้อขัดข้องเกี่ยวกับทรัพยากร Dependency
ตรวจสอบว่า URL ของที่เก็บถาวรเป็นแบบคงที่
Bazel จะยืนยันเนื้อหาของไฟล์เก็บถาวรด้วยค่าแฮช คุณจึงควรตรวจสอบว่าการตรวจสอบผลรวมของไฟล์ที่ดาวน์โหลดจะไม่เปลี่ยนแปลง หาก URL มาจาก GitHub โปรดสร้างและอัปโหลดไฟล์เก็บถาวรของรุ่นในหน้ารุ่น GitHub จะไม่รับประกันการตรวจสอบผลรวมของที่เก็บต้นทางที่สร้างขึ้นตามคำขอ กล่าวโดยย่อคือ URL ในรูปแบบ
https://github.com/<org>/<repo>/releases/download/...
จะถือว่ามีเสถียรภาพ ส่วนhttps://github.com/<org>/<repo>/archive/...
จะไม่เสถียร ดู GitHub ที่เก็บถาวรของ Checksum การหยุดทำงาน เพื่อดูบริบทเพิ่มเติมตรวจสอบว่าโครงสร้างต้นทางเป็นไปตามเลย์เอาต์ของที่เก็บข้อมูลเดิม
ในกรณีที่ที่เก็บข้อมูลมีขนาดใหญ่มากและคุณต้องการสร้างไฟล์เก็บถาวรสำหรับแจกจ่ายที่มีขนาดเล็กลงโดยการนําแหล่งที่มาที่ไม่จําเป็นออก โปรดตรวจสอบว่าต้นไม้แหล่งที่มาที่นําออกนั้นเป็นส่วนหนึ่งของต้นไม้แหล่งที่มาเดิม ซึ่งจะช่วยให้ผู้ใช้ปลายทางลบล้างข้อบังคับของข้อบังคับของโมดูลเป็นเวอร์ชันที่ไม่ใช่รุ่นได้ง่ายขึ้นด้วย
archive_override
และgit_override
รวมโมดูลทดสอบในไดเรกทอรีย่อยที่ทดสอบ API ที่คุณใช้บ่อยที่สุด
โมดูลทดสอบคือโปรเจ็กต์ Bazel ที่มีไฟล์ WORKSPACE และ MODULE.bazel ของตัวเองซึ่งอยู่ในไดเรกทอรีย่อยของที่เก็บถาวรต้นทางซึ่งจะขึ้นอยู่กับโมดูลจริงที่จะเผยแพร่ โดยควรมีตัวอย่างหรือการทดสอบการผสานรวมบางส่วนที่ครอบคลุม API ที่พบบ่อยที่สุด ไปที่โมดูลการทดสอบเพื่อดูวิธีตั้งค่า
เมื่อ URL ของไฟล์เก็บถาวรของแหล่งที่มาพร้อมแล้ว ให้ทำตามหลักเกณฑ์การมีส่วนร่วมใน BCR เพื่อส่งข้อบังคับของคุณไปยัง BCR ด้วยคำขอดึงข้อมูล GitHub
เราขอแนะนำอย่างยิ่งให้ตั้งค่าแอป GitHub Publish to BCR สำหรับที่เก็บของคุณเพื่อทำให้กระบวนการส่งโมดูลไปยัง BCR เป็นแบบอัตโนมัติ
แนวทางปฏิบัติแนะนำ
ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำบางประการที่คุณควรทำตามเพื่อจัดการทรัพยากรภายนอกให้ดียิ่งขึ้น
แยกเป้าหมายออกเป็นแพ็กเกจต่างๆ เพื่อหลีกเลี่ยงการดึงข้อมูลทรัพยากร Dependency ที่ไม่จำเป็น
โปรดดู #12835 ซึ่งมีการบังคับให้ดึงข้อมูลพึ่งพาสำหรับทดสอบโดยไม่จำเป็นสำหรับการสร้างเป้าหมายที่ไม่ต้องใช้ จริงๆ แล้ววิธีนี้ไม่ได้เจาะจงสำหรับ Bzlmod แต่การปฏิบัติตามแนวทางนี้จะช่วยให้ระบุทรัพยากร Dependency ของนักพัฒนาซอฟต์แวร์ได้อย่างถูกต้องได้ง่ายขึ้น
ระบุทรัพยากร Dependency สําหรับนักพัฒนาซอฟต์แวร์
คุณสามารถตั้งค่าแอตทริบิวต์ dev_dependency
เป็น "จริง" สําหรับคำสั่ง bazel_dep
และ use_extension
เพื่อไม่ให้คำสั่งดังกล่าวเผยแพร่ไปยังโปรเจ็กต์ที่เกี่ยวข้อง ในฐานะโมดูลรูท คุณสามารถใช้แฟล็ก --ignore_dev_dependency
เพื่อยืนยันว่าเป้าหมายยังคงสร้างโดยไม่มีทรัพยากร Dependency และการลบล้างสําหรับนักพัฒนาซอฟต์แวร์หรือไม่
ความคืบหน้าของการย้ายข้อมูลชุมชน
คุณสามารถตรวจสอบรีจิสทรีส่วนกลางของ Bazel เพื่อดูว่าพึ่งพาของคุณพร้อมใช้งานแล้วหรือยัง หรือจะเข้าร่วมการสนทนาใน GitHub เพื่อกดโหวตหรือโพสต์เกี่ยวกับข้อกำหนดที่บล็อกการย้ายข้อมูลของคุณก็ได้
รายงานปัญหา
โปรดดูรายการปัญหาใน GitHub ของ Bazel เพื่อดูปัญหาที่ทราบเกี่ยวกับ Bzlmod คุณสามารถยื่นปัญหาหรือคำขอฟีเจอร์ใหม่เพื่อช่วยเลิกบล็อกการย้ายข้อมูลได้