kargo-raze saat ini merupakan produk yang tidak dirawat dan tidak didukung .
crate_universe
di rules_rust
adalah produk yang didukung dan dipelihara dengan tujuan serupa.
Kami yakin crate_universe
mendukung semua fungsi yang didukung oleh cargo-raze. Kami mendorong Anda untuk mencoba bermigrasi ke sana. Jika Anda menemukan dukungan yang hilang, atau bug, harap ajukan masalah atau PR terhadap rules_rust
.
cargo-raze
telah diarsipkan untuk mencerminkan kenyataan bahwa PR dan permasalahan yang diajukan terhadap hal tersebut kemungkinan besar tidak akan ditangani.
Silakan hubungi #rust di Bazel Slack jika Anda tertarik untuk mengambil alih pemeliharaan proyek ini.
Plugin Cargo dukungan eksperimental untuk menyaring Cargo.toml tingkat ruang kerja menjadi target BUILD yang dapat diandalkan secara langsung oleh kode yang menggunakan rule_rust.
Ini bukan produk resmi Google (eksperimental atau lainnya), ini hanya kode yang dimiliki oleh Google.
Proyek ini mensintesis logika resolusi ketergantungan dan beberapa fungsi Cargo seperti fitur dan skrip build menjadi aturan yang dapat dieksekusi yang dapat dijalankan Bazel untuk mengkompilasi peti Rust. Meskipun aturan rule_rust standar dapat digunakan untuk mengkompilasi kode Rust dari awal, granularitas ekosistem ketergantungan yang baik membuat transformasi pohon ketergantungan berdasarkan ekosistem tersebut menjadi sulit, bahkan untuk kode dengan sedikit ketergantungan.
pengrusakan kargo dapat menghasilkan target yang dapat dibangun dalam salah satu dari dua mode: Vendoring, atau Non-Vendoring. Dalam mode vendoring, pengembang menggunakan subperintah cargo vendor
umum untuk mengambil dependensi yang ditunjukkan oleh ruang kerja mereka Cargo.toml ke dalam direktori yang kemudian diisi dengan file BUILD. Dalam mode non-vendoring, cargo-raze menghasilkan daftar datar file BUILD, dan makro tingkat ruang kerja yang dapat dipanggil dalam file WORKSPACE untuk menurunkan dependensi secara otomatis dengan cara yang mirip dengan Cargo itu sendiri.
Dalam kedua kasus tersebut, langkah pertama adalah memutuskan di mana menempatkan dependensi Cargo di ruang kerja. Pustaka ini dirancang dengan mempertimbangkan monorepos, tempat organisasi memutuskan serangkaian dependensi yang ditunjuk oleh semua orang. Hal ini dimaksudkan agar pemangku kepentingan dalam dependensi berkolaborasi untuk meningkatkan dependensi secara atom, dan memperbaiki kerusakan di seluruh basis kode mereka secara bersamaan. Jika hal ini tidak memungkinkan, masih dimungkinkan untuk menggunakan pengrusakan kargo dalam skenario desentralisasi, namun repositori yang dipisahkan tersebut tidak mungkin berinteraksi dengan baik dengan implementasi saat ini.
Terlepas dari pendekatan yang dipilih, Rust_rules harus dibawa ke WORKSPACE. Berikut ini contohnya:
load ( "@bazel_tools//tools/build_defs/repo:http.bzl" , "http_archive" )
http_archive (
name = "rules_rust" ,
sha256 = "accb5a89cbe63d55dcdae85938e56ff3aa56f21eb847ed826a28a83db8500ae6" ,
strip_prefix = "rules_rust-9aa49569b2b0dacecc51c05cee52708b7255bd98" ,
urls = [
# Main branch as of 2021-02-19
"https://github.com/bazelbuild/rules_rust/archive/9aa49569b2b0dacecc51c05cee52708b7255bd98.tar.gz" ,
],
)
load ( "@rules_rust//rust:repositories.bzl" , "rust_repositories" )
rust_repositories ( edition = "2018" )
Untuk proyek Bazel saja, pengguna harus terlebih dahulu membuat Cargo.toml standar dengan dependensi yang diinginkan. Berhati-hatilah untuk menyertakan direktif [lib]
sehingga Cargo tidak mengeluh tentang hilangnya file sumber untuk peti tiruan ini. Berikut ini contohnya:
[ package ]
name = " compile_with_bazel "
version = " 0.0.0 "
# Mandatory (or Cargo tooling is unhappy)
[ lib ]
path = " fake_lib.rs "
[ dependencies ]
log = " =0.3.6 "
Setelah Cargo.toml standar diterapkan, tambahkan arahan [package.metadata.raze]
untuk bagian selanjutnya.
Hampir semua pengaturan kargo kanonik harus dapat berfungsi di tempat dengan cargo-raze
. Dengan asumsi ruang kerja Cargo sekarang berada di bawah ruang kerja Bazel, Pengguna cukup menambahkan RazeSettings ke file Cargo.toml mereka untuk digunakan dalam menghasilkan file Bazel
# Above this line should be the contents of your Cargo.toml file
[ package . metadata . raze ]
# The path at which to write output files.
#
# `cargo raze` will generate Bazel-compatible BUILD files into this path.
# This can either be a relative path (e.g. "foo/bar"), relative to this
# Cargo.toml file; or relative to the Bazel workspace root (e.g. "//foo/bar").
workspace_path = " //cargo "
# This causes aliases for dependencies to be rendered in the BUILD
# file located next to this `Cargo.toml` file.
package_aliases_dir = " . "
# The set of targets to generate BUILD rules for.
targets = [
" x86_64-apple-darwin " ,
" x86_64-pc-windows-msvc " ,
" x86_64-unknown-linux-gnu " ,
]
# The two acceptable options are "Remote" and "Vendored" which
# is used to indicate whether the user is using a non-vendored or
# vendored set of dependencies.
genmode = " Remote "
Dalam proyek yang menggunakan ruang kerja kargo, pengguna harus mengatur semua pengaturan raze
mereka ke dalam bidang [workspace.metadata.raze]
di file Cargo.toml
tingkat atas yang berisi definisi [workspace]
. Pengaturan ini harus sama dengan yang terlihat di [package.metadata.raze]
di bagian sebelumnya. Namun, pengaturan peti masih dapat ditempatkan di file Cargo.toml
anggota ruang kerja:
# Above this line should be the contents of your package's Cargo.toml file
# Note that `some-dependency` is the name of an example dependency and
# `<0.3.0` is a semver version for the dependency crate's version. This
# should always be compaitble in some way with the dependency version
# specified in the `[dependencies]` section of the package defined in
# this file
[ package . metadata . raze . crates . some-dependency . '<0 . 3 . 0' ]
additional_flags = [
" --cfg=optional_feature_a " ,
" --cfg=optional_feature_b " ,
]
# This demonstrates that multiple crate settings may be defined.
[ package . metadata . raze . crates . some-other-dependency . '*' ]
additional_flags = [
" --cfg=special_feature " ,
]
Dalam mode Jarak Jauh, direktori yang mirip dengan mode vendor dipilih. Namun dalam kasus ini, ini hanya berisi file BUILD, instruksi vendor untuk WORKSPACE, dan alias untuk dependensi eksplisit. Diperlukan pipa yang sedikit berbeda.
Hal ini memberitahu Raze untuk tidak mengharapkan dependensi dijajakan dan menghasilkan file yang berbeda.
Pertama, instal kargo-raze.
$ cargo install cargo-raze
Selanjutnya, jalankan penggerusan kargo dari dalam direktori kargo
$ cargo raze
Terakhir, aktifkan fungsi pengambilan perpustakaan jarak jauh dalam WORKSPACE Anda:
load ( "//cargo:crates.bzl" , "raze_fetch_remote_crates" )
# Note that this method's name depends on your gen_workspace_prefix setting.
# `raze` is the default prefix.
raze_fetch_remote_crates ()
Ini memberi tahu Bazel dari mana mendapatkan dependensi, dan cara membuatnya: menggunakan file yang dihasilkan ke //cargo
.
Anda dapat bergantung pada dependensi eksplisit apa pun dalam aturan Rust mana pun dengan bergantung pada //cargo:your_dependency_name
.
Dalam mode Vendoring, root dipilih secara langsung yang akan menampung dependensi yang divendorkan dan menjadi pintu gerbang ke aturan build tersebut. //cargo
bersifat konvensional, namun //third_party/cargo
mungkin diinginkan untuk memenuhi kebutuhan organisasi. Vendor langsung ke root tidak didukung dengan baik karena kekhasan penerapannya, namun mungkin didukung di masa mendatang. Mulai sekarang, //cargo
akan menjadi direktori yang diasumsikan.
Pertama, instal alat yang diperlukan untuk melakukan vendor dan menghasilkan target yang DAPAT DIBUAT.
$ cargo install cargo-raze
Setelah itu, vendorkan dependensi Anda dari dalam direktori kargo/. Ini juga akan memperbarui file Cargo.lock
Anda.
$ cargo vendor --versioned-dirs
Terakhir, buat file BUILD Anda lagi dari dalam direktori cargo/
$ cargo raze
Anda sekarang dapat bergantung pada dependensi eksplisit apa pun dalam aturan Rust mana pun dengan bergantung pada //cargo:your_dependency_name
.
Cargo-raze dapat dibuat seluruhnya di Bazel dan digunakan tanpa perlu menyiapkan kargo di mesin host. Untuk melakukannya, cukup tambahkan yang berikut ini ke file WORKSPACE di proyek Anda:
load ( "@bazel_tools//tools/build_defs/repo:http.bzl" , "http_archive" )
http_archive (
name = "cargo_raze" ,
sha256 = "c664e258ea79e7e4ec2f2b57bca8b1c37f11c8d5748e02b8224810da969eb681" ,
strip_prefix = "cargo-raze-0.11.0" ,
url = "https://github.com/google/cargo-raze/archive/v0.11.0.tar.gz" ,
)
load ( "@cargo_raze//:repositories.bzl" , "cargo_raze_repositories" )
cargo_raze_repositories ()
load ( "@cargo_raze//:transitive_deps.bzl" , "cargo_raze_transitive_deps" )
cargo_raze_transitive_deps ()
Dengan ini, pengguna dapat menjalankan target @cargo_raze//:raze
untuk menghasilkan file BUILD baru. misalnya:
bazel run @cargo_raze//:raze -- --manifest-path= $( realpath /Cargo.toml )
Perhatikan bahwa pengguna yang menggunakan genmode vendored
masih harus menjual dependensinya karena cargo-raze
saat ini tidak melakukan hal ini untuk Anda.
Beberapa peti menjalankan "skrip pembuatan", yang, meskipun secara teknis tidak dibatasi fungsinya, biasanya melakukan salah satu dari beberapa hal umum.
Semua opsi yang disebutkan di bawah ini disebutkan dalam file src/settings.rs.
Dalam beberapa kasus, peti hanya menggunakan informasi dasar untuk menghasilkan file sumber Rust. Aturan skrip build ini sebenarnya dapat dijalankan dan digunakan dalam Bazel dengan menyertakan arahan di Cargo.toml Anda sebelum pembuatan:
[ package . metadata . raze . crates . clang-sys . '0 . 21 . 1' ]
gen_buildrs = true
Pengaturan ini memberitahukan cargo-raze untuk menghasilkan target rustic_binary untuk skrip build dan mengarahkan output yang dihasilkan (gaya OUT_DIR) ke peti induk.
Beberapa skrip build secara kondisional mengeluarkan arahan untuk memastikan bahwa Cargo mengetahui cara menyebarkannya. Sayangnya, mengelola informasi ketergantungan yang dihasilkan pada waktu build tidaklah mudah, jadi jika flag diketahui secara statis (mungkin, karena target kompilasi diketahui secara statis), flag tersebut dapat disediakan dari dalam Cargo.toml, dengan cara berikut
[ package . metadata . raze . crates . unicase . '2 . 1 . 0' ]
additional_flags = [
# Rustc is 1.15, enable all optional settings
" --cfg=__unicase__iter_cmp " ,
" --cfg=__unicase__defauler_hasher " ,
]
Bendera yang disediakan dengan cara ini langsung diserahkan kepada Rustc. Mungkin bermanfaat untuk merujuk ke bagian skrip build dari dokumentasi untuk menafsirkan skrip build dan arahan stdout yang ditemui, tersedia di sini: https://doc.rust-lang.org/cargo/reference/build-scripts.html
Ada dua cara untuk menyediakan perpustakaan sistem yang dibutuhkan peti untuk kompilasi. Yang pertama adalah menjual perpustakaan sistem secara langsung, membuat aturan BUILD untuknya, dan menambahkan ketergantungan ke peti -sys
yang sesuai. Untuk openssl, ini mungkin terlihat seperti:
[ package . metadata . raze . crates . openssl-sys . '0 . 9 . 24' ]
additional_flags = [
# Vendored openssl is 1.0.2m
" --cfg=ossl102 " ,
" --cfg=version=102 " ,
]
additional_deps = [
" @//third_party/openssl:crypto " ,
" @//third_party/openssl:ssl " ,
]
[ package . metadata . raze . crates . openssl . '0 . 10 . 2' ]
additional_flags = [
# Vendored openssl is 1.0.2m
" --cfg=ossl102 " ,
" --cfg=version=102 " ,
" --cfg=ossl10x " ,
]
Dalam beberapa kasus, menghubungkan langsung ketergantungan sistem lokal mungkin lebih baik. Untuk melakukannya, lihat bagian new_local_repository
pada dokumentasi Bazel. Untuk versi llvm yang telah dikompilasi di WORKSPACE, ini mungkin terlihat seperti:
new_local_repository (
name = "llvm" ,
build_file = "BUILD.llvm.bazel" ,
path = "/usr/lib/llvm-3.9" ,
)
Dalam beberapa kasus, peti sistem mungkin perlu diganti seluruhnya. Hal ini dapat difasilitasi dengan menghapus dan menambah ketergantungan di Cargo.toml, pra-generasi:
[ package . metadata . raze . crates . sdl2 . '0 . 31 . 0' ]
skipped_deps = [
" sdl2-sys-0.31.0 "
]
additional_deps = [
" @//cargo/overrides/sdl2-sys:sdl2_sys "
]
Beberapa peti menyediakan biner berguna yang dapat digunakan sebagai bagian dari proses kompilasi: Bindgen adalah contoh yang bagus. Bindgen menghasilkan file sumber Rust dengan memproses file C atau C++. Sebuah arahan dapat ditambahkan ke Cargo.toml untuk memberitahu Bazel agar mengekspos binari tersebut untuk Anda:
[ package . metadata . raze . crates . bindgen . '0 . 32 . 2' ]
gen_buildrs = true # needed to build bindgen
extra_aliased_targets = [
" cargo_bin_bindgen "
]
Cargo-raze mengawali target biner dengan cargo_bin_
, seolah-olah Cargo mengizinkan binari dan perpustakaan untuk berbagi nama target yang sama, Bazel melarangnya.
Saat ini, kargo tidak mengumpulkan metadata tentang peti yang tidak menyediakan perpustakaan apa pun. Artinya, penentuannya di bagian [dependencies]
pada file Cargo.toml
Anda tidak akan menghasilkan target Bazel yang dihasilkan. Cargo-raze memiliki bidang khusus untuk menangani peti ini saat menggunakan genmode = "Remote"
:
[ package . metadata . raze . binary_deps ]
wasm-bindgen-cli = " 0.2.68 "
Dalam cuplikan di atas, peti wasm-bindgen-cli
didefinisikan sebagai ketergantungan biner dan Cargo-raze akan memastikan metadata untuk peti ini dan peti lainnya yang ditentukan di sini disertakan dalam direktori keluaran yang dihasilkan. Lockfiles untuk target yang ditentukan pada [package.metadata.raze.binary_deps]
akan dibuat ke dalam direktori lockfiles
di dalam jalur yang ditentukan oleh workspace_path
.
Perhatikan bahwa bidang binary_deps
dapat masuk ke ruang kerja dan mengemas metadata, namun hanya satu definisi ketergantungan biner yang dapat ada pada satu waktu. Jika Anda memiliki beberapa paket yang bergantung pada satu ketergantungan biner, definisi tersebut perlu dipindahkan ke metadata ruang kerja.
Menyetel default_gen_buildrs ke true akan menyebabkan cargo-raze menghasilkan skrip build untuk semua peti yang memerlukannya:
[ package . metadata . raze ]
workspace_path = " //cargo "
genmode = " Remote "
default_gen_buildrs = true
Pengaturan ini merupakan trade-off antara kenyamanan dan kebenaran. Dengan mengaktifkannya, Anda akan mendapati banyak peti berfungsi tanpa harus menentukan tanda apa pun secara eksplisit, dan tanpa harus mengaktifkan skrip build individual secara manual. Namun dengan mengaktifkannya, Anda mengizinkan semua peti yang Anda gunakan untuk menjalankan kode arbitrer pada waktu pembuatan, dan tindakan yang dilakukannya mungkin tidak kedap udara.
Meskipun pengaturan ini diaktifkan, Anda mungkin masih perlu memberikan pengaturan tambahan untuk beberapa peti. Misalnya, peti cincin memerlukan akses ke pohon sumber pada waktu pembuatan:
[ package . metadata . raze . crates . ring . '*' ]
compile_data_attr = " glob([ " **/*.der " ]) "
Jika Anda ingin menonaktifkan skrip build pada masing-masing peti, Anda dapat melakukannya dengan cara berikut:
[ package . metadata . raze . crates . some_dependency . '*' ]
gen_buildrs = false
Bazel ("cepat", "benar", pilih dua) adalah sistem pembangunan yang telah teruji yang digunakan oleh Google untuk mengkompilasi proyek multibahasa yang sangat besar tanpa menduplikasi upaya, dan tanpa mengorbankan kebenaran. Hal ini dicapai dengan membatasi mekanisme apa yang dapat digunakan objek kompilasi tertentu untuk menemukan dependensi dan dengan memaksa unit yang dapat dibangun untuk mengekspresikan set lengkap dependensinya. Ia mengharapkan dua set input target build yang identik untuk menghasilkan hasil akhir yang setara byte demi byte.
Sebagai imbalannya, pengguna dihargai dengan sistem pembangunan yang dapat disesuaikan dan diperluas yang mengkompilasi segala jenis target yang dapat dikompilasi dan memungkinkan mengekspresikan "ketergantungan yang tidak konvensional", seperti objek Protobuf, shader grafis yang telah dikompilasi, atau kode yang dihasilkan, namun tetap cepat dan benar.
Ada kemungkinan juga (meskipun belum ditunjukkan dengan tolok ukur) bahwa aplikasi besar yang dibangun dengan mempertimbangkan kekuatan Bazel: unit build yang sangat granular, akan dikompilasi secara signifikan lebih cepat karena mereka mampu melakukan cache dengan lebih agresif dan menghindari kompilasi ulang kode sebanyak-banyaknya saat melakukan iterasi.
Baik atau buruk, ekosistem Rust sangat bergantung pada peti Cargo untuk menyediakan fungsionalitas yang sering ada di perpustakaan standar. Ini sebenarnya adalah hal yang luar biasa untuk evolusi bahasa, karena ini menggambarkan proses terstruktur menuju stabilisasi (peti eksperimental -> 1.0 peti -> RFC -> penyertaan di stdlib), tetapi itu berarti bahwa orang-orang yang tidak memiliki akses ke ekosistem ini harus menemukan kembali banyak roda.
Selain itu, ada juga peti fantastis yang membantu pengembang Rust berinteraksi dengan sistem dan perpustakaan standar industri yang dapat mempercepat pengembangan bahasa tersebut.
Meskipun beban untuk meniru fungsionalitas Cargo (jika memungkinkan!) tinggi, tampaknya ini adalah satu-satunya cara untuk menjaga jaminan (kebenaran, reproduktifitas) yang menjadi andalan Bazel agar tetap berkinerja. Ada kemungkinan dan kemungkinan besar dengan RFC dalam penerbangan bahwa Cargo akan menjadi cukup fleksibel untuk memungkinkannya digunakan secara langsung untuk kompilasi, tetapi pada saat ini nampaknya mempertahankan kesamaan fitur sebenarnya lebih mudah daripada menghindari semua sisi tajam yang diperkenalkan oleh memperlakukan Cargo seperti kompiler Rust.
Dengan sedikit kerja keras, dimungkinkan untuk membangun hampir semua hal, termasuk proyek yang bergantung pada openssl-sys. Banyak peti sistem memerlukan identifikasi perpustakaan sistem yang dibungkusnya, dan memasukkannya ke dalam proyek, atau memberi tahu Bazel di mana ia berada di sistem Anda. Beberapa mungkin memerlukan sedikit penyesuaian sumber, seperti menghilangkan persyaratan variabel lingkungan kargo yang dikodekan secara keras. Perbaikan mungkin tidak sepele dalam beberapa kasus, namun sejumlah peti paling populer telah dibuat dalam contoh repo, tersedia di https://github.com/acmcarther/cargo-raze-crater
Lihat contoh penyediaan konfigurasi peti berikut ini:
Menggunakan mode vendor :
Menggunakan mode jarak jauh :
Mengompilasi OpenSSL :
Bagian [package.metadata.raze]
berasal dari struct yang dideklarasikan di impl/src/settings.rs.