Bazel dapat bergantung pada target dari project lain. Dependensi dari project disebut dependensi eksternal.
File WORKSPACE
(atau file WORKSPACE.bazel
) di
direktori workspace
memberi tahu Bazel cara
mendapatkan proyek lain sumber. Proyek-proyek lain ini dapat
berisi satu atau beberapa file BUILD
dengan targetnya sendiri. BUILD
file di dalam
proyek utama dapat bergantung pada target eksternal ini dengan menggunakan namanya dari
file WORKSPACE
.
Misalnya, ada dua project pada sebuah sistem:
/
home/
user/
project1/
WORKSPACE
BUILD
srcs/
...
project2/
WORKSPACE
BUILD
my-libs/
Jika project1
ingin bergantung pada target, :foo
, yang ditentukan di
/home/user/project2/BUILD
, dia bisa menentukan bahwa repositori bernama
project2
dapat ditemukan di /home/user/project2
. Kemudian menargetkan di
/home/user/project1/BUILD
dapat bergantung pada @project2//:foo
.
File WORKSPACE
memungkinkan pengguna bergantung pada target dari bagian lain dalam Google Cloud
sistem file atau diunduh dari internet. Sintaksisnya sama dengan BUILD
file, tetapi mengizinkan seperangkat aturan berbeda yang disebut aturan repositori (terkadang
juga dikenal sebagai aturan ruang kerja). Bazel dilengkapi dengan
aturan repositori bawaan dan serangkaian
aturan repositori Starlark yang disematkan.
Pengguna juga dapat menulis aturan repositori kustom
untuk mendapatkan perilaku
yang lebih kompleks.
Jenis dependensi eksternal yang didukung
Beberapa jenis dasar dependensi eksternal dapat digunakan:
- Dependensi pada project Bazel lainnya
- Dependensi pada project non-Bazel
- Dependensi pada paket eksternal
Bergantung pada project Bazel lainnya
Jika ingin menggunakan target dari
proyek Bazel kedua, Anda dapat
penggunaan
local_repository
,
git_repository
atau http_archive
untuk melakukan symlink dari sistem file lokal, mereferensikan repositori git
(masing-masing).
Misalnya, Anda sedang mengerjakan sebuah project, my-project/
, dan ingin
untuk bergantung pada target dari project rekan kerja Anda, coworkers-project/
. Keduanya
proyek menggunakan Bazel, jadi Anda dapat menambahkan proyek rekan kerja Anda
dependensi dan kemudian menggunakan target apa pun yang telah
ditentukan rekan kerja Anda dari Anda sendiri
BUILD file. Anda akan menambahkan kode berikut ke my_project/WORKSPACE
:
local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
)
Jika rekan kerja Anda memiliki target //foo:bar
, project Anda dapat merujuknya sebagai
@coworkers_project//foo:bar
. Nama proyek eksternal harus
nama ruang kerja yang valid.
Bergantung pada project non-Bazel
Aturan yang diawali dengan new_
, seperti
new_local_repository
,
memungkinkan Anda membuat target dari project yang tidak menggunakan Bazel.
Misalnya, Anda sedang mengerjakan sebuah project, my-project/
, dan ingin
bergantung pada project rekan kerja Anda, coworkers-project/
. Milik rekan kerja Anda
project menggunakan make
untuk membangun, tetapi Anda ingin bergantung pada salah satu file .so
yang dihasilkannya. Untuk melakukannya, tambahkan kode berikut ke my_project/WORKSPACE
:
new_local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
build_file = "coworker.BUILD",
)
build_file
menetapkan file BUILD
untuk ditempatkan pada project yang ada, sebagai
contoh:
cc_library(
name = "some-lib",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
Anda kemudian dapat bergantung pada @coworkers_project//:some-lib
dari project
BUILD
file.
Bergantung pada paket eksternal
Artefak dan repositori Maven
Menggunakan kumpulan aturan rules_jvm_external
untuk mendownload artefak dari repositori Maven dan menyediakannya sebagai Java
dependensi.
Mengambil dependensi
Secara default, dependensi eksternal diambil sesuai kebutuhan selama bazel build
. Jika
Anda ingin mengambil dependensi yang diperlukan untuk kumpulan target tertentu, gunakan
bazel fetch
Untuk mengambil semua dependensi eksternal tanpa syarat, gunakan
bazel sync
Karena repositori yang diambil disimpan di basis output, pengambilan
yang terjadi per ruang kerja.
Dependensi bayangan
Jika memungkinkan, sebaiknya miliki satu kebijakan versi di proyek. Ini diperlukan untuk dependensi yang Anda kompilasi dan pada akhirnya dalam biner akhir. Tetapi untuk kasus di mana hal ini tidak benar, Anda dapat dependensi shadow. Pertimbangkan skenario berikut:
project saya/Ruang Kerja
workspace(name = "myproject")
local_repository(
name = "A",
path = "../A",
)
local_repository(
name = "B",
path = "../B",
)
A/Ruang Kerja
workspace(name = "A")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "...",
)
B/Ruang Kerja
workspace(name = "B")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
Kedua dependensi A
dan B
bergantung pada testrunner
, tetapi keduanya bergantung pada
versi berbeda dari testrunner
. Tidak ada alasan bagi
{i>test runner<i} ini untuk
tidak hidup berdampingan secara damai dalam myproject
, namun mereka akan bentrok dengan masing-masing
satu sama lain karena mereka
memiliki nama yang sama. Untuk mendeklarasikan kedua dependensi,
perbarui myproject/WORKSPACE:
workspace(name = "myproject")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner-v1",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "..."
)
http_archive(
name = "testrunner-v2",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
local_repository(
name = "A",
path = "../A",
repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
name = "B",
path = "../B",
repo_mapping = {"@testrunner" : "@testrunner-v2"}
)
Mekanisme ini juga bisa digunakan untuk menggabungkan berlian. Misalnya jika A
dan B
memiliki dependensi yang sama tetapi memanggilnya dengan
nama yang berbeda, dependensi tersebut dapat
bergabung di myproject/WORKSPACE.
Mengganti repositori dari command line
Untuk mengganti repositori yang dideklarasikan dengan repositori lokal dari command line,
gunakan
--override_repository
penanda. Menggunakan flag ini akan mengubah konten repositori eksternal tanpa
mengubah kode sumber.
Misalnya, untuk mengganti @foo
ke direktori lokal /path/to/local/foo
,
teruskan flag --override_repository=foo=/path/to/local/foo
.
Beberapa kasus penggunaan mencakup:
- Masalah proses debug. Misalnya, Anda dapat mengganti repositori
http_archive
ke direktori lokal di mana Anda dapat membuat perubahan dengan lebih mudah. - Vendor. Jika Anda berada di lingkungan di mana Anda tidak dapat melakukan panggilan jaringan, mengganti aturan repositori berbasis jaringan untuk mengarah ke direktori lokal sebagai gantinya.
Menggunakan proxy
Bazel akan mengambil alamat proxy dari HTTPS_PROXY
dan HTTP_PROXY
variabel lingkungan dan gunakan untuk mendownload file HTTP/HTTPS (jika ditentukan).
Dukungan untuk IPv6
Pada komputer yang hanya menggunakan IPv6, Bazel akan dapat
mengunduh dependensi dengan
tidak ada perubahan. Pada mesin dual-stack IPv4/IPv6, Bazel mengikuti cara
sebagai Java: jika IPv4 diaktifkan, IPv4 akan lebih disukai. Dalam beberapa situasi,
misalnya ketika jaringan IPv4 tidak dapat
menyelesaikan/menjangkau alamat eksternal,
hal ini dapat menyebabkan pengecualian Network unreachable
dan kegagalan build.
Dalam kasus ini, Anda dapat mengganti
perilaku Bazel untuk lebih memilih IPv6
menggunakan properti sistem java.net.preferIPv6Addresses=true
.
Khususnya:
Gunakan
--host_jvm_args=-Djava.net.preferIPv6Addresses=true
opsi startup, misalnya dengan menambahkan baris berikut ke File.bazelrc
:startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true
Jika Anda menjalankan target build Java yang perlu terhubung ke internet pengujian integrasi terkadang juga diperlukan), gunakan juga
--jvmopt=-Djava.net.preferIPv6Addresses=true
flag alat, misalnya dengan memiliki baris berikut di file.bazelrc
Anda:build --jvmopt=-Djava.net.preferIPv6Addresses
Jika Anda menggunakan rules_jvm_external, misalnya, untuk resolusi versi dependensi, tambahkan juga
-Djava.net.preferIPv6Addresses=true
menujuCOURSIER_OPTS
variabel lingkungan untuk menyediakan opsi JVM bagi Coursier
Dependensi transitif
Bazel hanya membaca dependensi yang tercantum dalam file WORKSPACE
Anda. Jika proyek Anda
(A
) bergantung pada project lain (B
) yang mencantumkan dependensi pada project
project (C
) dalam file WORKSPACE
-nya, Anda harus menambahkan B
dan C
ke file WORKSPACE
project Anda. Persyaratan ini dapat menggelembungkan
Ukuran file WORKSPACE
, tetapi membatasi kemungkinan memiliki satu library
menyertakan C
di versi 1.0 dan lainnya menyertakan C
pada versi 2.0.
Menyimpan cache dependensi eksternal
Secara {i>default<i}, Bazel hanya akan
mengunduh ulang dependensi eksternal jika
perubahan definisi. Perubahan pada file yang dirujuk dalam definisi (seperti patch
atau file BUILD
) juga dipertimbangkan oleh bazel.
Untuk memaksa download ulang, gunakan bazel sync
.
Tata Letak
Dependensi eksternal semuanya didownload ke direktori di bawah subdirektori
external
dalam base output. Dalam kasus
repositori lokal, symlink akan dibuat
di sana daripada membuat direktori baru.
Anda dapat melihat direktori external
dengan menjalankan:
ls $(bazel info output_base)/external
Perlu diketahui bahwa menjalankan bazel clean
tidak akan benar-benar menghapus
saat ini. Untuk menghapus semua artefak eksternal, gunakan bazel clean --expunge
.
Build offline
Terkadang, Anda perlu atau perlu menjalankan build secara offline. Sebagai
kasus penggunaan sederhana, seperti bepergian di pesawat,
prefetching yang diperlukan
repositori dengan bazel fetch
atau bazel sync
sudah cukup; selain itu,
menggunakan opsi --nofetch
, pengambilan repositori lebih lanjut dapat dinonaktifkan
selama proses build.
Untuk build offline yang sebenarnya, tempat penyediaan file yang diperlukan harus dilakukan
oleh entitas yang berbeda dari bazel, bazel mendukung opsi
--distdir
. Setiap kali aturan repositori meminta
bazel untuk mengambil file melalui
ctx.download
atau
ctx.download_and_extract
dan memberikan jumlah hash dari file
diperlukan, bazel akan melihat terlebih dahulu direktori
yang ditentukan oleh opsi itu untuk
file yang cocok dengan nama dasar URL pertama yang diberikan, dan gunakan salinan lokal tersebut
jika {i>hash <i}itu cocok.
Bazel sendiri menggunakan teknik ini untuk melakukan bootstrap secara offline dari distribusi
artefak.
Hal ini dilakukan dengan mengumpulkan semua kebutuhan eksternal
dependensi
dalam
distdir_tar
Namun, bazel memungkinkan eksekusi perintah arbitrer dalam aturan repositori, tanpa mengetahui apakah mereka terhubung ke jaringan. Oleh karena itu, bazel tidak memiliki opsi untuk menerapkan build yang sepenuhnya offline. Jadi menguji apakah build berfungsi dengan benar secara offline memerlukan pemblokiran jaringan eksternal, seperti yang dilakukan bazel pengujian bootstrap.
Praktik terbaik
Aturan repositori
Aturan repositori umumnya harus bertanggung jawab untuk:
- Mendeteksi setelan sistem dan menulisnya ke file.
- Mencari resource di tempat lain pada sistem.
- Mendownload resource dari URL.
- Membuat atau membuat symlink file BUILD ke direktori repositori eksternal.
Hindari penggunaan repository_ctx.execute
jika memungkinkan. Misalnya, saat menggunakan C++ non-Bazel
library yang memiliki build menggunakan Make, sebaiknya gunakan repository_ctx.download()
lalu
menulis file BUILD yang membangunnya, alih-alih menjalankan ctx.execute(["make"])
.
Lebih suka http_archive
ke git_repository
dan
new_git_repository
. Alasannya adalah:
- Aturan repositori Git bergantung pada
git(1)
sistem, sedangkan downloader HTTP dibangun ke dalam Bazel dan tidak memiliki dependensi sistem. http_archive
mendukung daftarurls
sebagai duplikat, dangit_repository
hanya mendukung saturemote
.http_archive
berfungsi dengan cache repositori, tetapi tidakgit_repository
. Lihat #5116 untuk informasi selengkapnya.
Jangan gunakan bind()
. Lihat "Pertimbangkan menghapus
pengikatan" untuk waktu yang lama
diskusi tentang isu dan alternatifnya.