Hướng dẫn di chuyển Bzlmod

Báo cáo sự cố Xem nguồn

Do những thiếu sót của WORKSPACE, Bzlmod sẽ thay thế hệ thống WORKSPACE cũ trong các bản phát hành Bazel sau này. Hướng dẫn này giúp bạn di chuyển dự án của mình sang Bzlmod và thả WORKSPACE để tìm nạp các phần phụ thuộc bên ngoài.

WORKSPACE so với Bzlmod

WORKSPACE và Bzlmod của Bazel cung cấp các tính năng tương tự nhưng có cú pháp khác nhau. Phần này giải thích cách di chuyển từ các chức năng cụ thể của WORKSPACE sang Bzlmod.

Xác định thư mục gốc của không gian làm việc Bazel

Tệp WORKSPACE đánh dấu gốc nguồn của một dự án Bazel. Trách nhiệm này sẽ được thay thế bằng MODULE.bazel trong Bazel phiên bản 6.3 trở lên. Với phiên bản Bazel trước 6.3, bạn vẫn sẽ thấy tệp WORKSPACE hoặc WORKSPACE.bazel tại thư mục gốc của không gian làm việc, có thể kèm theo các nhận xét như:

  • KHÔNG GIAN LÀM VIỆC

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

Bật Bzlmod trong bazelrc của bạn

.bazelrc cho phép bạn đặt cờ áp dụng mỗi khi chạy Bazel. Để bật Bzlmod, hãy sử dụng cờ --enable_bzlmod và áp dụng cờ này cho lệnh common để áp dụng cho mọi lệnh:

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

Chỉ định tên kho lưu trữ cho không gian làm việc của bạn

  • KHÔNG GIAN LÀM VIỆC

    Hàm workspace dùng để chỉ định tên kho lưu trữ cho không gian làm việc của bạn. Điều này cho phép //foo:bar mục tiêu trong không gian làm việc được tham chiếu là @<workspace name>//foo:bar. Nếu không được chỉ định, tên kho lưu trữ mặc định cho không gian làm việc của bạn sẽ là __main__.

    ## WORKSPACE
    workspace(name = "com_foo_bar")
    
  • Bzlmod

    Bạn nên tham chiếu các mục tiêu trong cùng một không gian làm việc bằng cú pháp //foo:bar không có @<repo name>. Tuy nhiên, nếu cần cú pháp cũ, bạn có thể sử dụng tên mô-đun do hàm module chỉ định làm tên kho lưu trữ. Nếu tên mô-đun khác với tên kho lưu trữ cần thiết, bạn có thể dùng thuộc tính repo_name của hàm module để ghi đè tên kho lưu trữ đó.

    ## MODULE.bazel
    module(
        name = "bar",
        repo_name = "com_foo_bar",
    )
    

Tìm nạp các phần phụ thuộc bên ngoài dưới dạng mô-đun Bazel

Nếu phần phụ thuộc của bạn là một dự án Bazel, bạn có thể dựa vào phần phụ thuộc đó làm mô-đun Bazel khi dự án này cũng sử dụng Bzlmod.

  • KHÔNG GIAN LÀM VIỆC

    Với WORKSPACE, thông thường, bạn nên sử dụng các quy tắc về kho lưu trữ http_archive hoặc git_repository để tải các nguồn của dự án Bazel xuống.

    ## 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()
    

    Như bạn có thể thấy, đây là một mẫu phổ biến mà người dùng cần tải các phần phụ thuộc bắc cầu từ một macro của phần phụ thuộc. Giả sử cả bazel_skylibrules_java đều phụ thuộc vào platform, thì phiên bản chính xác của phần phụ thuộc platform được xác định theo thứ tự của các macro.

  • Bzlmod

    Với Bzlmod, miễn là phần phụ thuộc của bạn có trong Sổ đăng ký Trung tâm Bazel hoặc trong hệ thống đăng ký BigQuery tuỳ chỉnh của mình, bạn chỉ cần phụ thuộc vào phần phụ thuộc đó bằng lệnh bazel_dep.

    ## MODULE.bazel
    bazel_dep(name = "bazel_skylib", version = "1.4.2")
    bazel_dep(name = "rules_java", version = "6.1.1")
    

    Bzlmod phân giải các phần phụ thuộc của mô-đun Bazel theo cách bắc cầu bằng thuật toán MVS. Do đó, phiên bản bắt buộc tối đa của platform sẽ được chọn tự động.

Ghi đè phần phụ thuộc dưới dạng mô-đun Bazel

Là mô-đun gốc, bạn có thể ghi đè các phần phụ thuộc của mô-đun Bazel theo nhiều cách.

Vui lòng đọc phần overrides để biết thêm thông tin.

Bạn có thể tìm thấy một số ví dụ về cách sử dụng trong kho lưu trữ ví dụ.

Tìm nạp các phần phụ thuộc bên ngoài bằng tiện ích mô-đun

Nếu phần phụ thuộc của bạn không phải là một dự án Bazel hoặc chưa có trong bất kỳ hệ thống đăng ký Bazel nào, bạn có thể giới thiệu phần phụ thuộc đó bằng cách sử dụng use_repo_rule hoặc phần mở rộng mô-đun.

  • KHÔNG GIAN LÀM VIỆC

    Tải tệp xuống bằng cách sử dụng quy tắc kho lưu trữ 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

    Với Bzlmod, bạn có thể sử dụng lệnh use_repo_rule trong tệp MODULE.bazel để trực tiếp tạo thực thể cho các kho lưu trữ:

    ## 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",
    )
    

    Về sau, việc này được triển khai bằng cách sử dụng tiện ích mô-đun. Nếu cần thực hiện logic phức tạp hơn thay vì chỉ gọi quy tắc kho lưu trữ, bạn cũng có thể tự triển khai tiện ích mô-đun. Bạn cần chuyển định nghĩa vào tệp .bzl. Thao tác này cũng cho phép bạn chia sẻ định nghĩa giữa WORKSPACE và Bzlmod trong quá trình di chuyển.

    ## 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",
        )
    

    Triển khai tiện ích mô-đun để tải macro phần phụ thuộc. Bạn có thể xác định macro này trong cùng một tệp .bzl của macro, nhưng để duy trì khả năng tương thích với các phiên bản Bazel cũ, bạn nên xác định trong một tệp .bzl riêng.

    ## 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,
    )
    

    Để dự án gốc hiển thị kho lưu trữ, bạn nên khai báo việc sử dụng đuôi mô-đun và kho lưu trữ trong tệp MODULE.bazel.

    ## MODULE.bazel
    non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
    use_repo(non_module_dependencies, "data_file")
    

Giải quyết các phần phụ thuộc bên ngoài xung đột bằng tiện ích mô-đun

Một dự án có thể cung cấp macro giới thiệu kho lưu trữ bên ngoài dựa trên dữ liệu đầu vào từ phương thức gọi. Nhưng nếu có nhiều phương thức gọi trong biểu đồ phần phụ thuộc và các phương thức này gây ra xung đột thì sao?

Giả sử dự án foo cung cấp macro sau đây, lấy version làm đối số.

## 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
    )
  • KHÔNG GIAN LÀM VIỆC

    Với WORKSPACE, bạn có thể tải macro từ @foo và chỉ định phiên bản của phần phụ thuộc dữ liệu mà bạn cần. Giả sử bạn có một phần phụ thuộc khác @bar, phần phụ thuộc này cũng phụ thuộc vào @foo nhưng đòi hỏi một phiên bản khác của phần phụ thuộc dữ liệu đó.

    ## 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")
    

    Trong trường hợp này, người dùng cuối phải điều chỉnh cẩn thận thứ tự macro trong WORKSPACE để nhận được phiên bản họ cần. Đây là một trong những khó khăn lớn nhất với WORKSPACE vì công cụ này không thực sự đưa ra cách hợp lý để giải quyết các phần phụ thuộc.

  • Bzlmod

    Với Bzlmod, tác giả của dự án foo có thể sử dụng tiện ích mô-đun để giải quyết xung đột. Ví dụ: giả sử bạn luôn chọn phiên bản tối đa bắt buộc của phần phụ thuộc dữ liệu trong số tất cả các mô-đun 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")
    

    Trong trường hợp này, mô-đun gốc yêu cầu phiên bản dữ liệu 2.0, trong khi phần phụ thuộc bar yêu cầu 3.0. Tiện ích mô-đun trong foo có thể giải quyết chính xác xung đột này và tự động chọn phiên bản 3.0 cho phần phụ thuộc dữ liệu.

Tích hợp trình quản lý gói của bên thứ ba

Tiếp theo phần cuối, vì tiện ích mô-đun cung cấp cách thức để thu thập thông tin từ biểu đồ phần phụ thuộc, thực hiện logic tuỳ chỉnh để phân giải các phần phụ thuộc và gọi quy tắc kho lưu trữ để giới thiệu các kho lưu trữ bên ngoài, nên đây là một cách hay để tác giả quy tắc cải thiện tập quy tắc tích hợp trình quản lý gói cho các ngôn ngữ cụ thể.

Vui lòng đọc trang phần mở rộng về mô-đun để tìm hiểu thêm về cách sử dụng phần mở rộng của mô-đun.

Dưới đây là danh sách các tập hợp quy tắc đã sử dụng Bzlmod để tìm nạp các phần phụ thuộc từ nhiều trình quản lý gói:

Bạn có thể xem một ví dụ tối thiểu về việc tích hợp trình quản lý gói giả tại kho lưu trữ ví dụ.

Phát hiện chuỗi công cụ trên máy chủ lưu trữ

Khi các quy tắc xây dựng của Bazel cần phát hiện chuỗi công cụ nào hiện có trên máy chủ, các quy tắc đó sẽ sử dụng các quy tắc kho lưu trữ để kiểm tra máy chủ và tạo thông tin về chuỗi công cụ dưới dạng kho lưu trữ bên ngoài.

  • KHÔNG GIAN LÀM VIỆC

    Cho quy tắc kho lưu trữ sau đây để phát hiện chuỗi công cụ 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,
    )
    

    Bạn có thể tải quy tắc kho lưu trữ trong WORKSPACE.

    ## WORKSPACE
    load("//:local_config_sh.bzl", "sh_config_rule")
    sh_config_rule(name = "local_config_sh")
    
  • Bzlmod

    Với Bzlmod, bạn có thể giới thiệu cùng một kho lưu trữ bằng cách sử dụng tiện ích mô-đun, tương tự như việc giới thiệu kho lưu trữ @data_file trong phần trước.

    ## 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"),
    )
    

    Sau đó, sử dụng đuôi tệp trong tệp 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")
    

Đăng ký chuỗi công cụ và nền tảng thực thi

Theo phần cuối cùng, sau khi giới thiệu một kho lưu trữ lưu trữ thông tin về chuỗi công cụ (ví dụ: local_config_sh), bạn có thể muốn đăng ký chuỗi công cụ.

  • KHÔNG GIAN LÀM VIỆC

    Với WORKSPACE, bạn có thể đăng ký chuỗi công cụ theo những cách sau.

    1. Bạn có thể đăng ký chuỗi công cụ cho tệp .bzl và tải macro trong tệp 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. Hoặc đăng ký trực tiếp chuỗi công cụ trong tệp 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

    Với Bzlmod, các API register_toolchainsregister_execution_platforms chỉ có trong tệp MODULE.bazel. Bạn không thể gọi native.register_toolchains trong tiện ích mô-đun.

    ## 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")
    

Các chuỗi công cụ và nền tảng thực thi đã đăng ký trong WORKSPACE, WORKSPACE.bzlmod và tệp MODULE.bazel của từng mô-đun Bazel đều tuân theo thứ tự ưu tiên sau trong quá trình lựa chọn chuỗi công cụ (từ cao nhất đến thấp nhất):

  1. chuỗi công cụ và nền tảng thực thi đã đăng ký trong tệp MODULE.bazel của mô-đun gốc.
  2. chuỗi công cụ và nền tảng thực thi đã đăng ký trong tệp WORKSPACE hoặc WORKSPACE.bzlmod.
  3. chuỗi công cụ và nền tảng thực thi do các mô-đun đăng ký là phần phụ thuộc (có tính chất bắc cầu) của mô-đun gốc.
  4. khi không sử dụng WORKSPACE.bzlmod: các chuỗi công cụ đã đăng ký trong hậu tố WORKSPACE.

Ra mắt kho lưu trữ cục bộ

Bạn có thể cần phải giới thiệu một phần phụ thuộc làm kho lưu trữ cục bộ khi cần phiên bản cục bộ của phần phụ thuộc để gỡ lỗi hoặc bạn muốn kết hợp một thư mục trong không gian làm việc của mình làm kho lưu trữ bên ngoài.

  • KHÔNG GIAN LÀM VIỆC

    Với WORKSPACE, điều này có được nhờ hai quy tắc về kho lưu trữ gốc là local_repositorynew_local_repository.

    ## WORKSPACE
    local_repository(
        name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    
  • Bzlmod

    Với Bzlmod, bạn có thể dùng local_path_override để ghi đè một mô-đun có đường dẫn cục bộ.

    ## MODULE.bazel
    bazel_dep(name = "rules_java")
    local_path_override(
        module_name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    

    Bạn cũng có thể giới thiệu một kho lưu trữ cục bộ có đuôi mô-đun. Tuy nhiên, bạn không thể gọi native.local_repository trong phần mở rộng mô-đun. Chúng tôi đang nỗ lực làm rõ tất cả các quy tắc về kho lưu trữ gốc (xem #18285 để biết tiến trình). Sau đó, bạn có thể gọi starlark local_repository tương ứng trong một đuôi mô-đun. Việc triển khai phiên bản tuỳ chỉnh của quy tắc kho lưu trữ local_repository cũng không hề đơn giản nếu đây là vấn đề chặn đối với bạn.

Liên kết các mục tiêu

Quy tắc bind trong WORKSPACE không được dùng nữa và không được hỗ trợ trong Bzlmod. Hàm này được giới thiệu để tạo bí danh cho một mục tiêu trong gói //external đặc biệt. Tất cả người dùng phụ thuộc vào tuỳ chọn này sẽ di chuyển khỏi nhóm.

Ví dụ: Nếu bạn có

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

Điều này cho phép các mục tiêu khác phụ thuộc vào //external:openssl. Bạn có thể di chuyển khỏi chế độ này bằng cách:

  • Thay thế mọi cách sử dụng của //external:openssl bằng @my-ssl//src:openssl-lib.

  • Hoặc sử dụng quy tắc xây dựng alias

    • Xác định mục tiêu sau trong một gói (ví dụ: //third_party)

      ## third_party/BUILD
      alias(
          name = "openssl",
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • Thay thế mọi cách sử dụng của //external:openssl bằng //third_party:openssl.

Tìm nạp và đồng bộ hoá

Các lệnh tìm nạp và đồng bộ hoá được dùng để tải các kho lưu trữ bên ngoài xuống cục bộ và cập nhật các kho lưu trữ đó. Đôi khi, bạn cũng có thể cho phép tạo bản dựng ngoại tuyến bằng cách sử dụng cờ --nofetch sau khi tìm nạp tất cả kho lưu trữ cần thiết cho một bản dựng.

  • KHÔNG GIAN LÀM VIỆC

    Quá trình đồng bộ hoá thực hiện quá trình tìm nạp bắt buộc đối với tất cả các kho lưu trữ hoặc cho một tập hợp kho lưu trữ đã định cấu hình cụ thể, trong khi quá trình tìm nạp chỉ được dùng để tìm nạp cho một mục tiêu cụ thể.

  • Bzlmod

    Lệnh đồng bộ hoá không còn áp dụng được nữa, nhưng hoạt động tìm nạp cung cấp nhiều lựa chọn. Bạn có thể tìm nạp mục tiêu, kho lưu trữ, tập hợp kho lưu trữ đã định cấu hình hoặc tất cả các kho lưu trữ liên quan đến việc phân giải phần phụ thuộc và tiện ích mô-đun của mình. Kết quả tìm nạp sẽ được lưu vào bộ nhớ đệm và để buộc tìm nạp, bạn phải đưa lựa chọn --force vào trong quá trình tìm nạp.

Di chuyển

Phần này cung cấp thông tin và hướng dẫn hữu ích cho quy trình di chuyển Bzlmod của bạn.

Tìm hiểu về các phần phụ thuộc trong WORKSPACE

Bước đầu tiên của quá trình di chuyển là tìm hiểu xem bạn có những phần phụ thuộc nào. Bạn khó có thể tìm ra phần phụ thuộc chính xác nào được đưa vào tệp WORKSPACE vì các phần phụ thuộc bắc cầu thường được tải bằng macro *_deps.

Kiểm tra phần phụ thuộc bên ngoài bằng tệp đã giải quyết không gian làm việc

Rất may là cờ --experimental_repository_resolved_file có thể giúp ích. Về cơ bản, cờ này tạo ra một "tệp khoá" gồm tất cả các phần phụ thuộc bên ngoài đã tìm nạp trong lệnh Bazel gần đây nhất của bạn. Bạn có thể tìm thêm thông tin chi tiết trong bài đăng trên blog này.

Có thể sử dụng theo hai cách:

  1. Để tìm nạp thông tin về các phần phụ thuộc bên ngoài cần thiết nhằm xây dựng một số mục tiêu nhất định.

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. Để tìm nạp thông tin của tất cả phần phụ thuộc bên ngoài được xác định trong tệp WORKSPACE.

    bazel clean --expunge
    bazel sync --experimental_repository_resolved_file=resolved.bzl
    

    Với lệnh bazel sync, bạn có thể tìm nạp tất cả phần phụ thuộc được xác định trong tệp WORKSPACE, bao gồm:

    • bind lượt sử dụng
    • Mức sử dụng register_toolchainsregister_execution_platforms

    Tuy nhiên, nếu dự án của bạn chạy trên nhiều nền tảng, thì tính năng đồng bộ hoá bazel có thể bị lỗi trên một số nền tảng vì một số quy tắc về kho lưu trữ chỉ có thể chạy chính xác trên các nền tảng được hỗ trợ.

Sau khi chạy lệnh, bạn sẽ có thông tin về các phần phụ thuộc bên ngoài trong tệp resolved.bzl.

Kiểm tra phần phụ thuộc bên ngoài bằng bazel query

Bạn cũng có thể biết bazel query có thể được dùng để kiểm tra các quy tắc kho lưu trữ thông qua

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

Mặc dù thuận tiện và nhanh hơn nhiều, nhưng truy vấn bazel có thể dựa trên phiên bản phần phụ thuộc bên ngoài, vì vậy, hãy cẩn thận khi sử dụng truy vấn này! Bạn có thể truy vấn và kiểm tra các phần phụ thuộc bên ngoài bằng Bzlmod qua một lệnh con mới.

Phần phụ thuộc mặc định tích hợp sẵn

Nếu kiểm tra tệp do --experimental_repository_resolved_file tạo, bạn sẽ thấy nhiều phần phụ thuộc chưa được xác định trong WORKSPACE. Điều này là do Bazel thực sự đã thêm các tiền tố và hậu tố vào nội dung tệp WORKSPACE của người dùng để chèn một số phần phụ thuộc mặc định mà các quy tắc gốc thường yêu cầu (ví dụ: @bazel_tools, @platforms@remote_java_tools). Với Bzlmod, các phần phụ thuộc đó được đưa vào bằng một mô-đun tích hợp bazel_tools. Đây là phần phụ thuộc mặc định cho mọi mô-đun Bazel khác.

Chế độ kết hợp để di chuyển dần

Bzlmod và WORKSPACE có thể hoạt động song song, cho phép việc di chuyển các phần phụ thuộc từ tệp WORKSPACE sang Bzlmod theo một quá trình dần dần.

WORKSPACE.bzlmod

Trong quá trình di chuyển, người dùng Bazel có thể cần phải chuyển đổi giữa các bản dựng có và không bật Bzlmod. Triển khai tính năng hỗ trợ WORKSPACE.bzlmod để giúp quá trình chạy mượt mà hơn.

WORKSPACE.bzlmod có cú pháp giống hệt như WORKSPACE. Khi Bzlmod được bật, nếu tệp WORKSPACE.bzlmod cũng tồn tại ở thư mục gốc của không gian làm việc:

  • WORKSPACE.bzlmod có hiệu lực và nội dung của WORKSPACE bị bỏ qua.
  • Không có tiền tố hoặc hậu tố nào được thêm vào tệp WORKSPACE.bzlmod.

Việc sử dụng tệp WORKSPACE.bzlmod có thể giúp quá trình di chuyển trở nên dễ dàng hơn vì:

  • Khi tắt Bzlmod, bạn sẽ quay lại tìm nạp các phần phụ thuộc từ tệp WORKSPACE gốc.
  • Khi bật Bzlmod, bạn có thể dùng WORKSPACE.bzlmod để theo dõi tốt hơn những phần phụ thuộc còn lại cần di chuyển.

Chế độ hiển thị kho lưu trữ

Bzlmod có thể kiểm soát những kho lưu trữ nào khác được hiển thị từ một kho lưu trữ nhất định, hãy kiểm tra tên kho lưu trữ và dep nghiêm ngặt để biết thêm thông tin.

Dưới đây là bản tóm tắt về chức năng của kho lưu trữ qua nhiều loại kho lưu trữ khi xem xét cả WORKSPACE.

Từ kho lưu trữ chính Từ kho lưu trữ mô-đun Bazel Từ kho lưu trữ tiện ích mô-đun Từ kho lưu trữ WORKSPACE
Kho lưu trữ chính Khả năng hiển thị Nếu mô-đun gốc là phần phụ thuộc trực tiếp Nếu mô-đun gốc là phần phụ thuộc trực tiếp của mô-đun lưu trữ tiện ích mô-đun Khả năng hiển thị
Kho lưu trữ mô-đun Bazel Phần phụ thuộc Direct Phần phụ thuộc Direct Phần phụ thuộc trực tiếp của mô-đun lưu trữ tiện ích mô-đun Phần phụ thuộc trực tiếp của mô-đun gốc
Kho lưu trữ tiện ích mô-đun Phần phụ thuộc Direct Phần phụ thuộc Direct Phần phụ thuộc trực tiếp của mô-đun lưu trữ tiện ích mô-đun + tất cả các kho lưu trữ được tạo bởi cùng một tiện ích mô-đun Phần phụ thuộc trực tiếp của mô-đun gốc
Kho lưu trữ WORKSPACE Tất cả đều hiển thị Không hiển thị Không hiển thị Tất cả đều hiển thị
@bar@bar

Quá trình di chuyển

Quy trình di chuyển Bzlmod điển hình có thể có dạng như sau:

  1. Tìm hiểu những phần phụ thuộc bạn có trong WORKSPACE.
  2. Thêm một tệp MODULE.bazel trống vào thư mục gốc của dự án.
  3. Thêm một tệp WORKSPACE.bzlmod trống để ghi đè nội dung của tệp WORKSPACE.
  4. Xây dựng các mục tiêu khi bật Bzlmod và kiểm tra xem kho lưu trữ nào bị thiếu.
  5. Kiểm tra định nghĩa về kho lưu trữ bị thiếu trong tệp phần phụ thuộc đã được phân giải.
  6. Hãy đưa phần phụ thuộc bị thiếu dưới dạng mô-đun Bazel, thông qua một tiện ích mô-đun hoặc để phần phụ thuộc đó trong WORKSPACE.bzlmod để di chuyển sau này.
  7. Quay lại 4 và lặp lại cho đến khi tất cả phần phụ thuộc đều xuất hiện.

Công cụ di chuyển

Bạn có thể bắt đầu sử dụng một tập lệnh trợ giúp di chuyển Bzlmod tương tác.

Tập lệnh thực hiện những việc sau:

  • Tạo và phân tích cú pháp tệp đã giải quyết WORKSPACE.
  • In thông tin kho lưu trữ từ tệp đã phân giải theo cách mà con người có thể đọc được.
  • Chạy lệnh bản dựng bazel, phát hiện các thông báo lỗi được nhận dạng và đề xuất cách di chuyển.
  • Kiểm tra xem phần phụ thuộc đã có trong BCR hay chưa.
  • Thêm phần phụ thuộc vào tệp MODULE.bazel.
  • Thêm phần phụ thuộc thông qua tiện ích mô-đun.
  • Thêm phần phụ thuộc vào tệp WORKSPACE.bzlmod.

Để sử dụng công cụ này, hãy đảm bảo bạn đã cài đặt bản phát hành Bazel mới nhất và chạy lệnh sau:

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>

Xuất bản các mô-đun Bazel

Nếu dự án Bazel của bạn là phần phụ thuộc của các dự án khác, thì bạn có thể xuất bản dự án trong Bazel Central Registry (Sổ đăng ký trung tâm Bazel).

Để có thể kiểm tra dự án trong BCR, bạn cần có một URL lưu trữ nguồn của dự án. Hãy lưu ý một số điều khi tạo bản lưu trữ nguồn:

  • Đảm bảo tệp lưu trữ trỏ đến một phiên bản cụ thể.

    BCR chỉ có thể chấp nhận các bản lưu trữ nguồn được tạo phiên bản vì Bzlmod cần tiến hành so sánh phiên bản trong quá trình phân giải phần phụ thuộc.

  • Đảm bảo rằng URL lưu trữ ổn định.

    Bazel xác minh nội dung của tệp lưu trữ bằng một giá trị băm, vì vậy, bạn phải đảm bảo giá trị tổng kiểm của tệp đã tải xuống không bao giờ thay đổi. Nếu URL đến từ GitHub, vui lòng tạo và tải một bản lưu trữ bản phát hành lên trang phát hành. GitHub sẽ không đảm bảo tổng kiểm tra các bản lưu trữ nguồn được tạo theo yêu cầu. Tóm lại, URL ở dạng https://github.com/<org>/<repo>/releases/download/... được coi là ổn định trong khi https://github.com/<org>/<repo>/archive/... thì không. Hãy xem GitHub Archive Checksum Outage (Tạm ngừng lưu trữ kiểm tra trong GitHub) để biết thêm thông tin.

  • Đảm bảo cây nguồn tuân theo bố cục của kho lưu trữ ban đầu.

    Trong trường hợp kho lưu trữ của bạn rất lớn và bạn muốn tạo một tệp lưu trữ phân phối với kích thước giảm bằng cách loại bỏ các nguồn không cần thiết, hãy đảm bảo rằng cây nguồn đã loại bỏ là một tập con của cây nguồn ban đầu. Điều này giúp người dùng cuối dễ dàng ghi đè mô-đun sang phiên bản không phát hành bằng archive_overridegit_override.

  • Thêm mô-đun kiểm thử trong một thư mục con để kiểm thử những API phổ biến nhất.

    Mô-đun kiểm thử là một dự án Bazel có tệp WORKSPACE và MODULE.bazel riêng nằm trong một thư mục con của kho lưu trữ nguồn phụ thuộc vào mô-đun thực tế sẽ được xuất bản. Tài liệu này sẽ chứa các ví dụ hoặc một số bài kiểm thử tích hợp đề cập đến các API phổ biến nhất của bạn. Hãy xem mô-đun kiểm thử để tìm hiểu cách thiết lập.

Khi bạn đã có sẵn URL lưu trữ nguồn, hãy làm theo nguyên tắc đóng góp BCR để gửi mô-đun của bạn đến BCR bằng Yêu cầu kéo GitHub.

Bạn nên thiết lập ứng dụng GitHub Xuất bản lên BCR cho kho lưu trữ của mình để tự động hoá quy trình gửi mô-đun đến BCR.

Các phương pháp hay nhất

Phần này trình bày một số phương pháp hay nhất mà bạn nên làm theo để quản lý tốt hơn các phần phụ thuộc bên ngoài.

Phân tách mục tiêu thành nhiều gói để tránh tìm nạp các phần phụ thuộc không cần thiết.

Kiểm tra #12835, trong đó các phần phụ thuộc của nhà phát triển dành cho kiểm thử buộc phải tìm nạp một cách không cần thiết để tạo các mục tiêu không cần đến phần phụ thuộc đó. Thực sự thì đây không phải là Bzlmod cụ thể, nhưng việc làm theo các phương pháp này sẽ giúp bạn dễ dàng chỉ định chính xác các phần phụ thuộc của nhà phát triển.

Chỉ định phần phụ thuộc nhà phát triển

Bạn có thể đặt thuộc tính dev_dependency thành true cho các lệnh bazel_depuse_extension để các lệnh này không truyền đến các dự án phụ thuộc. Là mô-đun gốc, bạn có thể sử dụng cờ --ignore_dev_dependency để xác minh xem các mục tiêu của bạn có còn được xây dựng mà không cần phần phụ thuộc của nhà phát triển hay không.

Tiến trình di chuyển cộng đồng

Bạn có thể kiểm tra Bazel Central Registry (Sổ đăng ký trung tâm Bazel) để tìm hiểu xem các phần phụ thuộc của bạn đã có sẵn hay chưa. Nếu không, vui lòng tham gia cuộc thảo luận này trên GitHub để tán thành hoặc đăng những phần phụ thuộc đang cản trở quá trình di chuyển của bạn.

Báo cáo vấn đề

Vui lòng xem danh sách vấn đề về Bazel GitHub để biết các vấn đề đã biết về Bzlmod. Bạn có thể gửi các vấn đề hoặc yêu cầu về tính năng mới để giúp bỏ chặn quá trình di chuyển!