From 88928b96e1fe72d173c106f511d7f6537ed30000 Mon Sep 17 00:00:00 2001 From: Ernesto Ocampo Date: Thu, 23 May 2024 11:47:28 +0000 Subject: [PATCH] Build micro_rpc for bare metal with Bazel (second edition). BUG: 340185847 Change-Id: I63093f971b4dda1e818926f0338ae3727ad54e3a --- Cargo.bazel.lock | 1 + Cargo_no_std.bazel.lock | 10 ++++ WORKSPACE | 9 ++++ cargo-bazel-lock.json | 7 ++- cargo-no-std-bazel-lock.json | 54 ++++++++++++++++++- justfile | 2 +- micro_rpc/BUILD | 20 ++++++- micro_rpc/build.rs | 44 ++++++++++++++- .../rust-hypervisor-firmware-virtio/BUILD | 2 +- 9 files changed, 142 insertions(+), 7 deletions(-) diff --git a/Cargo.bazel.lock b/Cargo.bazel.lock index 7cb5d391cc9..94a95abe571 100644 --- a/Cargo.bazel.lock +++ b/Cargo.bazel.lock @@ -744,6 +744,7 @@ dependencies = [ "procfs", "prost", "prost-build", + "prost-derive", "prost-types", "rand_core", "regex", diff --git a/Cargo_no_std.bazel.lock b/Cargo_no_std.bazel.lock index 7b98de79f2f..e789c6fa4c0 100644 --- a/Cargo_no_std.bazel.lock +++ b/Cargo_no_std.bazel.lock @@ -41,6 +41,7 @@ dependencies = [ "bytes", "getrandom", "log", + "prost", "x86_64", ] @@ -67,6 +68,15 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", +] + [[package]] name = "rustversion" version = "1.0.16" diff --git a/WORKSPACE b/WORKSPACE index b8139aab52e..887676340a0 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -564,6 +564,9 @@ crates_repository( features = ["prost-derive"], version = "*", ), + "prost-derive": crate.spec( + version = "*", + ), "prost-build": crate.spec( version = "*", ), @@ -703,6 +706,12 @@ crates_repository( features = [], version = "*", ), + "prost": crate.spec( + default_features = False, + # No derive feature - it requires std and will make other crates + # in this index, like bytes, require std. + version = "*", + ), "x86_64": crate.spec(version = "*"), }, supported_platform_triples = [ diff --git a/cargo-bazel-lock.json b/cargo-bazel-lock.json index 41dd0b30748..dca9368c368 100644 --- a/cargo-bazel-lock.json +++ b/cargo-bazel-lock.json @@ -1,5 +1,5 @@ { - "checksum": "cf72206d8060287b076fedaeccc63131ecb47e453b310a56cb0a4c11f1900455", + "checksum": "1230c1a0283e3fd0d98539343f1a0dc7140874471b93228f8fc2bcebfe50f4d5", "crates": { "acpi 5.0.0": { "name": "acpi", @@ -4588,6 +4588,10 @@ { "id": "async-trait 0.1.79", "target": "async_trait" + }, + { + "id": "prost-derive 0.12.4", + "target": "prost_derive" } ], "selects": {} @@ -19350,6 +19354,7 @@ "procfs 0.16.0", "prost 0.12.4", "prost-build 0.12.3", + "prost-derive 0.12.4", "prost-types 0.12.3", "rand_core 0.6.4", "regex 1.10.4", diff --git a/cargo-no-std-bazel-lock.json b/cargo-no-std-bazel-lock.json index 2498ffcab6d..6ebab15a1fb 100644 --- a/cargo-no-std-bazel-lock.json +++ b/cargo-no-std-bazel-lock.json @@ -1,5 +1,5 @@ { - "checksum": "7d35e77527edbd7a0a9f635fb185d7c95cd49f7877c7f4a65b183212d648d18b", + "checksum": "631d10644e387894ecdde4db0556fe725d97f7c5bd599465b375cdeb5dee84fd", "crates": { "anyhow 1.0.83": { "name": "anyhow", @@ -267,6 +267,10 @@ "id": "log 0.4.21", "target": "log" }, + { + "id": "prost 0.12.6", + "target": "prost" + }, { "id": "x86_64 0.15.1", "target": "x86_64" @@ -452,6 +456,53 @@ ], "license_file": "LICENSE-APACHE" }, + "prost 0.12.6": { + "name": "prost", + "version": "0.12.6", + "package_url": "https://github.com/tokio-rs/prost", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/prost/0.12.6/download", + "sha256": "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" + } + }, + "targets": [ + { + "Library": { + "crate_name": "prost", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": false, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "prost", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "bytes 1.6.0", + "target": "bytes" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.12.6" + }, + "license": "Apache-2.0", + "license_ids": [ + "Apache-2.0" + ], + "license_file": null + }, "rustversion 1.0.16": { "name": "rustversion", "version": "1.0.16", @@ -695,6 +746,7 @@ "bytes 1.6.0", "getrandom 0.2.15", "log 0.4.21", + "prost 0.12.6", "x86_64 0.15.1" ], "direct_dev_deps": [] diff --git a/justfile b/justfile index 00f40fef3c7..08b1ecfaae4 100644 --- a/justfile +++ b/justfile @@ -172,7 +172,7 @@ kokoro_run_tests: all_ensure_no_std clang-tidy: bazel build $BAZEL_CONFIG_FLAG --config=clang-tidy //cc/... -bare_metal_crates := "//oak_linux_boot_params //oak_channel //oak_core //oak_virtio //third_party/rust-hypervisor-firmware-virtio" +bare_metal_crates := "//oak_linux_boot_params //oak_channel //oak_core //oak_virtio //third_party/rust-hypervisor-firmware-virtio //micro_rpc" bazel-ci: bazel build --config=unsafe-fast-presubmit -- @jemalloc //...:all diff --git a/micro_rpc/BUILD b/micro_rpc/BUILD index e4ddffd1a92..8c92f989a49 100644 --- a/micro_rpc/BUILD +++ b/micro_rpc/BUILD @@ -27,11 +27,24 @@ rust_library( srcs = glob(["src/**"]), proc_macro_deps = [ "@oak_crates_index//:async-trait", + "@oak_crates_index//:prost-derive", ], deps = [ ":build", - "@oak_crates_index//:prost", - ], + ] + select({ + "@platforms//os:none": [ + "@oak_no_std_crates_index//:prost", + ], + "//conditions:default": [ + # When not building for bare metal, use the crate with std. Crates that require std + # and that also require prost won't work with @oak_no_std_crates_index//:prost. For + # example, oak_containers_orchestrator uses tonic which uses both prost and std. + # Both oak_containers_orchestrator and tonic need to see the same prost symbols. + # It doesn't work if one sees "@oak_no_std_crates_index//:prost" and the other + # sees "@oak_crates_index//:prost". + "@oak_crates_index//:prost", + ], + }), ) cargo_build_script( @@ -42,8 +55,11 @@ cargo_build_script( build_script_env = { "PROTOC": "$(execpath @com_google_protobuf//:protoc)", }, + crate_features = ["bazel"], # See b/340185847 and fix_prost_derives function doc. data = [ "//proto/micro_rpc:messages_proto", + ], + tools = [ "@com_google_protobuf//:protoc", ], deps = [ diff --git a/micro_rpc/build.rs b/micro_rpc/build.rs index 5bbd3e02adc..30ce6d4068e 100644 --- a/micro_rpc/build.rs +++ b/micro_rpc/build.rs @@ -14,10 +14,52 @@ // limitations under the License. // -fn main() { +#[cfg(feature = "bazel")] +use std::fs; + +fn main() -> Result<(), Box> { micro_rpc_build::compile( &["../proto/micro_rpc/messages.proto"], &["../proto"], Default::default(), ); + + #[cfg(feature = "bazel")] + fix_prost_derives()?; + + Ok(()) +} + +#[cfg(feature = "bazel")] +/// Replaces refs to prost with prost_derive. See b/340185847. +/// Only to be called from build scripts of crates that generate prost code. +/// Only to be called when building with Bazel. +/// The issue that this fixes is that prost with "derive" feature uses +/// "prost-derive", which requires std. In Cargo, that works OK as the +/// feature "std" isn't propagated to deps of crates that don't use them, +/// but Bazel's can't handle that. With Bazel, if we bring prost-derive +/// into the index, it'll make deps like `bytes` also use the "std" feature. +/// Take into account that in Cargo, features of dependencies are declared in +/// the "depending" crate, that is, they belong to the dependency arc, while +/// in Bazel, one crate is brought into an index with a fixed set of features. +/// To solve this, and to be able to build for bare metal from Bazel, we +/// import prost without derive to oak_no_std_crates_index, use prost-derive +/// derive macro directly, but we need to change the crate name, as we no +/// longer have prost re-exporting the derive macros. +pub fn fix_prost_derives() -> Result<(), Box> { + // let out_dir_path = std::path::PathBuf::from(std::env::var("OUT_DIR"))?; + + let out_dir = std::env::var("OUT_DIR")?; + for entry in fs::read_dir(&out_dir)? { + let file_path = entry?.path(); + let contents = fs::read_to_string(&file_path)?; + + let updated = contents.replace("::prost::Message", "::prost_derive::Message"); + let updated = updated.replace("::prost::Oneof", "::prost_derive::Oneof"); + let updated = updated.replace("::prost::Enumeration", "::prost_derive::Enumeration"); + + fs::write(&file_path, updated)?; + } + + Ok(()) } diff --git a/third_party/rust-hypervisor-firmware-virtio/BUILD b/third_party/rust-hypervisor-firmware-virtio/BUILD index 65f29db50a4..dee065f89b5 100644 --- a/third_party/rust-hypervisor-firmware-virtio/BUILD +++ b/third_party/rust-hypervisor-firmware-virtio/BUILD @@ -25,8 +25,8 @@ rust_library( srcs = glob(["src/**"]), deps = [ "@oak_crates_index//:atomic_refcell", - "@oak_no_std_crates_index//:log", "@oak_no_std_crates_index//:bitflags", + "@oak_no_std_crates_index//:log", "@oak_no_std_crates_index//:x86_64", ], )