Bazel mendukung dependensi eksternal, yaitu file sumber (teks dan biner) yang digunakan dalam build yang bukan dari ruang kerja Anda. Misalnya, kumpulan aturan tersebut dapat berupa kumpulan aturan yang dihosting di repo GitHub, artefak Maven, atau direktori di mesin lokal Anda di luar ruang kerja Anda saat ini.
Mulai Bazel 6.0, ada dua cara untuk mengelola dependensi eksternal dengan Bazel:
sistem WORKSPACE
tradisional yang berfokus pada repositori, dan
sistem MODULE.bazel
yang berfokus pada modul lebih baru (dengan nama kode Bzlmod,
dan diaktifkan dengan flag --enable_bzlmod
). Kedua sistem ini dapat digunakan
bersama-sama, tetapi Bzlmod akan mengganti sistem WORKSPACE
dalam rilis Bazel
mendatang. Lihat panduan
migrasi Bzlmod tentang cara{/10.memigrasikan{/10.
bezel<i}
Dokumen ini menjelaskan konsep seputar pengelolaan dependensi eksternal di Bazel, sebelum membahas lebih detail tentang kedua sistem secara berurutan.
Konsep
Repositori
Direktori dengan file WORKSPACE
atau WORKSPACE.bazel
, yang berisi file sumber
yang akan digunakan dalam build Bazel. Sering disingkat menjadi hanya repo.
Repositori utama
Repositori tempat perintah Bazel saat ini dijalankan.
Workspace
Lingkungan yang digunakan bersama oleh semua perintah Bazel berjalan di repositori utama yang sama.
Perhatikan bahwa secara historis, konsep "repositori" dan "ruang kerja" telah digabungkan; istilah "ruang kerja" sering digunakan untuk merujuk ke repositori utama, dan terkadang bahkan digunakan sebagai sinonim dari "repositori".
Nama repositori kanonis
Nama kanonis yang dapat menangani repositori. Dalam konteks ruang kerja, setiap repositori memiliki satu nama kanonis. Target di dalam repositori
yang nama kanonisnya adalah canonical_name
dapat ditangani dengan label
@@canonical_name//pac/kage:target
(perhatikan @
ganda).
Repositori utama selalu memiliki string kosong sebagai nama kanonis.
Nama repositori yang terlihat
Nama repositori dapat ditangani dalam konteks repo tertentu lainnya.
Hal ini dapat dianggap sebagai "nama panggilan" repo: Repo dengan nama kanonis
michael
mungkin memiliki nama jelas mike
dalam konteks repo
alice
, tetapi mungkin memiliki nama jelas mickey
dalam konteks repo
bob
. Dalam hal ini, target di dalam michael
dapat ditangani dengan label
@mike//pac/kage:target
dalam konteks alice
(perhatikan satu @
).
Sebaliknya, hal ini dapat dipahami sebagai pemetaan repositori: setiap repo mempertahankan pemetaan dari "nama repo yang jelas" ke "nama repo kanonis".
Aturan repositori
Skema untuk definisi repositori yang memberi tahu Bazel cara merealisasikan
repositori. Misalnya, hal ini dapat berupa "download arsip zip dari URL tertentu
dan ekstrak", atau "ambil artefak Maven tertentu dan sediakan sebagai
target java_import
", atau cukup dengan "symlink direktori lokal". Setiap repo
ditentukan dengan memanggil aturan repo bersama jumlah argumen yang sesuai.
Lihat Aturan repositori untuk mengetahui informasi lebih lanjut tentang cara menulis aturan repositori Anda sendiri.
Aturan repo yang paling umum sejauh ini adalah
http_archive
, yang mendownload arsip
dari URL dan mengekstraknya, serta
local_repository
, yang membuat symlink ke
direktori lokal yang sudah menjadi repositori Bazel.
Mengambil repositori
Tindakan menyediakan repo di disk lokal dengan menjalankan aturan repo terkait. Repo yang ditentukan dalam ruang kerja tidak tersedia di disk lokal sebelum diambil.
Biasanya, Bazel hanya mengambil repo saat memerlukan sesuatu dari repo tersebut, dan repo belum diambil. Jika repo sudah diambil sebelumnya, Bazel hanya akan mengambilnya kembali jika definisinya telah berubah.
Tata letak direktori
Setelah diambil, repo dapat ditemukan di subdirektori external
di
base output, di bawah nama kanonisnya.
Anda dapat menjalankan perintah berikut untuk melihat konten repo dengan
nama kanonis canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
Mengelola dependensi eksternal dengan Bzlmod
Bzlmod, subsistem dependensi eksternal baru, tidak secara langsung berfungsi dengan definisi repo. Sebagai gantinya, aplikasi ini membuat grafik dependensi dari modul, menjalankan ekstensi di atas grafik, dan menentukan repo sebagaimana mestinya.
Modul Bazel adalah project Bazel yang dapat memiliki beberapa
versi, yang masing-masing memublikasikan metadata tentang modul lain yang menjadi
dependensinya. Modul harus memiliki file MODULE.bazel
di root repo-nya, di samping
file WORKSPACE
. File ini adalah manifes modul, yang mendeklarasikan nama,
versi, daftar dependensi, di antara informasi lainnya. Berikut adalah contoh
dasarnya:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
Modul hanya boleh mencantumkan dependensi langsungnya, yang dicari Bzlmod di
registry Bazel — secara default, Bazel Central Registry. Registry ini menyediakan file MODULE.bazel
dependensi, yang memungkinkan Bazel menemukan seluruh grafik dependensi transitif sebelum melakukan resolusi versi.
Setelah resolusi versi, yaitu satu versi dipilih untuk setiap modul,
Bazel akan kembali berkonsultasi dengan registry untuk mempelajari cara menentukan repo setiap modul
(umumnya, menggunakan http_archive
).
Modul juga dapat menentukan bagian data yang disesuaikan yang disebut tag, yang digunakan oleh ekstensi modul setelah resolusi modul untuk menentukan repositori tambahan. Ekstensi ini memiliki kemampuan yang mirip dengan aturan repo, yang memungkinkannya melakukan tindakan seperti I/O file dan mengirim permintaan jaringan. Di antara hal lainnya, API tersebut memungkinkan Bazel berinteraksi dengan sistem pengelolaan paket lainnya sekaligus mengikuti grafik dependensi yang dibuat dari modul Bazel.
Link eksternal di Bzlmod
- Contoh penggunaan Bzlmod di bazelbuild/contoh
- Perbaikan Dependensi Eksternal Bazel (dokumen desain Bzlmod asli)
- Diskusi BazelCon 2021 di Bzlmod
- Diskusi Hari Komunitas Bazel di Bzlmod
Menentukan repo dengan WORKSPACE
Secara historis, Anda dapat mengelola dependensi eksternal dengan menentukan repositori dalam
file WORKSPACE
(atau WORKSPACE.bazel
). File ini memiliki sintaksis yang mirip dengan
file BUILD
, yang menggunakan aturan repo, bukan aturan build.
Cuplikan berikut adalah contoh untuk menggunakan aturan repo http_archive
dalam
file WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)
Cuplikan menentukan repo yang nama kanonisnya adalah foo
. Dalam sistem WORKSPACE
, secara default, nama kanonis repo juga merupakan nama jelasnya untuk
semua repositori lainnya.
Lihat daftar lengkap fungsi yang tersedia di file WORKSPACE
.
Kekurangan sistem WORKSPACE
Pada tahun-tahun sejak sistem WORKSPACE
diperkenalkan, pengguna telah melaporkan
banyak titik masalah, termasuk:
- Bazel tidak mengevaluasi file
WORKSPACE
dependensi apa pun, sehingga semua dependensi transitif harus ditentukan dalam fileWORKSPACE
di repositori utama, selain dependensi langsung. - Untuk mengatasi hal ini, project telah mengadopsi pola "deps.bzl", dengan
cara menentukan makro yang kemudian menentukan beberapa repo, dan meminta pengguna
untuk memanggil makro ini dalam file
WORKSPACE
.- Hal ini memiliki masalah sendiri: makro tidak dapat
load
file.bzl
lainnya, sehingga project ini harus menentukan dependensi transitifnya dalam makro "dependensi" ini, atau mengatasi masalah ini dengan meminta pengguna memanggil beberapa makro "dependensi" berlapis. - Bazel mengevaluasi file
WORKSPACE
secara berurutan. Selain itu, dependensi ditetapkan menggunakanhttp_archive
dengan URL, tanpa informasi versi apa pun. Artinya, tidak ada cara yang andal untuk melakukan resolusi versi jika terjadi dependensi diamond (A
bergantung padaB
danC
;B
danC
bergantung pada versiD
yang berbeda).
- Hal ini memiliki masalah sendiri: makro tidak dapat
Karena kekurangan pada WORKSPACE, Bzlmod akan menggantikan sistem WORKSPACE lama dalam rilis Bazel mendatang. Baca Panduan migrasi Bzlmod tentang cara bermigrasi ke Bzlmod.