Panduan Migrasi Bzlmod

Laporkan masalah Lihat sumber Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Karena kekurangan WORKSPACE, Bzlmod menggantikan sistem WORKSPACE lama. File WORKSPACE sudah dinonaktifkan di Bazel 8 (akhir 2024) dan akan dihapus di Bazel 9 (akhir 2025). Panduan ini membantu Anda memigrasikan project ke Bzlmod dan menghapus WORKSPACE untuk mengelola dependensi eksternal.

Mengapa bermigrasi ke Bzlmod?

  • Ada banyak keuntungan dibandingkan dengan sistem WORKSPACE lama, yang membantu memastikan pertumbuhan ekosistem Bazel yang sehat.

  • Jika project Anda adalah dependensi project lain, migrasi ke Bzlmod akan memperlancar migrasi mereka dan memudahkan mereka bergantung pada project Anda.

  • Migrasi ke Bzlmod adalah langkah yang diperlukan untuk menggunakan versi Bazel mendatang (wajib di Bazel 9).

Bagaimana cara bermigrasi ke Bzlmod?

Proses migrasi yang direkomendasikan:

  1. Gunakan alat migrasi sebagai alat bantu untuk menyederhanakan proses migrasi sebanyak mungkin. Periksa bagian alat migrasi dan cara menggunakan alat.
  2. Jika masih ada error setelah menggunakan alat migrasi, selesaikan error tersebut secara manual. Untuk memahami perbedaan utama antara konsep di dalam file WORKSPACE dan MODULE.bazel, lihat bagian WORKSPACE versus Bzlmod.

Alat migrasi

Untuk menyederhanakan proses yang sering kali rumit dalam berpindah dari WORKSPACE ke Bzlmod, sebaiknya gunakan skrip migrasi. Alat bantu ini mengotomatiskan banyak langkah yang terlibat dalam memigrasikan sistem pengelolaan dependensi eksternal Anda.

Fungsi Inti

Fungsi utama skrip adalah:

  • Pengumpulan Informasi Dependensi: Menganalisis file WORKSPACE project Anda untuk mengidentifikasi repositori eksternal yang digunakan oleh target build tertentu. Tindakan ini menggunakan flag experimental_repository_resolved_file Bazel untuk membuat file resolved_deps.py yang berisi informasi ini.
  • Identifikasi Dependensi Langsung: Menggunakan bazel query untuk menentukan repositori mana yang merupakan dependensi langsung untuk target yang ditentukan.
  • Migrasi Bzlmod: Menerjemahkan dependensi WORKSPACE yang relevan ke padanannya di Bzlmod. Proses ini terdiri dari dua langkah:
    1. Mencoba memperkenalkan semua dependensi langsung yang diidentifikasi ke file MODULE.bazel.
    2. Mencoba membangun target yang ditentukan dengan Bzlmod diaktifkan, lalu mengidentifikasi dan memperbaiki error yang dapat dikenali secara berulang. Langkah ini diperlukan karena beberapa dependensi mungkin tidak ada di langkah pertama.
  • Pembuatan Laporan Migrasi: Membuat file migration_info.md yang mendokumentasikan proses migrasi. Laporan ini mencakup daftar dependensi langsung, deklarasi Bzlmod yang dihasilkan, dan langkah-langkah manual yang mungkin diperlukan untuk menyelesaikan migrasi.

Alat migrasi mendukung:

  • Dependensi yang tersedia di Bazel Central Registry
  • Aturan repositori kustom yang ditentukan pengguna
  • [Segera hadir] Dependensi pengelola paket

Catatan Penting: Alat migrasi adalah utilitas yang diupayakan sebaik mungkin. Selalu periksa ulang rekomendasi Gemini untuk memastikan kebenarannya.

Cara Menggunakan Alat Migrasi

Sebelum memulai:

  • Lakukan upgrade ke rilis Bazel 7 terbaru, yang memberikan dukungan yang andal untuk WORKSPACE dan Bzlmod.
  • Verifikasi bahwa perintah berikut berhasil dijalankan untuk target build utama project Anda:

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

Setelah prasyarat terpenuhi, jalankan perintah berikut untuk menggunakan alat migrasi:

# 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 vs. Bzlmod

WORKSPACE dan Bzlmod Bazel menawarkan fitur serupa dengan sintaksis yang berbeda. Bagian ini menjelaskan cara melakukan migrasi dari fungsi WORKSPACE tertentu ke Bzlmod.

Menentukan root ruang kerja Bazel

File WORKSPACE menandai root sumber project Bazel, tanggung jawab ini digantikan oleh MODULE.bazel di Bazel versi 6.3 dan yang lebih baru. Dengan versi Bazel sebelum 6.3, masih ada file WORKSPACE atau WORKSPACE.bazel di root ruang kerja Anda, mungkin dengan komentar seperti:

  • WORKSPACE

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

Aktifkan Bzlmod di bazelrc Anda

.bazelrc memungkinkan Anda menetapkan tanda yang berlaku setiap kali Anda menjalankan Bazel. Untuk mengaktifkan Bzlmod, gunakan flag --enable_bzlmod, dan terapkan ke perintah common agar dapat diterapkan ke setiap perintah:

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

Menentukan nama repositori untuk ruang kerja Anda

  • WORKSPACE

    Fungsi workspace digunakan untuk menentukan nama repositori untuk ruang kerja Anda. Hal ini memungkinkan //foo:bar target di ruang kerja dirujuk sebagai @<workspace name>//foo:bar. Jika tidak ditentukan, nama repositori default untuk ruang kerja Anda adalah __main__.

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

    Sebaiknya rujuk target di ruang kerja yang sama dengan sintaksis //foo:bar tanpa @<repo name>. Namun, jika Anda memerlukan sintaksis lama, Anda dapat menggunakan nama modul yang ditentukan oleh fungsi module sebagai nama repositori. Jika nama modul berbeda dengan nama repositori yang diperlukan, Anda dapat menggunakan atribut repo_name dari fungsi module untuk mengganti nama repositori.

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

Mengambil dependensi eksternal sebagai modul Bazel

Jika dependensi Anda adalah project Bazel, Anda dapat menggunakannya sebagai modul Bazel jika project tersebut juga mengadopsi Bzlmod.

  • WORKSPACE

    Dengan WORKSPACE, aturan repositori http_archive atau git_repository biasanya digunakan untuk mendownload sumber project 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()
    

    Seperti yang dapat Anda lihat, pengguna sering kali perlu memuat dependensi transitif dari makro dependensi. Asumsikan bazel_skylib dan rules_java bergantung pada platform, versi persis dari dependensi platform ditentukan oleh urutan makro.

  • Bzlmod

    Dengan Bzlmod, selama dependensi Anda tersedia di Bazel Central Registry atau registry Bazel kustom, Anda dapat bergantung padanya hanya dengan direktif bazel_dep.

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

    Bzlmod menyelesaikan dependensi modul Bazel secara transitif menggunakan algoritma MVS. Oleh karena itu, versi maksimal yang diperlukan untuk platform akan dipilih secara otomatis.

Mengganti dependensi sebagai modul Bazel

Sebagai modul root, Anda dapat mengganti dependensi modul Bazel dengan berbagai cara.

Baca bagian penggantian untuk mengetahui informasi selengkapnya.

Anda dapat menemukan beberapa contoh penggunaan di repositori examples.

Mengambil dependensi eksternal dengan ekstensi modul

Jika dependensi Anda bukan project Bazel atau belum tersedia di registry Bazel mana pun, Anda dapat memperkenalkannya menggunakan use_repo_rule atau ekstensi modul.

  • WORKSPACE

    Download file menggunakan aturan repositori 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

    Dengan Bzlmod, Anda dapat menggunakan direktif use_repo_rule dalam file MODULE.bazel untuk membuat instance repositori secara langsung:

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

    Di balik layar, hal ini diimplementasikan menggunakan ekstensi modul. Jika perlu melakukan logika yang lebih kompleks daripada sekadar memanggil aturan repo, Anda juga dapat menerapkan ekstensi modul sendiri. Anda harus memindahkan definisi ke dalam file .bzl, yang juga memungkinkan Anda membagikan definisi antara WORKSPACE dan Bzlmod selama periode migrasi.

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

    Terapkan ekstensi modul untuk memuat makro dependensi. Anda dapat menentukannya dalam file .bzl yang sama dengan makro, tetapi untuk menjaga kompatibilitas dengan versi Bazel yang lebih lama, sebaiknya tentukan dalam file .bzl terpisah.

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

    Agar repositori dapat dilihat oleh project root, Anda harus mendeklarasikan penggunaan ekstensi modul dan repositori dalam file MODULE.bazel.

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

Menyelesaikan konflik dependensi eksternal dengan ekstensi modul

Project dapat menyediakan makro yang memperkenalkan repositori eksternal berdasarkan input dari pemanggilnya. Namun, bagaimana jika ada beberapa pemanggil dalam grafik dependensi dan mereka menyebabkan konflik?

Anggap project foo menyediakan makro berikut yang menggunakan version sebagai argumen.

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

    Dengan WORKSPACE, Anda dapat memuat makro dari @foo dan menentukan versi dependensi data yang Anda butuhkan. Asumsikan Anda memiliki dependensi lain @bar, yang juga bergantung pada @foo, tetapi memerlukan versi dependensi data yang berbeda.

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

    Dalam hal ini, pengguna akhir harus menyesuaikan urutan makro dengan cermat di WORKSPACE untuk mendapatkan versi yang mereka butuhkan. Ini adalah salah satu titik masalah terbesar dengan WORKSPACE karena tidak benar-benar menyediakan cara yang masuk akal untuk menyelesaikan dependensi.

  • Bzlmod

    Dengan Bzlmod, penulis project foo dapat menggunakan ekstensi modul untuk menyelesaikan konflik. Misalnya, asumsikan bahwa selalu memilih versi maksimal yang diperlukan dari dependensi data di antara semua modul Bazel adalah hal yang masuk akal.

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

    Dalam hal ini, modul root memerlukan versi data 2.0, sedangkan dependensinya bar memerlukan 3.0. Ekstensi modul di foo dapat menyelesaikan konflik ini dengan benar dan memilih versi 3.0 secara otomatis untuk dependensi data.

Mengintegrasikan pengelola paket pihak ketiga

Setelah bagian terakhir, karena ekstensi modul menyediakan cara untuk mengumpulkan informasi dari grafik dependensi, lakukan logika kustom untuk menyelesaikan dependensi dan panggil aturan repositori untuk memperkenalkan repositori eksternal, hal ini memberikan cara yang bagus bagi penulis aturan untuk meningkatkan kualitas kumpulan aturan yang mengintegrasikan pengelola paket untuk bahasa tertentu.

Baca halaman ekstensi modul untuk mempelajari lebih lanjut cara menggunakan ekstensi modul.

Berikut adalah daftar set aturan yang telah mengadopsi Bzlmod untuk mengambil dependensi dari pengelola paket yang berbeda:

Contoh minimal yang mengintegrasikan pengelola paket pseudo tersedia di repositori examples.

Mendeteksi toolchain di mesin host

Saat aturan build Bazel perlu mendeteksi toolchain yang tersedia di mesin host Anda, aturan tersebut menggunakan aturan repositori untuk memeriksa mesin host dan membuat info toolchain sebagai repositori eksternal.

  • WORKSPACE

    Mengingat aturan repositori berikut untuk mendeteksi 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,
    )
    

    Anda dapat memuat aturan repositori di WORKSPACE.

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

    Dengan Bzlmod, Anda dapat memperkenalkan repositori yang sama menggunakan ekstensi modul, yang mirip dengan memperkenalkan repositori @data_file di bagian terakhir.

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

    Kemudian, gunakan ekstensi di file 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")
    

Mendaftarkan toolchain & platform eksekusi

Setelah bagian terakhir, setelah memperkenalkan informasi toolchain hosting repositori (misalnya, local_config_sh), Anda mungkin ingin mendaftarkan toolchain.

  • WORKSPACE

    Dengan WORKSPACE, Anda dapat mendaftarkan toolchain dengan cara berikut.

    1. Anda dapat mendaftarkan toolchain file .bzl dan memuat makro dalam file 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. Atau, daftarkan toolchain langsung di file 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

    Dengan Bzlmod, API register_toolchains dan register_execution_platforms hanya tersedia di file MODULE.bazel. Anda tidak dapat memanggil native.register_toolchains dalam ekstensi modul.

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

Rangkaian alat dan platform eksekusi yang terdaftar di WORKSPACE, WORKSPACE.bzlmod dan file MODULE.bazel setiap modul Bazel mengikuti urutan prioritas ini selama pemilihan rangkaian alat (dari tertinggi hingga terendah):

  1. toolchain dan platform eksekusi yang terdaftar dalam file MODULE.bazel modul root.
  2. toolchain dan platform eksekusi yang terdaftar dalam file WORKSPACE atau WORKSPACE.bzlmod.
  3. toolchain dan platform eksekusi yang didaftarkan oleh modul yang merupakan dependensi (transitif) modul root.
  4. jika tidak menggunakan WORKSPACE.bzlmod: toolchain yang terdaftar dalam akhiran WORKSPACE.

Memperkenalkan repositori lokal

Anda mungkin perlu memperkenalkan dependensi sebagai repositori lokal saat Anda memerlukan versi lokal dependensi untuk proses debug atau Anda ingin menggabungkan direktori di ruang kerja Anda sebagai repositori eksternal.

  • WORKSPACE

    Dengan WORKSPACE, hal ini dicapai oleh dua aturan repositori native, local_repository dan new_local_repository.

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

    Dengan Bzlmod, Anda dapat menggunakan local_path_override untuk mengganti modul dengan jalur lokal.

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

    Anda juga dapat memperkenalkan repositori lokal dengan ekstensi modul. Namun, Anda tidak dapat memanggil native.local_repository di ekstensi modul, ada upaya berkelanjutan untuk men-starlark-kan semua aturan repositori native (lihat #18285 untuk mengetahui progresnya). Kemudian, Anda dapat memanggil local_repository starlark yang sesuai dalam ekstensi modul. Anda juga dapat menerapkan versi kustom aturan repositori local_repository dengan mudah jika hal ini menjadi masalah yang menghambat Anda.

Target pengikatan

Aturan bind di WORKSPACE tidak digunakan lagi dan tidak didukung di Bzlmod. Fitur ini diperkenalkan untuk memberikan alias target dalam paket //external khusus. Semua pengguna yang bergantung pada ini harus bermigrasi.

Misalnya, Anda memiliki

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

Hal ini memungkinkan target lain bergantung pada //external:openssl. Anda dapat beralih dari paket ini dengan:

  • Ganti semua penggunaan //external:openssl dengan @my-ssl//src:openssl-lib.

    • Tips: Gunakan perintah bazel query --output=build --noenable_bzlmod --enable_workspace [target] untuk menemukan info yang relevan tentang target.
  • Atau gunakan aturan build alias

    • Tentukan target berikut dalam paket (misalnya, //third_party)

      ## third_party/BUILD
      alias(
          name = "openssl",
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • Ganti semua penggunaan //external:openssl dengan //third_party:openssl.

Pengambilan versus Sinkronisasi

Perintah pengambilan dan sinkronisasi digunakan untuk mendownload repo eksternal secara lokal dan terus memperbaruinya. Terkadang juga untuk memungkinkan pembuatan offline menggunakan flag --nofetch setelah mengambil semua repo yang diperlukan untuk build.

  • WORKSPACE

    Sinkronisasi melakukan pengambilan paksa untuk semua repositori, atau untuk serangkaian repositori yang dikonfigurasi tertentu, sementara pengambilan hanya digunakan untuk mengambil target tertentu.

  • Bzlmod

    Perintah sinkronisasi tidak lagi berlaku, tetapi pengambilan menawarkan berbagai opsi. Anda dapat mengambil target, repositori, serangkaian repositori yang dikonfigurasi, atau semua repositori yang terlibat dalam penyelesaian dependensi dan ekstensi modul Anda. Hasil pengambilan di-cache dan untuk memaksa pengambilan, Anda harus menyertakan opsi --force selama proses pengambilan.

Migrasi manual

Bagian ini memberikan informasi dan panduan yang berguna untuk proses migrasi Bzlmod manual Anda. Untuk proses migrasi yang lebih otomatis, lihat bagian proses migrasi yang direkomendasikan.

Mengenali dependensi Anda di WORKSPACE

Langkah pertama migrasi adalah memahami dependensi yang Anda miliki. Mungkin sulit untuk mengetahui dependensi persis yang diperkenalkan dalam file WORKSPACE karena dependensi transitif sering dimuat dengan makro *_deps.

Memeriksa dependensi eksternal dengan file yang diselesaikan ruang kerja

Untungnya, tanda --experimental_repository_resolved_file dapat membantu. Flag ini pada dasarnya menghasilkan "file kunci" dari semua dependensi eksternal yang diambil dalam perintah Bazel terakhir Anda. Anda dapat menemukan detail selengkapnya di postingan blog ini.

Kolom ini dapat digunakan dengan dua cara:

  1. Untuk mengambil info dependensi eksternal yang diperlukan untuk membangun target tertentu.

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. Untuk mengambil info semua dependensi eksternal yang ditentukan dalam file WORKSPACE.

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

    Dengan perintah bazel sync, Anda dapat mengambil semua dependensi yang ditentukan dalam file WORKSPACE, yang mencakup:

    • Penggunaan bind
    • Penggunaan register_toolchains & register_execution_platforms

    Namun, jika project Anda lintas platform, sinkronisasi bazel mungkin rusak di platform tertentu karena beberapa aturan repositori hanya dapat berjalan dengan benar di platform yang didukung.

Setelah menjalankan perintah, Anda akan memiliki informasi dependensi eksternal dalam file resolved.bzl.

Memeriksa dependensi eksternal dengan bazel query

Anda mungkin juga tahu bahwa bazel query dapat digunakan untuk memeriksa aturan repositori dengan

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

Meskipun lebih nyaman dan jauh lebih cepat, kueri bazel dapat memberikan informasi yang salah tentang versi dependensi eksternal, jadi berhati-hatilah saat menggunakannya. Mengirim kueri dan memeriksa dependensi eksternal dengan Bzlmod akan dilakukan dengan subperintah baru.

Dependensi default bawaan

Jika Anda memeriksa file yang dihasilkan oleh --experimental_repository_resolved_file, Anda akan menemukan banyak dependensi yang tidak ditentukan di WORKSPACE Anda. Hal ini karena Bazel sebenarnya menambahkan awalan dan akhiran ke konten file WORKSPACE pengguna untuk menyuntikkan beberapa dependensi default, yang biasanya diperlukan oleh aturan native (misalnya @bazel_tools, @platforms, dan @remote_java_tools). Dengan Bzlmod, dependensi tersebut diperkenalkan dengan modul bawaan bazel_tools, yang merupakan dependensi default untuk setiap modul Bazel lainnya.

Mode hybrid untuk migrasi bertahap

Bzlmod dan WORKSPACE dapat bekerja secara berdampingan, sehingga memungkinkan migrasi dependensi dari file WORKSPACE ke Bzlmod menjadi proses bertahap.

WORKSPACE.bzlmod

Selama migrasi, pengguna Bazel mungkin perlu beralih di antara build dengan dan tanpa Bzlmod diaktifkan. Dukungan WORKSPACE.bzlmod diterapkan untuk membuat proses lebih lancar.

WORKSPACE.bzlmod memiliki sintaksis yang sama persis dengan WORKSPACE. Jika Bzlmod diaktifkan, dan file WORKSPACE.bzlmod juga ada di root ruang kerja:

  • WORKSPACE.bzlmod berlaku dan konten WORKSPACE diabaikan.
  • Tidak ada awalan atau akhiran yang ditambahkan ke file WORKSPACE.bzlmod.

Menggunakan file WORKSPACE.bzlmod dapat mempermudah migrasi karena:

  • Jika Bzlmod dinonaktifkan, Anda akan kembali mengambil dependensi dari file WORKSPACE asli.
  • Jika Bzlmod diaktifkan, Anda dapat melacak dengan lebih baik dependensi yang tersisa untuk dimigrasikan dengan WORKSPACE.bzlmod.

Visibilitas repositori

Bzlmod dapat mengontrol repositori lain yang terlihat dari repositori tertentu, lihat nama repositori dan deps ketat untuk mengetahui detail selengkapnya.

Berikut ringkasan visibilitas repositori dari berbagai jenis repositori dengan mempertimbangkan RUANG KERJA.

Dari repo utama Dari repositori modul Bazel Dari repositori ekstensi modul Dari repositori WORKSPACE
Repositori utama Terlihat Jika modul root adalah dependensi langsung Jika modul root adalah dependensi langsung dari modul yang menghosting ekstensi modul Terlihat
Repositori modul Bazel Dependensi langsung Dependensi langsung Dependensi langsung modul yang menghosting ekstensi modul Dependensi langsung modul root
Repositori ekstensi modul Dependensi langsung Dependensi langsung Dependensi langsung modul yang menghosting ekstensi modul + semua repositori yang dihasilkan oleh ekstensi modul yang sama Dependensi langsung modul root
Repositori WORKSPACE Semua terlihat Tidak terlihat Tidak terlihat Semua terlihat

Proses migrasi manual

Proses migrasi Bzlmod standar dapat terlihat seperti ini:

  1. Pahami dependensi yang Anda miliki di RUANG KERJA.
  2. Tambahkan file MODULE.bazel kosong di root project Anda.
  3. Tambahkan file WORKSPACE.bzlmod kosong untuk mengganti konten file WORKSPACE.
  4. Bangun target Anda dengan Bzlmod yang diaktifkan dan periksa repositori mana yang tidak ada.
  5. Periksa definisi repositori yang hilang di file dependensi yang diselesaikan.
  6. Perkenalkan dependensi yang tidak ada sebagai modul Bazel, melalui ekstensi modul, atau biarkan di WORKSPACE.bzlmod untuk migrasi nanti.
  7. Kembali ke 4 dan ulangi hingga semua dependensi tersedia.

Memublikasikan modul Bazel

Jika project Bazel Anda adalah dependensi untuk project lain, Anda dapat memublikasikan project di Bazel Central Registry.

Agar dapat mendaftarkan project di BCR, Anda memerlukan URL arsip sumber project. Perhatikan beberapa hal saat membuat arsip sumber:

  • Pastikan arsip mengarah ke versi tertentu.

    BCR hanya dapat menerima arsip sumber yang diberi versi karena Bzlmod perlu melakukan perbandingan versi selama penyelesaian dependensi.

  • Pastikan URL arsip stabil.

    Bazel memverifikasi konten arsip dengan nilai hash, jadi Anda harus memastikan checksum file yang didownload tidak pernah berubah. Jika URL berasal dari GitHub, buat dan upload arsip rilis di halaman rilis. GitHub tidak akan menjamin checksum arsip sumber yang dibuat sesuai permintaan. Singkatnya, URL dalam bentuk https://github.com/<org>/<repo>/releases/download/... dianggap stabil sedangkan https://github.com/<org>/<repo>/archive/... tidak. Lihat GitHub Checksum Arsip Gangguan untuk mengetahui konteks selengkapnya.

  • Pastikan hierarki sumber mengikuti tata letak repositori asli.

    Jika repositori Anda sangat besar dan Anda ingin membuat arsip distribusi dengan ukuran yang lebih kecil dengan menghapus sumber yang tidak diperlukan, pastikan pohon sumber yang dihapus adalah subset dari pohon sumber asli. Hal ini memudahkan pengguna akhir mengganti modul ke versi non-rilis dengan archive_override dan git_override.

  • Sertakan modul pengujian di subdirektori yang menguji API paling umum Anda.

    Modul pengujian adalah project Bazel dengan file WORKSPACE dan MODULE.bazel sendiri yang terletak di subdirektori arsip sumber yang bergantung pada modul sebenarnya yang akan dipublikasikan. File ini harus berisi contoh atau beberapa pengujian integrasi yang mencakup API paling umum Anda. Periksa modul pengujian untuk mempelajari cara menyiapkannya.

Setelah URL arsip sumber Anda siap, ikuti pedoman kontribusi BCR untuk mengirimkan modul Anda ke BCR dengan Permintaan Tarik GitHub.

Sangat direkomendasikan untuk menyiapkan Aplikasi GitHub Publish to BCR untuk repositori Anda guna mengotomatiskan proses pengiriman modul ke BCR.

Praktik terbaik

Bagian ini mendokumentasikan beberapa praktik terbaik yang harus Anda ikuti untuk mengelola dependensi eksternal dengan lebih baik.

Bagi target menjadi paket yang berbeda untuk menghindari pengambilan dependensi yang tidak perlu.

Periksa #12835, tempat dependensi pengembangan untuk pengujian dipaksa untuk diambil secara tidak perlu untuk membangun target yang tidak memerlukannya. Sebenarnya ini tidak khusus untuk Bzlmod, tetapi mengikuti praktik ini akan mempermudah penentuan dependensi pengembangan dengan benar.

Menentukan dependensi dev

Anda dapat menyetel atribut dev_dependency ke benar (true) untuk bazel_dep dan use_extension sehingga tidak disebarkan ke project dependen. Sebagai modul root, Anda dapat menggunakan flag --ignore_dev_dependency untuk memverifikasi apakah target Anda masih di-build tanpa dependensi dan penggantian dev.

Progres migrasi komunitas

Anda dapat memeriksa Bazel Central Registry untuk mengetahui apakah dependensi Anda sudah tersedia. Atau, Anda dapat bergabung dalam diskusi GitHub ini untuk memberikan suara positif atau memposting dependensi yang menghalangi migrasi Anda.

Laporkan masalah

Lihat daftar masalah GitHub Bazel untuk mengetahui masalah Bzlmod yang diketahui. Jangan ragu untuk mengajukan masalah baru atau permintaan fitur yang dapat membantu memperlancar migrasi Anda.