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

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

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

ลบล้างทรัพยากร 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 และระบุเวอร์ชัน ของการอ้างอิงข้อมูลที่ต้องการได้ สมมติว่าคุณมีทรัพยากร Dependency อื่น @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 สำหรับการอ้างอิงข้อมูลโดยอัตโนมัติ

ผสานรวมเครื่องมือจัดการแพ็กเกจของบุคคลที่สาม

จากส่วนสุดท้าย เนื่องจากส่วนขยายโมดูลมีวิธีรวบรวมข้อมูลจากกราฟการขึ้นต่อกัน ดำเนินการตรรกะที่กำหนดเองเพื่อแก้ไขการขึ้นต่อกัน และเรียกใช้กฎของที่เก็บเพื่อนำที่เก็บภายนอกมาใช้ จึงเป็นวิธีที่ยอดเยี่ยมสำหรับผู้เขียนกฎในการปรับปรุงชุดกฎที่ผสานรวมเครื่องมือจัดการแพ็กเกจสำหรับภาษาที่เฉพาะเจาะจง

โปรดอ่านหน้าส่วนขยายโมดูลเพื่อดูข้อมูลเพิ่มเติม เกี่ยวกับวิธีใช้ส่วนขยายโมดูล

ต่อไปนี้คือรายการชุดกฎที่ใช้ 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

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

กฎ 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

    คำสั่งซิงค์ใช้ไม่ได้อีกต่อไป แต่คำสั่งดึงข้อมูลมีตัวเลือกต่างๆ คุณสามารถดึงข้อมูลเป้าหมาย ที่เก็บ ชุดของ repo ที่กำหนดค่า หรือที่เก็บทั้งหมด ที่เกี่ยวข้องกับการแก้ปัญหาการขึ้นต่อกันและส่วนขยายโมดูล ระบบจะแคชผลการดึงข้อมูล และหากต้องการบังคับให้ดึงข้อมูล คุณต้องใส่ตัวเลือก --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 ของผู้ใช้เพื่อแทรกการอ้างอิงเริ่มต้นบางรายการ ซึ่งมักจำเป็นสำหรับ กฎดั้งเดิม (เช่น @bazel_tools, @platforms และ @remote_java_tools) เมื่อใช้ Bzlmod การอ้างอิงเหล่านั้นจะมาพร้อมกับโมดูลในตัว bazel_tools ซึ่งเป็นการอ้างอิงเริ่มต้นสำหรับโมดูล 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 และทำซ้ำจนกว่าจะพร้อมใช้งาน

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

เรามีสคริปต์ตัวช่วยในการย้ายข้อมูล 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 นี้เพื่อโหวตหรือโพสต์การอ้างอิงที่บล็อกการย้ายข้อมูลก็ได้

รายงานปัญหา

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