เนื่องจากข้อบกพร่องของ WORKSPACE Bzlmod จึงจะมา แทนที่ระบบ WORKSPACE แบบเดิม เราจะปิดใช้ไฟล์ WORKSPACE โดยค่าเริ่มต้นใน Bazel 8 (ปลายปี 2024) และจะนำออกใน Bazel 9 (ปลายปี 2025) คำแนะนำนี้จะช่วยคุณย้ายข้อมูลโปรเจ็กต์ไปยัง Bzlmod และเลิกใช้ WORKSPACE สำหรับ การดึงข้อมูลการอ้างอิงภายนอก
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 ช่วยให้คุณตั้งค่าสถานะที่จะมีผลทุกครั้งที่เรียกใช้ 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 คุณควรใช้เป็นโมดูล Bazel ได้เมื่อใช้ Bzlmod ด้วย
WORKSPACE
เมื่อใช้ 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เวอร์ชันที่แน่นอนของplatformDependency จะกำหนดโดยลำดับของมาโครBzlmod
เมื่อใช้ Bzlmod ตราบใดที่ทรัพยากร Dependency ของคุณพร้อมใช้งานในรีจิสทรี Bazel Central หรือรีจิสทรี Bazel ที่กำหนดเอง คุณก็สามารถใช้เป็น Dependency ได้อย่างง่ายดายด้วยคำสั่ง
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 ภายนอกด้วยส่วนขยายโมดูล
หากการขึ้นต่อกันไม่ใช่โปรเจ็กต์ 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 เพื่อสร้างอินสแตนซ์ของที่เก็บได้โดยตรง## 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", )ฟีเจอร์นี้ทำงานโดยใช้ส่วนขยายโมดูล หากต้องการใช้ตรรกะที่ซับซ้อนกว่าการเรียกใช้กฎของที่เก็บ คุณก็สามารถ ติดตั้งใช้งานส่วนขยายโมดูลด้วยตนเองได้เช่นกัน คุณจะต้องย้ายคำจำกัดความ ไปไว้ในไฟล์
.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")
แก้ไขข้อขัดแย้งของทรัพยากร Dependency ภายนอกด้วยส่วนขยายโมดูล
โปรเจ็กต์สามารถระบุมาโครที่แนะนำที่เก็บข้อมูลภายนอกตาม อินพุตจากผู้เรียกใช้ แต่จะเกิดอะไรขึ้นหากมีผู้โทรหลายรายในกราฟการอ้างอิงและทำให้เกิดความขัดแย้ง
สมมติว่าโปรเจ็กต์ 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ด้วย แต่ต้องใช้การอ้างอิงข้อมูลเวอร์ชันอื่น## 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สำหรับการอ้างอิงข้อมูลโดยอัตโนมัติ
ผสานรวมเครื่องมือจัดการแพ็กเกจของบุคคลที่สาม
จากส่วนสุดท้าย เนื่องจากส่วนขยายโมดูลมีวิธีรวบรวมข้อมูลจากกราฟการขึ้นต่อกัน ดำเนินการตรรกะที่กำหนดเองเพื่อแก้ไขการขึ้นต่อกัน และเรียกใช้กฎของที่เก็บเพื่อนำที่เก็บภายนอกมาใช้ จึงเป็นวิธีที่ยอดเยี่ยมสำหรับผู้เขียนกฎในการปรับปรุงชุดกฎที่ผสานรวมเครื่องมือจัดการแพ็กเกจสำหรับภาษาที่เฉพาะเจาะจง
โปรดอ่านหน้าส่วนขยายโมดูลเพื่อดูข้อมูลเพิ่มเติม เกี่ยวกับวิธีใช้ส่วนขยายโมดูล
ต่อไปนี้คือรายการชุดกฎที่ใช้ Bzlmod เพื่อดึงข้อมูลการอ้างอิงจากตัวจัดการแพ็กเกจต่างๆ
ตัวอย่างแบบเรียบง่ายที่ผสานรวมเครื่องมือจัดการแพ็กเกจจำลองมีอยู่ในที่เก็บตัวอย่าง
ตรวจหา Toolchain ในเครื่องโฮสต์
เมื่อกฎการสร้าง Bazel จำเป็นต้องตรวจหาว่ามี Toolchain ใดบ้างในเครื่องโฮสต์ กฎของที่เก็บจะใช้เพื่อตรวจสอบเครื่องโฮสต์และสร้าง ข้อมูล Toolchain เป็นที่เก็บภายนอก
WORKSPACE
เมื่อพิจารณากฎของที่เก็บต่อไปนี้เพื่อตรวจหาเชนเครื่องมือของเชลล์
## 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")
ลงทะเบียนเครื่องมือและแพลตฟอร์มการดำเนินการ
หลังจากส่วนสุดท้าย เมื่อแนะนำข้อมูลเชนเครื่องมือการโฮสต์ที่เก็บ (เช่น local_config_sh) คุณอาจต้องการลงทะเบียนเชนเครื่องมือ
WORKSPACE
เมื่อใช้ WORKSPACE คุณจะลงทะเบียน Toolchain ได้ด้วยวิธีต่อไปนี้
คุณลงทะเบียน Toolchain ไฟล์
.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()หรือลงทะเบียน Toolchain ในไฟล์ 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 จะเป็นไปตามลำดับความสำคัญต่อไปนี้
ระหว่างการเลือกชุดเครื่องมือ (จากสูงสุดไปต่ำสุด)
- เครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์
MODULE.bazelของโมดูลรูท - เครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์
WORKSPACEหรือWORKSPACE.bzlmod - ชุดเครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนโดยโมดูลซึ่งเป็นทรัพยากร Dependency (แบบทรานซิทีฟ) ของโมดูลรูท
- เมื่อไม่ได้ใช้
WORKSPACE.bzlmod: ชุดเครื่องมือที่ลงทะเบียนในWORKSPACEsuffix
แนะนำที่เก็บในพื้นที่
คุณอาจต้องระบุการอ้างอิงเป็นที่เก็บในเครื่องเมื่อต้องการใช้การอ้างอิงเวอร์ชันในเครื่องเพื่อการแก้ไขข้อบกพร่อง หรือต้องการรวมไดเรกทอรีในพื้นที่ทำงานเป็นที่เก็บภายนอก
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) จากนั้นคุณจะเรียกใช้local_repositoryของ Starlark ที่เกี่ยวข้องในโมดูล ส่วนขยายได้ นอกจากนี้ คุณยังสามารถใช้กฎที่กำหนดเองของlocal_repositoryrepository rule ได้อย่างง่ายดายหากปัญหานี้ทำให้คุณถูกบล็อก
เป้าหมายการเชื่อมโยง
กฎ 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
การดึงข้อมูลกับการซิงค์
คำสั่งดึงข้อมูลและซิงค์ใช้เพื่อดาวน์โหลดที่เก็บภายนอกในเครื่องและอัปเดตที่เก็บเหล่านั้นอยู่เสมอ
บางครั้งก็เพื่ออนุญาตให้สร้างแบบออฟไลน์โดยใช้แฟล็ก --nofetch
หลังจากดึงข้อมูลที่จำเป็นทั้งหมดสำหรับการสร้าง
WORKSPACE
Sync จะบังคับดึงข้อมูลสำหรับที่เก็บทั้งหมด หรือสำหรับชุดที่เก็บที่กำหนดค่าไว้โดยเฉพาะ ในขณะที่ Fetch จะใช้เฉพาะเพื่อดึงข้อมูลสำหรับเป้าหมายที่เฉพาะเจาะจง
Bzlmod
คำสั่งซิงค์ใช้ไม่ได้อีกต่อไป แต่คำสั่งดึงข้อมูลมีตัวเลือกต่างๆ คุณสามารถดึงข้อมูลเป้าหมาย ที่เก็บ ชุดที่เก็บที่กำหนดค่าไว้ หรือที่เก็บทั้งหมด ที่เกี่ยวข้องกับการแก้ปัญหาการขึ้นต่อกันและส่วนขยายโมดูล ระบบจะแคชผลการดึงข้อมูล และหากต้องการบังคับให้ดึงข้อมูล คุณต้องใส่ตัวเลือก
--forceในระหว่างกระบวนการดึงข้อมูล
การย้ายข้อมูล
ส่วนนี้จะให้ข้อมูลและคำแนะนำที่เป็นประโยชน์สำหรับการย้ายข้อมูล Bzlmod
รู้จักการอ้างอิงใน WORKSPACE
ขั้นตอนแรกของการย้ายข้อมูลคือการทำความเข้าใจการขึ้นต่อกันที่คุณมี การระบุว่ามีการเพิ่มการอ้างอิงใดในไฟล์ WORKSPACE อาจเป็นเรื่องยาก เนื่องจากมักจะโหลดการอ้างอิงแบบทรานซิทีฟด้วย*_deps
แมโคร
ตรวจสอบการขึ้นต่อกันภายนอกด้วยไฟล์ที่แก้ไขแล้วของพื้นที่ทำงาน
โชคดีที่ฟีเจอร์รายงาน
--experimental_repository_resolved_file
ช่วยได้ โดยพื้นฐานแล้ว แฟล็กนี้จะสร้าง "ไฟล์ล็อก" ของการอ้างอิงภายนอกทั้งหมดที่ดึงข้อมูลมา
ในคำสั่ง 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ช่วยให้คุณดึงข้อมูลการอ้างอิงทั้งหมดที่กำหนดไว้ในไฟล์ WORKSPACE ซึ่งรวมถึงรายการต่อไปนี้- การใช้งาน
bind - การใช้งาน
register_toolchainsและregister_execution_platforms
อย่างไรก็ตาม หากโปรเจ็กต์ของคุณเป็นแบบข้ามแพลตฟอร์ม การซิงค์ Bazel อาจหยุดทำงานในบางแพลตฟอร์ม เนื่องจากกฎของที่เก็บบางอย่างอาจทำงานได้อย่างถูกต้องในแพลตฟอร์มที่รองรับเท่านั้น
- การใช้งาน
หลังจากเรียกใช้คำสั่งแล้ว คุณควรมีข้อมูลของทรัพยากร Dependency ภายนอกในไฟล์ resolved.bzl
ตรวจสอบทรัพยากร Dependency ภายนอกด้วย bazel query
คุณอาจทราบว่า bazel query สามารถใช้ตรวจสอบกฎของที่เก็บได้ด้วย
bazel query --output=build //external:<repo name>
แม้ว่า bazel query จะสะดวกและเร็วกว่ามาก แต่ก็อาจให้ข้อมูลที่ไม่ถูกต้องเกี่ยวกับเวอร์ชันของทรัพยากรภายนอก ดังนั้นโปรดระมัดระวังในการใช้งาน การค้นหาและตรวจสอบทรัพยากร Dependency ภายนอกด้วย 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 คุณจะติดตามได้ดียิ่งขึ้นว่ายังเหลือการขึ้นต่อใดที่ต้อง ย้ายข้อมูลด้วย WORKSPACE.bzlmod
ระดับการเข้าถึงที่เก็บ
Bzlmod สามารถควบคุมได้ว่าจะให้ที่เก็บอื่นๆ ใดที่มองเห็นได้จากที่เก็บหนึ่งๆ ดูรายละเอียดเพิ่มเติมได้ที่ชื่อที่เก็บและ strict deps
ต่อไปนี้คือสรุปการเข้าถึงที่เก็บจากที่เก็บประเภทต่างๆ เมื่อพิจารณาถึง WORKSPACE ด้วย
| จากที่เก็บหลัก | จากที่เก็บโมดูล Bazel | จากที่เก็บส่วนขยายของโมดูล | จากที่เก็บ WORKSPACE | |
|---|---|---|---|---|
| ที่เก็บหลัก | แสดง | หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรง | หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล | แสดง |
| ที่เก็บโมดูล Bazel | การขึ้นต่อโดยตรง | การขึ้นต่อโดยตรง | การขึ้นต่อกันโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล | การขึ้นต่อกันโดยตรงของโมดูลรูท |
| ที่เก็บส่วนขยายโมดูล | การขึ้นต่อโดยตรง | การขึ้นต่อโดยตรง | การขึ้นต่อกันโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล + ที่เก็บทั้งหมดที่สร้างโดยส่วนขยายโมดูลเดียวกัน | การขึ้นต่อกันโดยตรงของโมดูลรูท |
| ที่เก็บ Workspace | ทั้งหมดที่มองเห็นได้ | ไม่แสดง | ไม่แสดง | ทั้งหมดที่มองเห็นได้ |
กระบวนการย้ายข้อมูล
กระบวนการย้ายข้อมูล Bzlmod ทั่วไปอาจมีลักษณะดังนี้
- ทำความเข้าใจการขึ้นต่อกันที่คุณมีใน WORKSPACE
- เพิ่มไฟล์ MODULE.bazel ที่ว่างเปล่าในรูทของโปรเจ็กต์
- เพิ่มไฟล์ WORKSPACE.bzlmod ที่ว่างเปล่าเพื่อลบล้างเนื้อหาไฟล์ WORKSPACE
- สร้างเป้าหมายโดยเปิดใช้ Bzlmod และตรวจสอบว่าที่เก็บใดขาดหายไป
- ตรวจสอบคำจำกัดความของที่เก็บที่ขาดหายไปในไฟล์การอ้างอิงที่แก้ไขแล้ว
- แนะนำการขึ้นต่อกันที่ขาดหายไปเป็นโมดูล Bazel ผ่านส่วนขยายโมดูล หรือปล่อยไว้ใน WORKSPACE.bzlmod เพื่อการย้ายข้อมูลในภายหลัง
- กลับไปที่ขั้นตอนที่ 4 แล้วทำซ้ำจนกว่าจะพร้อมใช้งาน
เครื่องมือย้ายข้อมูล
มีสคริปต์ตัวช่วยการย้ายข้อมูล Bzlmod แบบอินเทอร์แอกทีฟที่จะช่วยให้คุณเริ่มต้นใช้งานได้
สคริปต์จะทำสิ่งต่อไปนี้
- สร้างและแยกวิเคราะห์ไฟล์ WORKSPACE ที่แก้ไขแล้ว
- พิมพ์ข้อมูลที่เก็บจากไฟล์ที่แก้ไขแล้วในรูปแบบที่มนุษย์อ่านได้
- เรียกใช้คำสั่ง Bazel Build ตรวจหาข้อความแสดงข้อผิดพลาดที่รู้จัก และแนะนำวิธี ย้ายข้อมูล
- ตรวจสอบว่ามีทรัพยากร Dependency ใน BCR อยู่แล้วหรือไม่
- เพิ่มทรัพยากร Dependency ลงในไฟล์ MODULE.bazel
- เพิ่มทรัพยากร Dependency ผ่านส่วนขยายโมดูล
- เพิ่มทรัพยากร Dependency ลงในไฟล์ 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 ได้
หากต้องการเช็คอินโปรเจ็กต์ใน BCR คุณต้องมี URL ของที่เก็บต้นฉบับของโปรเจ็กต์ โปรดทราบสิ่งต่อไปนี้เมื่อสร้างที่เก็บถาวรของแหล่งที่มา
ตรวจสอบว่าไฟล์เก็บถาวรชี้ไปยังเวอร์ชันที่เฉพาะเจาะจง
BCR รับได้เฉพาะไฟล์เก็บถาวรของแหล่งที่มาที่มีการกำหนดเวอร์ชันเท่านั้น เนื่องจาก Bzlmod ต้อง เปรียบเทียบเวอร์ชันระหว่างการแก้ไขการอ้างอิง
ตรวจสอบว่า URL ของที่เก็บถาวรมีความเสถียร
Bazel จะยืนยันเนื้อหาของที่เก็บโดยใช้ค่าแฮช ดังนั้นคุณควร ตรวจสอบว่าผลรวมตรวจสอบของไฟล์ที่ดาวน์โหลดไม่เปลี่ยนแปลง หาก URL มาจาก GitHub โปรดสร้างและอัปโหลดที่เก็บถาวรของรุ่นในหน้ารุ่น GitHub ไม่รับประกันผลรวมตรวจสอบของที่เก็บต้นฉบับที่สร้างขึ้นตามคำขอ กล่าวโดยย่อคือ URL ในรูปแบบ
https://github.com/<org>/<repo>/releases/download/...ถือว่าเสถียร ขณะที่https://github.com/<org>/<repo>/archive/...ไม่เสถียร ดูบริบทเพิ่มเติมได้ที่GitHub การหยุดทำงานของ ผลรวมตรวจสอบของที่เก็บตรวจสอบว่าโครงสร้างแหล่งที่มาเป็นไปตามเลย์เอาต์ของที่เก็บต้นฉบับ
ในกรณีที่ที่เก็บมีขนาดใหญ่มากและคุณต้องการสร้างที่เก็บถาวรสำหรับการเผยแพร่ ที่มีขนาดเล็กลงโดยการลบแหล่งที่มาที่ไม่จำเป็นออก โปรดตรวจสอบ ว่าโครงสร้างแหล่งที่มาที่ลบออกเป็นส่วนย่อยของโครงสร้างแหล่งที่มาเดิม ซึ่งช่วยให้ผู้ใช้ปลายทางแทนที่โมดูลเป็นเวอร์ชันที่ไม่ใช่เวอร์ชันที่เผยแพร่ได้ง่ายขึ้นโดยใช้
archive_overrideและgit_overrideรวมโมดูลทดสอบในไดเรกทอรีย่อยที่ทดสอบ API ที่ใช้กันมากที่สุด
โมดูลทดสอบคือโปรเจ็กต์ Bazel ที่มีไฟล์ WORKSPACE และ MODULE.bazel ของตัวเองซึ่งอยู่ในไดเรกทอรีย่อยของที่เก็บถาวรของแหล่งที่มาซึ่งขึ้นอยู่กับโมดูลจริงที่จะเผยแพร่ โดยควรมีตัวอย่างหรือการทดสอบการผสานรวมบางอย่างที่ครอบคลุม API ที่พบบ่อยที่สุด ดูวิธีตั้งค่าได้ในโมดูลทดสอบ
เมื่อมี URL ของที่เก็บต้นฉบับพร้อมแล้ว ให้ทำตามหลักเกณฑ์การมีส่วนร่วมใน BCR เพื่อส่งโมดูลไปยัง BCR ด้วยคำขอ Pull ใน GitHub
เราขอแนะนำเป็นอย่างยิ่งให้ตั้งค่าแอป GitHub Publish to BCR สำหรับที่เก็บของคุณเพื่อทำให้กระบวนการส่งโมดูลไปยัง BCR เป็นไปโดยอัตโนมัติ
แนวทางปฏิบัติแนะนำ
ส่วนนี้จะบันทึกแนวทางปฏิบัติแนะนำบางส่วนที่คุณควรทำตามเพื่อจัดการการอ้างอิงภายนอกได้ดียิ่งขึ้น
แยกเป้าหมายออกเป็นแพ็กเกจต่างๆ เพื่อหลีกเลี่ยงการดึงข้อมูลการอ้างอิงที่ไม่จำเป็น
ดู #12835 ซึ่งมีการบังคับให้ดึงข้อมูล dev dependencies สำหรับการทดสอบโดยไม่จำเป็นสำหรับการสร้าง เป้าหมายที่ไม่ต้องการ จริงๆ แล้วการดำเนินการนี้ไม่ได้เจาะจง Bzlmod แต่ การปฏิบัติตามแนวทางนี้จะช่วยให้ระบุทรัพยากร Dependency สำหรับการพัฒนาได้อย่างถูกต้องง่ายขึ้น
ระบุทรัพยากร Dependency สำหรับการพัฒนา
คุณตั้งค่าแอตทริบิวต์ dev_dependency เป็น "จริง" สำหรับ
bazel_dep และ
use_extension เพื่อไม่ให้
แอตทริบิวต์ดังกล่าวแพร่ไปยังโปรเจ็กต์ที่ขึ้นต่อกัน ในฐานะโมดูลรูท คุณสามารถใช้แฟล็ก --ignore_dev_dependency เพื่อตรวจสอบว่าเป้าหมายยังสร้างได้โดยไม่มีทรัพยากร Dependency สำหรับการพัฒนาและการลบล้างหรือไม่
ความคืบหน้าในการย้ายข้อมูลชุมชน
คุณสามารถตรวจสอบรีจิสทรีกลางของ Bazel เพื่อดูว่ามีทรัพยากร Dependency ที่คุณต้องการอยู่แล้วหรือไม่ หรือคุณจะเข้าร่วมการสนทนาใน GitHub นี้เพื่อโหวตหรือโพสต์การอ้างอิงที่บล็อกการย้ายข้อมูลก็ได้
รายงานปัญหา
โปรดดูรายการปัญหา GitHub ของ Bazel เพื่อดูปัญหาที่ทราบเกี่ยวกับ Bzlmod โปรดรายงานปัญหาใหม่หรือคำขอฟีเจอร์ที่จะช่วยให้การย้ายข้อมูลของคุณไม่ติดขัด