Bazel mendukung dependensi eksternal, file sumber (baik teks maupun biner) yang digunakan dalam build yang bukan dari ruang kerja Anda. Misalnya, mereka bisa berupa kumpulan aturan yang dihosting di repo GitHub, artefak Maven, atau direktori di komputer di luar ruang kerja Anda saat ini.
Pada Bazel 6.0, ada dua cara untuk mengelola dependensi eksternal dengan Bazel:
sistem WORKSPACE
tradisional yang berfokus pada repositori, dan
sistem MODULE.bazel
baru yang berfokus pada modul (dengan nama kode Bzlmod,
dan diaktifkan dengan flag --enable_bzlmod
). Kedua sistem tersebut
dapat digunakan
bersama-sama, tetapi Bzlmod menggantikan
sistem WORKSPACE
di masa depan Bazel
rilis, baca Panduan migrasi Bzlmod untuk mengetahui cara
melakukan migrasi.
Dokumen ini menjelaskan konsep seputar manajemen dependensi eksternal di Bazel, sebelum membahas lebih detail tentang dua sistem secara berurutan.
Konsep
Repositori
Hierarki direktori dengan file penanda batas di root-nya, yang berisi sumber file yang dapat digunakan dalam versi Bazel. Sering dipersingkat menjadi repo.
File penanda batas repo dapat berupa MODULE.bazel
(yang menandakan bahwa repositori ini
mewakili modul Bazel), REPO.bazel
(lihat di bawah), atau di
konteks lama, WORKSPACE
atau WORKSPACE.bazel
. Setiap file penanda batas repo
akan menandakan batas repo; beberapa file semacam itu
dapat beroperasi berdampingan dalam
saat ini.
Repositori utama
Repositori tempat perintah Bazel saat ini dijalankan.
{i>Root<i} dari repositori utama juga dikenal sebagai {i>root <i} root workspace.
Workspace
Lingkungan yang digunakan bersama oleh semua perintah Bazel berjalan di repositori utama yang sama. Ini mencakup repo utama dan kumpulan semua repositori eksternal yang ditentukan.
Perhatikan bahwa secara historis konsep "repositori" dan "workspace" telah bercampur; istilah "ruang kerja" sering digunakan untuk mengacu pada repositori, dan kadang-kadang bahkan digunakan sebagai sinonim dari "repositori".
Nama repositori kanonis
Nama kanonis yang menjadi alamat repositori. Dalam konteks
Workspace, setiap repositori memiliki satu nama kanonis. Target di dalam repo
yang nama kanonisnya adalah canonical_name
dapat dikenali dengan label
@@canonical_name//package:target
(perhatikan @
ganda).
Repositori utama selalu memiliki string kosong sebagai nama kanonis.
Nama repositori yang terlihat
Nama repositori yang 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 oleh label
@mike//package:target
dalam konteks alice
(perhatikan @
tunggal).
Sebaliknya, ini dapat dipahami sebagai pemetaan repositori: setiap repo mempertahankan pemetaan dari "apparent repo name" menjadi "nama repositori kanonis".
Aturan repositori
Skema untuk definisi repositori yang
memberi tahu Bazel cara mewujudkan
repositori resource. Misalnya, dapat berupa "mendownload arsip zip dari URL tertentu
dan mengekstraknya", atau "mengambil artefak Maven tertentu dan menyediakannya sebagai
java_import
target", atau cukup "symlink direktori lokal". Setiap repo
ditentukan dengan memanggil aturan repo dengan jumlah argumen yang sesuai.
Lihat Aturan repositori untuk informasi selengkapnya tentang cara menulis aturan repositori Anda sendiri.
Aturan repo yang paling
umum sejauh ini adalah
http_archive
, yang mendownload arsip
dari URL dan mengekstraknya, dan
local_repository
, yang menghubungkan
direktori lokal yang sudah
menjadi repositori Bazel.
Mengambil repositori
Tindakan untuk menyediakan repo di disk lokal dengan menjalankan repositori repo. Repositori yang ditentukan di ruang kerja tidak tersedia di disk lokal sebelum file tersebut diambil.
Biasanya, Bazel hanya mengambil repo ketika membutuhkan sesuatu dari repo, dan repo belum diambil. Jika repo sudah diambil sebelumnya, Bazel hanya mengambilnya kembali jika definisinya telah berubah.
Perintah fetch
dapat digunakan untuk memulai pra-pengambilan untuk repositori,
target, atau semua repositori yang
diperlukan untuk menjalankan build apa pun. Kemampuan ini
mengaktifkan build offline menggunakan opsi --nofetch
.
Opsi --fetch
berfungsi untuk mengelola akses jaringan. Nilai defaultnya adalah true.
Namun, jika ditetapkan ke false (--nofetch
), perintah ini akan menggunakan semua data
dari dependensi tersebut, dan jika tidak ada, perintah akan menghasilkan
gagal.
Lihat opsi pengambilan untuk informasi selengkapnya informasi tentang mengontrol pengambilan.
Tata letak direktori
Setelah diambil, repo dapat ditemukan di subdirektori external
di
output base, dengan nama kanonisnya.
Anda dapat menjalankan perintah berikut untuk melihat konten repo dengan
nama kanonis canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
File REPO.bazel
File REPO.bazel
digunakan untuk menandai batas paling atas hierarki direktori
yang merupakan repositori. Tidak perlu berisi apa pun untuk berfungsi sebagai repositori
{i>border file<i}; Namun, atribut juga dapat digunakan untuk menentukan beberapa atribut
untuk semua target build di dalam repo.
Sintaksis file REPO.bazel
mirip dengan file BUILD
, hanya saja tidak ada
Pernyataan load
didukung, dan hanya satu fungsi, repo()
, yang
yang tersedia. repo()
menggunakan argumen yang sama dengan package()
fungsi di file BUILD
; sedangkan package()
menentukan atribut umum untuk semua target build di dalam paket, repo()
juga dilakukan untuk semua target build di dalam repo.
Misalnya, Anda dapat menentukan lisensi umum untuk semua target di repo Anda dengan
memiliki file REPO.bazel
berikut:
repo(
default_package_metadata = ["//:my_license"],
)
Mengelola dependensi eksternal dengan Bzlmod
Bzlmod, subsistem dependensi eksternal baru, tidak berfungsi secara langsung dengan repo definisi. Sebagai gantinya, modul ini membuat grafik dependensi dari modul, menjalankan ekstensi di atas grafik, dan menentukan repositori yang sesuai.
Modul Bazel adalah project Bazel yang dapat memiliki beberapa
versi, yang masing-masing memublikasikan metadata tentang modul lain yang
kueri. Modul harus memiliki file MODULE.bazel
di root repo-nya, di samping
File WORKSPACE
. File ini adalah manifes modul, yang mendeklarasikan namanya,
versi, daftar dependensi, di antara informasi lainnya. Berikut ini adalah dasar
contoh:
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
Registry Bazel — secara default, Bazel Central
Registrasi. {i>Registry<i} ini menyediakan
dependensi' MODULE.bazel
, yang memungkinkan Bazel menemukan seluruh
grafik dependensi transitif sebelum menjalankan resolusi versi.
Setelah resolusi versi, di mana satu versi dipilih untuk setiap modul,
Bazel berkonsultasi dengan {i>registry<i} lagi untuk mempelajari cara menentukan repo untuk 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 repo aturan, yang memungkinkan mereka untuk melakukan tindakan seperti I/O file dan jaringan pengirim permintaan. Di antaranya, mereka mengizinkan Bazel untuk berinteraksi dengan paket lain manajemen proyek sekaligus mengikuti grafik dependensi yang dibuat modul.
Link eksternal di Bzlmod
- Contoh penggunaan Bzlmod dalam bazelbuild/contoh
- Perbaikan Dependensi Eksternal Bazel (dokumen desain Bzlmod asli)
- Diskusi BazelCon 2021 di Bzlmod
- Pembicaraan Hari Komunitas Bazel di Bzlmod
Tentukan repositori dengan WORKSPACE
Secara historis, Anda dapat mengelola dependensi eksternal dengan menentukan repositori di
File WORKSPACE
(atau WORKSPACE.bazel
). File ini memiliki
{i>syntax<i} yang mirip dengan
BUILD
, menggunakan aturan repo, bukan aturan build.
Cuplikan berikut adalah contoh penggunaan 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 ini menentukan repo yang nama kanonisnya adalah foo
. Di WORKSPACE
secara default, nama kanonis repo juga merupakan nama jelasnya
semua repositori lainnya.
Lihat daftar lengkap fungsi yang tersedia di
WORKSPACE
file.
Kekurangan sistem WORKSPACE
Pada tahun-tahun sejak sistem WORKSPACE
diperkenalkan, pengguna telah melaporkan
banyak poin masalah, termasuk:
- Bazel tidak mengevaluasi file
WORKSPACE
dari dependensi apa pun, jadi semua dependensi transitif harus ditentukan dalam fileWORKSPACE
dari elemen repo, selain dependensi langsung. - Untuk mengatasi hal ini, proyek telah mengadopsi model "deps.bzl" pola, di mana
mereka menentukan makro yang pada gilirannya mendefinisikan
beberapa repositori, dan meminta pengguna untuk
memanggil makro ini dalam file
WORKSPACE
-nya.- Ini memiliki masalah sendiri: makro tidak dapat
load
file.bzl
lain, jadi proyek ini harus menentukan dependensi transitifnya dalam "dependensi" makro, atau mengatasi masalah ini dengan meminta pengguna memanggil "deps" berlapis makro. - Bazel mengevaluasi file
WORKSPACE
secara berurutan. Selain itu, dependensi ditentukan menggunakanhttp_archive
dengan URL, tanpa elemen informasi versi. Ini berarti bahwa tidak ada cara yang dapat diandalkan untuk melakukan resolusi versi dalam kasus dependensi diamond (A
bergantung padaB
danC
;B
danC
bergantung pada versiD
yang berbeda).
- Ini memiliki masalah sendiri: makro tidak dapat
Karena kekurangan WORKSPACE, Bzlmod akan menggantikan versi lama WORKSPACE dalam rilis Bazel mendatang. Baca Migrasi Bzlmod panduan tentang cara bermigrasi ke Bzlmod.