คู่มือการย้ายข้อมูล Bzlmod

รายงานปัญหา ดูแหล่งที่มา Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Bzlmod จะมาแทนที่ระบบ WORKSPACE เดิมเนื่องจากข้อบกพร่องของ WORKSPACE เราได้ปิดใช้ไฟล์ WORKSPACE ใน Bazel 8 (ปลายปี 2024) แล้ว และจะนำออกใน Bazel 9 (ปลายปี 2025) คำแนะนำนี้จะช่วยคุณย้ายข้อมูลโปรเจ็กต์ไปยัง Bzlmod และเลิกใช้ WORKSPACE เพื่อจัดการการอ้างอิงภายนอก

เหตุใดจึงควรย้ายข้อมูลไปยัง Bzlmod

  • ซึ่งมีข้อดีมากมายเมื่อเทียบกับระบบ WORKSPACE รุ่นเดิม ซึ่งจะช่วยให้มั่นใจได้ว่าระบบนิเวศของ Bazel จะเติบโตอย่างแข็งแรง

  • หากโปรเจ็กต์ของคุณเป็นทรัพยากร Dependency ของโปรเจ็กต์อื่นๆ การย้ายข้อมูลไปยัง Bzlmod จะช่วยให้โปรเจ็กต์เหล่านั้นย้ายข้อมูลได้และทำให้การขึ้นอยู่กับโปรเจ็กต์ของคุณง่ายขึ้น

  • การย้ายข้อมูลไปยัง Bzlmod เป็นขั้นตอนที่จำเป็นในการใช้ Bazel เวอร์ชันในอนาคต (จำเป็นใน Bazel 9)

วิธีย้ายข้อมูลไปยัง Bzlmod

กระบวนการย้ายข้อมูลที่แนะนำ

  1. ใช้เครื่องมือย้ายข้อมูลเป็นเครื่องมือช่วยเพื่อเพิ่มประสิทธิภาพ กระบวนการย้ายข้อมูลให้มากที่สุด ดูส่วนเครื่องมือ การย้ายข้อมูลและวิธีใช้เครื่องมือ
  2. หากยังมีข้อผิดพลาดหลังจากใช้เครื่องมือย้ายข้อมูล ให้แก้ไขด้วยตนเอง หากต้องการทำความเข้าใจความแตกต่างหลักระหว่างแนวคิดภายในไฟล์ WORKSPACEและMODULE.bazel โปรดดูส่วนWORKSPACE เทียบกับ Bzlmod

เครื่องมือย้ายข้อมูล

เพื่อลดความซับซ้อนของกระบวนการย้ายข้อมูลจาก WORKSPACE ไปยัง Bzlmod ซึ่งมักจะมีความซับซ้อน เราขอแนะนำให้ใช้สคริปต์การย้ายข้อมูล เครื่องมือช่วยนี้จะทำให้ขั้นตอนต่างๆ ที่เกี่ยวข้องกับการย้ายข้อมูลระบบการจัดการทรัพยากรภายนอกเป็นแบบอัตโนมัติ

ฟังก์ชันหลัก

ฟังก์ชันหลักของสคริปต์มีดังนี้

  • การรวบรวมข้อมูลการขึ้นต่อกัน: วิเคราะห์WORKSPACE ของโปรเจ็กต์เพื่อระบุที่เก็บข้อมูลภายนอกที่ใช้โดยเป้าหมายการบิลด์ที่ระบุ โดยใช้แฟล็ก experimental_repository_resolved_file ของ Bazel เพื่อสร้างไฟล์ resolved_deps.py ที่มีข้อมูลนี้
  • การระบุการอ้างอิงโดยตรง: ใช้ bazel query เพื่อพิจารณาว่าที่เก็บใดเป็นการอ้างอิงโดยตรงสำหรับเป้าหมายที่ระบุ
  • การย้ายข้อมูล Bzlmod: แปลการอ้างอิง WORKSPACE ที่เกี่ยวข้องเป็น รายการที่เทียบเท่าใน Bzlmod โดยมี 2 ขั้นตอนดังนี้
    1. ลองเพิ่มทรัพยากร Dependency โดยตรงที่ระบุทั้งหมดลงในไฟล์ MODULE.bazel
    2. พยายามสร้างเป้าหมายที่ระบุโดยเปิดใช้ Bzlmod จากนั้น ระบุและแก้ไขข้อผิดพลาดที่รู้จักได้ซ้ำๆ ขั้นตอนนี้จำเป็นเนื่องจากอาจไม่มีการระบุการอ้างอิงบางอย่างในขั้นตอนแรก
  • การสร้างรายงานการย้ายข้อมูล: สร้างไฟล์ migration_info.md ที่ บันทึกกระบวนการย้ายข้อมูล รายงานนี้ประกอบด้วยรายการการอ้างอิงโดยตรง ประกาศ Bzlmod ที่สร้างขึ้น และขั้นตอนด้วยตนเองที่อาจต้องใช้เพื่อทำการย้ายข้อมูลให้เสร็จสมบูรณ์

เครื่องมือย้ายข้อมูลรองรับรายการต่อไปนี้

  • การขึ้นต่อกันที่พร้อมใช้งานในรีจิสทรีส่วนกลางของ Bazel
  • กฎที่กำหนดเองของที่เก็บที่ผู้ใช้กำหนด
  • [เร็วๆ นี้] ทรัพยากร Dependency ของเครื่องมือจัดการแพ็กเกจ

หมายเหตุสำคัญ: เครื่องมือการย้ายข้อมูลเป็นยูทิลิตีที่ทำงานอย่างเต็มที่ โปรดตรวจสอบคำแนะนำของเครื่องมือนี้อีกครั้งเสมอ เพื่อความถูกต้อง

วิธีใช้เครื่องมือย้ายข้อมูล

ก่อนเริ่มใช้งาน

  • อัปเกรดเป็น Bazel 7 รุ่นล่าสุด ซึ่งรองรับทั้ง WORKSPACE และ Bzlmod ได้อย่างมีประสิทธิภาพ
  • ตรวจสอบว่าคำสั่งต่อไปนี้ทำงานสำเร็จสำหรับเป้าหมายการบิลด์หลักของโปรเจ็กต์

    bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
    

เมื่อตรงตามข้อกำหนดเบื้องต้นแล้ว ให้เรียกใช้คำสั่งต่อไปนี้เพื่อใช้เครื่องมือย้ายข้อมูล

# Clone the Bazel Central Registry repository
git clone https://github.com/bazelbuild/bazel-central-registry.git
cd bazel-central-registry

# Build the migration tool
bazel build //tools:migrate_to_bzlmod

# Create a convenient alias for the tool
alias migrate2bzlmod=$(realpath ./bazel-bin/tools/migrate_to_bzlmod)

# Navigate to your project's root directory and run the tool
cd <your workspace root>
migrate2bzlmod -t <your build targets>

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 เวอร์ชันที่แน่นอนของplatform Dependency จะกำหนดโดยลำดับของมาโคร

  • 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 โดยอัตโนมัติ

ลบล้างทรัพยากร Dependency เป็นโมดูล 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 ได้ด้วยวิธีต่อไปนี้

    1. คุณลงทะเบียน 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()
      
    2. หรือลงทะเบียน 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 จะเป็นไปตามลำดับความสำคัญต่อไปนี้ ในระหว่างการเลือกเครื่องมือ (จากสูงสุดไปต่ำสุด)

  1. เครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์ MODULE.bazel ของโมดูลรูท
  2. เครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนไว้ในไฟล์ WORKSPACE หรือ WORKSPACE.bzlmod
  3. ชุดเครื่องมือและแพลตฟอร์มการดำเนินการที่ลงทะเบียนโดยโมดูลซึ่งเป็นทรัพยากร Dependency (แบบทรานซิทีฟ) ของโมดูลรูท
  4. เมื่อไม่ได้ใช้ WORKSPACE.bzlmod: Toolchain ที่ลงทะเบียนในWORKSPACE suffix

แนะนำที่เก็บในพื้นที่

คุณอาจต้องระบุการอ้างอิงเป็นที่เก็บในเครื่องเมื่อต้องการใช้การอ้างอิงเวอร์ชันในเครื่องเพื่อการแก้ไขข้อบกพร่อง หรือต้องการรวมไดเรกทอรีในพื้นที่ทำงานเป็นที่เก็บภายนอก

  • 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_repository repository rule ได้อย่างง่ายดายหากปัญหานี้ทำให้คุณถูกบล็อก

เป้าหมายการเชื่อมโยง

กฎ bind ใน WORKSPACE ถูกเลิกใช้งานแล้วและไม่รองรับใน Bzlmod โดยฟีเจอร์นี้เปิดตัวเพื่อให้เป้าหมายมีชื่อแทนในแพ็กเกจ//externalพิเศษ ผู้ใช้ทั้งหมดที่ใช้ฟีเจอร์นี้ควรย้ายข้อมูลออก

เช่น หากคุณมีผู้ติดตาม

## WORKSPACE
bind(
    name = "openssl",
    actual = "@my-ssl//src:openssl-lib",
)

ซึ่งจะช่วยให้เป้าหมายอื่นๆ ขึ้นอยู่กับ //external:openssl ได้ คุณสามารถย้ายข้อมูล ออกจากบริการนี้ได้โดยทำดังนี้

  • แทนที่การใช้งาน //external:openssl ทั้งหมดด้วย @my-ssl//src:openssl-lib

    • เคล็ดลับ: ใช้คำสั่ง bazel query --output=build --noenable_bzlmod --enable_workspace [target] เพื่อค้นหาข้อมูลที่เกี่ยวข้อง เกี่ยวกับเป้าหมาย
  • หรือใช้กฎการสร้าง 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 ด้วยตนเอง ดูข้อมูลเพิ่มเติมเกี่ยวกับกระบวนการย้ายข้อมูลอัตโนมัติได้ที่ส่วนกระบวนการย้ายข้อมูลที่แนะนํา

ทราบทรัพยากร Dependency ใน WORKSPACE

ขั้นตอนแรกของการย้ายข้อมูลคือการทำความเข้าใจการขึ้นต่อกันที่คุณมี การระบุว่ามีการเพิ่มการอ้างอิงใดในไฟล์ WORKSPACE อาจเป็นเรื่องยาก เนื่องจากมักจะโหลดการอ้างอิงแบบทรานซิทีฟด้วย*_deps แมโคร

ตรวจสอบการขึ้นต่อกันภายนอกด้วยไฟล์ที่แก้ไขแล้วของพื้นที่ทำงาน

โชคดีที่ธง --experimental_repository_resolved_file ช่วยได้ โดยพื้นฐานแล้ว แฟล็กนี้จะสร้าง "ไฟล์ล็อก" ของการอ้างอิงภายนอกทั้งหมดที่ดึงข้อมูลมา ในคำสั่ง Bazel ล่าสุด ดูรายละเอียดเพิ่มเติมได้ในบล็อก โพสต์นี้

โดยใช้ได้ 2 วิธีดังนี้

  1. เพื่อดึงข้อมูลของทรัพยากร Dependency ภายนอกที่จำเป็นสำหรับการสร้างเป้าหมายบางอย่าง

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. เพื่อดึงข้อมูลของทรัพยากร 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) จะต้องใช้ทรัพยากร Dependency เหล่านี้ เมื่อใช้ Bzlmod ทรัพยากร Dependency เหล่านั้นจะมาพร้อมกับโมดูลในตัว bazel_tools ซึ่งเป็นทรัพยากร Dependency เริ่มต้นสำหรับโมดูล Bazel อื่นๆ ทั้งหมด

โหมดผสมสำหรับการย้ายข้อมูลแบบค่อยเป็นค่อยไป

Bzlmod และ WORKSPACE สามารถทำงานควบคู่กันได้ ซึ่งช่วยให้การย้ายข้อมูลการอ้างอิง จากไฟล์ WORKSPACE ไปยัง Bzlmod เป็นกระบวนการที่ค่อยเป็นค่อยไป

WORKSPACE.bzlmod

ในระหว่างการย้ายข้อมูล ผู้ใช้ Bazel อาจต้องสลับระหว่างบิลด์ที่เปิดใช้และไม่ได้เปิดใช้ Bzlmod เราได้ติดตั้งใช้งานการรองรับ WORKSPACE.bzlmod เพื่อให้กระบวนการนี้ราบรื่นยิ่งขึ้น

WORKSPACE.bzlmod มีไวยากรณ์เหมือนกับ WORKSPACE ทุกประการ เมื่อเปิดใช้ Bzlmod หากมีไฟล์ WORKSPACE.bzlmod อยู่ที่รูทของพื้นที่ทำงานด้วย ให้ทำดังนี้

การใช้ไฟล์ WORKSPACE.bzlmod จะช่วยให้การย้ายข้อมูลง่ายขึ้นเนื่องจาก

  • เมื่อปิดใช้ Bzlmod คุณจะกลับไปดึงข้อมูลทรัพยากร Dependency จากไฟล์ WORKSPACE เดิม
  • เมื่อเปิดใช้ Bzlmod คุณจะติดตามได้ดียิ่งขึ้นว่ายังเหลือการย้ายข้อมูลการอ้างอิงใดบ้างด้วย WORKSPACE.bzlmod

ระดับการเข้าถึงที่เก็บ

Bzlmod สามารถควบคุมได้ว่าจะให้ที่เก็บอื่นๆ ใดบ้างที่มองเห็นได้จากที่เก็บหนึ่งๆ ดูรายละเอียดเพิ่มเติมได้ที่ชื่อที่เก็บและ strict deps

ต่อไปนี้คือสรุปการเข้าถึงที่เก็บจากที่เก็บประเภทต่างๆ เมื่อพิจารณาถึง WORKSPACE ด้วย

จากที่เก็บหลัก จากที่เก็บโมดูล Bazel จากที่เก็บส่วนขยายของโมดูล จากที่เก็บ WORKSPACE
ที่เก็บหลัก แสดง หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรง หากโมดูลรูทเป็นทรัพยากร Dependency โดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล แสดง
ที่เก็บโมดูล Bazel การขึ้นต่อโดยตรง การขึ้นต่อโดยตรง การขึ้นต่อกันโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล การขึ้นต่อกันโดยตรงของโมดูลรูท
ที่เก็บส่วนขยายโมดูล การขึ้นต่อโดยตรง การขึ้นต่อโดยตรง การขึ้นต่อกันโดยตรงของโมดูลที่โฮสต์ส่วนขยายโมดูล + ที่เก็บข้อมูลทั้งหมดที่สร้างขึ้นโดยส่วนขยายโมดูลเดียวกัน การขึ้นต่อกันโดยตรงของโมดูลรูท
ที่เก็บข้อมูลของ Workspace ทั้งหมดที่มองเห็นได้ ไม่แสดง ไม่แสดง ทั้งหมดที่มองเห็นได้

กระบวนการย้ายข้อมูลด้วยตนเอง

กระบวนการย้ายข้อมูล Bzlmod ทั่วไปอาจมีลักษณะดังนี้

  1. ทำความเข้าใจการขึ้นต่อกันที่คุณมีใน WORKSPACE
  2. เพิ่มไฟล์ MODULE.bazel ที่ว่างเปล่าในรูทของโปรเจ็กต์
  3. เพิ่มไฟล์ WORKSPACE.bzlmod ที่ว่างเปล่าเพื่อลบล้างเนื้อหาไฟล์ WORKSPACE
  4. สร้างเป้าหมายโดยเปิดใช้ Bzlmod และตรวจสอบว่าที่เก็บใดขาดหายไป
  5. ตรวจสอบคำจำกัดความของที่เก็บที่ขาดหายไปในไฟล์การอ้างอิงที่แก้ไขแล้ว
  6. แนะนำการขึ้นต่อกันที่ขาดหายไปเป็นโมดูล Bazel ผ่านส่วนขยายโมดูล หรือปล่อยไว้ใน WORKSPACE.bzlmod เพื่อการย้ายข้อมูลในภายหลัง
  7. กลับไปที่ขั้นตอนที่ 4 แล้วทำซ้ำจนกว่าจะพร้อมใช้งาน

เผยแพร่โมดูล 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 สำหรับการทดสอบโดยไม่จำเป็นสำหรับการสร้าง เป้าหมายที่ไม่ต้องการ จริงๆ แล้วการดำเนินการนี้ไม่ได้เจาะจงเฉพาะ Bzlmod แต่ การปฏิบัติตามแนวทางนี้จะช่วยให้ระบุทรัพยากร Dependency สำหรับการพัฒนาได้อย่างถูกต้องง่ายขึ้น

ระบุทรัพยากร Dependency สำหรับการพัฒนา

คุณตั้งค่าแอตทริบิวต์ dev_dependency เป็น true สำหรับ bazel_dep และ use_extension ได้เพื่อให้ แอตทริบิวต์ดังกล่าวไม่แพร่กระจายไปยังโปรเจ็กต์ที่ขึ้นต่อกัน ในฐานะโมดูลรูท คุณสามารถใช้แฟล็ก --ignore_dev_dependency เพื่อตรวจสอบว่าเป้าหมายยังสร้างได้โดยไม่มีทรัพยากร Dependency สำหรับการพัฒนาและการลบล้างหรือไม่

ความคืบหน้าในการย้ายข้อมูลชุมชน

คุณสามารถตรวจสอบรีจิสทรีกลางของ Bazel เพื่อดูว่ามีการขึ้นต่อกันของคุณอยู่แล้วหรือไม่ หรือคุณจะเข้าร่วมการสนทนาใน GitHub นี้เพื่อโหวตหรือโพสต์การอ้างอิงที่บล็อกการย้ายข้อมูลก็ได้

รายงานปัญหา

โปรดดูรายการปัญหา GitHub ของ Bazel เพื่อดูปัญหาที่ทราบเกี่ยวกับ Bzlmod โปรดรายงานปัญหาใหม่หรือคำขอฟีเจอร์ที่จะช่วยให้การย้ายข้อมูลของคุณไม่ติดขัด