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

รายงานปัญหา ดูแหล่งที่มา

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

WORKSPACE เทียบกับ Bzlmod

WORKSPACE และ Bzlmod ของ Bazel มีฟีเจอร์ที่คล้ายกันและใช้ไวยากรณ์ต่างกัน หัวข้อนี้จะอธิบายวิธีย้ายข้อมูลจากฟังก์ชันการทำงานของ WORKSPACE ที่เฉพาะเจาะจงไปยัง Bzlmod

กำหนดรูทของพื้นที่ทำงาน Bazel

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

  • พื้นที่ทำงาน

    # This file marks the root of the Bazel workspace.
    # See MODULE.bazel for external dependencies setup.
    

เปิดใช้ Bzlmod ใน bazelrc ของคุณ

.bazelrc ให้คุณตั้งค่าแฟล็กที่จะมีผลทุกครั้งที่คุณเรียกใช้ Bazel หากต้องการเปิดใช้ Bzlmod ให้ใช้แฟล็ก --enable_bzlmod และนำไปใช้กับคำสั่ง common เพื่อให้มีผลกับทุกคำสั่ง ดังนี้

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

ระบุชื่อที่เก็บสำหรับพื้นที่ทำงานของคุณ

  • พื้นที่ทำงาน

    ฟังก์ชัน 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 เป็นเรื่องปกติที่จะใช้กฎที่เก็บ 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()
    

    คุณจะเห็นว่ารูปแบบนี้เป็นรูปแบบทั่วไปที่ผู้ใช้ต้องโหลดทรัพยากร Dependency แบบทางอ้อมจากมาโครของทรัพยากร Dependency สมมติว่าทั้ง bazel_skylib และ rules_java ขึ้นอยู่กับ platform เวอร์ชันที่แน่นอนของทรัพยากร Dependency ของ platform จะกำหนดโดยลำดับของมาโคร

  • Bzlmod

    เมื่อใช้ Bzlmod ตราบใดที่ทรัพยากร Dependency ของคุณพร้อมใช้งานใน Bazel Central Registry หรือรีจิสทรี 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 แก้ไขทรัพยากร Dependency ของโมดูล Bazel อย่างคร่าวๆ โดยใช้อัลกอริทึม MVS ดังนั้น ระบบจะเลือก platform เวอร์ชันสูงสุดที่จำเป็นโดยอัตโนมัติ

ลบล้างทรัพยากร Dependency แบบโมดูล Bazel

ในฐานะโมดูลรูท คุณลบล้างทรัพยากร Dependency ของโมดูล Bazel ได้หลายวิธี

โปรดอ่านข้อมูลเพิ่มเติมในส่วนoverrides

คุณดูตัวอย่างการใช้งานได้ในที่เก็บตัวอย่าง

ดึงข้อมูลทรัพยากร Dependency ภายนอกด้วยส่วนขยายโมดูล

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

  • พื้นที่ทำงาน

    ดาวน์โหลดไฟล์โดยใช้กฎที่เก็บ 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",
        )
    

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

  • Bzlmod

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

ตัวอย่างง่ายๆ ที่ผสานรวมตัวจัดการแพ็กเกจจำลองจะอยู่ในที่เก็บตัวอย่าง

ตรวจหาเชนเครื่องมือในเครื่องโฮสต์

เมื่อกฎบิลด์ของ Bazel ต้องตรวจจับเชนเครื่องมือที่พร้อมใช้งานบนเครื่องโฮสต์ กฎดังกล่าวจะใช้กฎที่เก็บเพื่อตรวจสอบเครื่องโฮสต์และสร้างข้อมูล Toolchain เป็นที่เก็บภายนอก

  • พื้นที่ทำงาน

    ตามกฎที่เก็บต่อไปนี้เพื่อตรวจหาเชนเครื่องมือของ 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 คุณจะลงทะเบียนห่วงโซ่เครื่องมือได้ด้วยวิธีต่อไปนี้

    1. คุณจะลงทะเบียนเครื่องมือเชนไฟล์ .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. หรือลงทะเบียนห่วงโซ่เครื่องมือในไฟล์ 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 register_toolchains และ register_execution_platforms API จะใช้ได้เฉพาะในไฟล์ 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 แต่ละไฟล์จะเรียงตามลำดับความสำคัญต่อไปนี้ในระหว่างการเลือก Toolchain (จากสูงสุดไปต่ำสุด)

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

แนะนำที่เก็บในเครื่อง

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

  • พื้นที่ทำงาน

    ด้วย 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 ในส่วนขยายโมดูลได้ เนื่องจากระบบต้องติดดาวให้กฎที่เก็บเนทีฟทั้งหมดเป็นดาวเด่น (ตรวจสอบความคืบหน้าได้ที่ #18285) จากนั้นเรียก Starlark local_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

การดึงข้อมูลกับการซิงค์

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

  • พื้นที่ทำงาน

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

  • Bzlmod

    คำสั่งซิงค์นี้ใช้ไม่ได้แล้ว แต่การดึงข้อมูลมีตัวเลือกต่างๆ คุณสามารถดึงข้อมูลเป้าหมาย ที่เก็บ ชุดของที่เก็บที่กำหนดค่าไว้ หรือที่เก็บทั้งหมดที่เกี่ยวข้องกับการแก้ปัญหาทรัพยากร Dependency และส่วนขยายโมดูล ผลการดึงข้อมูลมีการแคชไว้ และหากต้องการบังคับให้ดึงข้อมูล คุณต้องใส่ตัวเลือก --force ในระหว่างกระบวนการดึงข้อมูล

การย้ายข้อมูล

ส่วนนี้จะมีข้อมูลและคำแนะนำที่เป็นประโยชน์สำหรับกระบวนการย้ายข้อมูล Bzlmod

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

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

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

โชคดีที่ --experimental_repository_resolved_file ช่วยได้ แฟล็กนี้จะสร้าง "ไฟล์ล็อก" ของทรัพยากร Dependency ภายนอกที่ดึงมาทั้งหมดในคำสั่ง 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 คุณจะดึงข้อมูลทรัพยากร Dependency ทั้งหมดที่ระบุไว้ในไฟล์ Workspace ซึ่งได้แก่

    • การใช้งาน bind
    • การใช้ register_toolchains และ register_execution_platforms

    อย่างไรก็ตาม หากโปรเจ็กต์เป็นแบบข้ามแพลตฟอร์ม การซิงค์แบบ Bazel อาจใช้งานไม่ได้ในบางแพลตฟอร์ม เนื่องจากกฎที่เก็บบางกฎอาจทำงานได้อย่างถูกต้องในแพลตฟอร์มที่รองรับเท่านั้น

หลังจากเรียกใช้คำสั่งแล้ว คุณควรมีข้อมูลทรัพยากร Dependency ภายนอกของคุณในไฟล์ resolved.bzl

ตรวจสอบทรัพยากร Dependency ภายนอกด้วย bazel query

คุณอาจทราบว่าสามารถใช้ bazel query เพื่อตรวจสอบกฎที่เก็บกับ

bazel query --output=build //external:<repo name>

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

ทรัพยากร Dependency เริ่มต้นในตัว

หากตรวจสอบไฟล์ที่ --experimental_repository_resolved_file สร้างขึ้น คุณจะเห็นทรัพยากร Dependency หลายรายการที่ไม่ได้กำหนดไว้ใน WORKSPACE เนื่องจากในความเป็นจริง Bazel จะเพิ่มคำนำหน้าและคำต่อท้ายให้เนื้อหาไฟล์ WORKSPACE ของผู้ใช้เพื่อแทรกทรัพยากร Dependency เริ่มต้นบางรายการ ซึ่งมักจำเป็นสำหรับกฎเนทีฟ (เช่น @bazel_tools, @platforms และ @remote_java_tools) เมื่อใช้ Bzlmod ระบบจะแนะนำทรัพยากร Dependency เหล่านั้นด้วยโมดูลในตัว bazel_tools ซึ่งเป็นทรัพยากร Dependency เริ่มต้นสำหรับโมดูลอื่นๆ ทั้งหมดของ Bazl

โหมดผสมสำหรับการทยอยย้ายข้อมูล

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

WORKSPACE.bzlmod

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

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

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

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

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

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

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

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

กระบวนการย้ายข้อมูล

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

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

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

เรามีสคริปต์ตัวช่วยการย้ายข้อมูล Bzlmod แบบอินเทอร์แอกทีฟที่ช่วยให้คุณเริ่มต้นใช้งานได้

สคริปต์จะทำสิ่งต่อไปนี้

  • สร้างและแยกวิเคราะห์ไฟล์ที่แก้ไขแล้วของ WORKSPACE
  • พิมพ์ข้อมูลที่เก็บจากไฟล์ที่แก้ไขแล้วในแบบที่มนุษย์อ่านได้
  • เรียกใช้คำสั่ง Bazel Build ตรวจหาข้อความแสดงข้อผิดพลาดที่รู้จัก และแนะนำวิธีย้ายข้อมูล
  • ตรวจสอบว่าทรัพยากร Dependency พร้อมใช้งานใน BCR อยู่แล้วหรือไม่
  • เพิ่มการอ้างอิงไปยังไฟล์ 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 ของคุณเป็นทรัพยากร Dependency สำหรับโปรเจ็กต์อื่นๆ คุณจะเผยแพร่โปรเจ็กต์ใน Bazel Central Registry ได้

เพื่อให้สามารถตรวจสอบในโปรเจ็กต์ใน BCR ได้ คุณต้องมี URL ที่เก็บถาวรของต้นทางของโปรเจ็กต์ ข้อควรทราบเมื่อสร้างที่เก็บถาวรแหล่งที่มา มีดังนี้

  • ตรวจสอบว่าที่เก็บถาวรชี้ไปยังเวอร์ชันที่เฉพาะเจาะจง

    BCR จะยอมรับได้เฉพาะที่เก็บถาวรของแหล่งที่มาที่มีเวอร์ชันเนื่องจาก Bzlmod ต้องเปรียบเทียบเวอร์ชันระหว่างการแก้ปัญหาทรัพยากร Dependency

  • ตรวจสอบว่า URL ของที่เก็บถาวรเสถียร

    Bazel จะตรวจสอบเนื้อหาของที่เก็บถาวรโดยใช้ค่าแฮช คุณจึงควรตรวจสอบว่าการตรวจสอบข้อผิดพลาดของไฟล์ที่ดาวน์โหลดมาไม่มีการเปลี่ยนแปลง หาก URL มาจาก GitHub โปรดสร้างและอัปโหลดไฟล์ที่เก็บถาวรของรุ่นในหน้าการเผยแพร่ GitHub ไม่ได้รับประกัน Checksum ของที่เก็บถาวรของแหล่งที่มาที่สร้างขึ้นตามคำขอ กล่าวโดยสรุปคือ 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 พร้อมคำขอพุลของ GitHub

เราขอแนะนำอย่างยิ่งให้ตั้งค่าแอป GitHub เผยแพร่ไปยัง BCR สำหรับที่เก็บเพื่อทำให้กระบวนการส่งโมดูลไปยัง BCR เป็นไปโดยอัตโนมัติ

แนวทางปฏิบัติแนะนำ

ส่วนนี้จะอธิบายแนวทางปฏิบัติแนะนำที่คุณควรทำตามเพื่อจัดการทรัพยากร Dependency ภายนอกได้ดียิ่งขึ้น

แยกเป้าหมายออกเป็นแพ็กเกจที่แตกต่างกันเพื่อหลีกเลี่ยงการดึงข้อมูลทรัพยากร Dependency ที่ไม่จำเป็น

ดู #12835 ซึ่งจะบังคับให้ระบบดึงข้อมูลทรัพยากร Dependency สำหรับนักพัฒนาซอฟต์แวร์สำหรับการทดสอบโดยไม่จำเป็นสำหรับการสร้างเป้าหมายที่ไม่จำเป็นต้องใช้ อันที่จริงแล้ว วิธีนี้ไม่ได้มีไว้สำหรับ Bzlmod โดยเฉพาะ แต่การทำตามแนวทางปฏิบัตินี้จะช่วยให้คุณระบุทรัพยากร Dependency สำหรับนักพัฒนาซอฟต์แวร์ได้อย่างถูกต้องง่ายขึ้น

ระบุทรัพยากร Dependency สำหรับนักพัฒนาซอฟต์แวร์

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

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

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

รายงานปัญหา

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