diff --git a/tools/aconfig/aconfig_storage_file/Android.bp b/tools/aconfig/aconfig_storage_file/Android.bp index b590312961..390067a28b 100644 --- a/tools/aconfig/aconfig_storage_file/Android.bp +++ b/tools/aconfig/aconfig_storage_file/Android.bp @@ -12,6 +12,7 @@ rust_defaults { "libtempfile", "libprotobuf", "libclap", + "libcxx", "libaconfig_storage_protos", ], } @@ -69,3 +70,46 @@ cc_library_static { ], host_supported: true, } + +// cxx source codegen from rust api +genrule { + name: "libcxx_aconfig_storage_file_bridge_code", + tools: ["cxxbridge"], + cmd: "$(location cxxbridge) $(in) > $(out)", + srcs: ["src/lib.rs"], + out: ["aconfig_storage/lib.rs.cc"], +} + +// cxx header codegen from rust api +genrule { + name: "libcxx_aconfig_storage_file_bridge_header", + tools: ["cxxbridge"], + cmd: "$(location cxxbridge) $(in) --header > $(out)", + srcs: ["src/lib.rs"], + out: ["aconfig_storage/lib.rs.h"], +} + +// a static cc lib based on generated code +rust_ffi_static { + name: "libaconfig_storage_file_cxx_bridge", + crate_name: "aconfig_storage_file_cxx_bridge", + host_supported: true, + srcs: ["src/lib.rs"], + defaults: ["aconfig_storage_file.defaults"], +} + +// flag storage file cc interface +cc_library_static { + name: "libaconfig_storage_file_cc", + srcs: ["aconfig_storage_file.cpp"], + generated_headers: [ + "cxx-bridge-header", + "libcxx_aconfig_storage_file_bridge_header", + ], + generated_sources: ["libcxx_aconfig_storage_file_bridge_code"], + whole_static_libs: ["libaconfig_storage_file_cxx_bridge"], + export_include_dirs: ["include"], + static_libs: [ + "libbase", + ], +} diff --git a/tools/aconfig/aconfig_storage_file/Cargo.toml b/tools/aconfig/aconfig_storage_file/Cargo.toml index 641f481ed3..5c51e83f2d 100644 --- a/tools/aconfig/aconfig_storage_file/Cargo.toml +++ b/tools/aconfig/aconfig_storage_file/Cargo.toml @@ -12,6 +12,7 @@ anyhow = "1.0.69" protobuf = "3.2.0" tempfile = "3.9.0" thiserror = "1.0.56" +cxx = "1.0" clap = { version = "4.1.8", features = ["derive"] } [[bin]] diff --git a/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp new file mode 100644 index 0000000000..4807788e22 --- /dev/null +++ b/tools/aconfig/aconfig_storage_file/aconfig_storage_file.cpp @@ -0,0 +1,20 @@ +#include "rust/cxx.h" +#include "aconfig_storage/lib.rs.h" +#include "aconfig_storage/aconfig_storage_file.hpp" + +namespace aconfig_storage { +android::base::Result create_flag_info( + std::string const& package_map, + std::string const& flag_map, + std::string const& flag_info_out) { + auto creation_cxx = create_flag_info_cxx( + rust::Str(package_map.c_str()), + rust::Str(flag_map.c_str()), + rust::Str(flag_info_out.c_str())); + if (creation_cxx.success) { + return {}; + } else { + return android::base::Error() << creation_cxx.error_message; + } +} +} // namespace aconfig_storage diff --git a/tools/aconfig/aconfig_storage_file/build.rs b/tools/aconfig/aconfig_storage_file/build.rs index 1feeb60677..894b71c10f 100644 --- a/tools/aconfig/aconfig_storage_file/build.rs +++ b/tools/aconfig/aconfig_storage_file/build.rs @@ -14,4 +14,7 @@ fn main() { .inputs(proto_files) .cargo_out_dir("aconfig_storage_protos") .run_from_script(); + + let _ = cxx_build::bridge("src/lib.rs"); + println!("cargo:rerun-if-changed=src/lib.rs"); } diff --git a/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp new file mode 100644 index 0000000000..31af8cdec0 --- /dev/null +++ b/tools/aconfig/aconfig_storage_file/include/aconfig_storage/aconfig_storage_file.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +namespace aconfig_storage { +/// Create flag info file based on package and flag map +/// \input package_map: package map file +/// \input flag_map: flag map file +/// \input flag_info_out: flag info file to be created +android::base::Result create_flag_info( + std::string const& package_map, + std::string const& flag_map, + std::string const& flag_info_out); +} // namespace aconfig_storage diff --git a/tools/aconfig/aconfig_storage_file/src/lib.rs b/tools/aconfig/aconfig_storage_file/src/lib.rs index 3b975d95f6..229c3d5f96 100644 --- a/tools/aconfig/aconfig_storage_file/src/lib.rs +++ b/tools/aconfig/aconfig_storage_file/src/lib.rs @@ -332,6 +332,43 @@ pub fn create_flag_info( Ok(()) } +// *************************************** // +// CC INTERLOP +// *************************************** // +#[cxx::bridge] +mod ffi { + pub struct FlagInfoCreationCXX { + pub success: bool, + pub error_message: String, + } + + extern "Rust" { + pub fn create_flag_info_cxx( + package_map: &str, + flag_map: &str, + flag_info_out: &str, + ) -> FlagInfoCreationCXX; + } +} + +/// Create flag info file cc interlop +pub fn create_flag_info_cxx( + package_map: &str, + flag_map: &str, + flag_info_out: &str, +) -> ffi::FlagInfoCreationCXX { + match create_flag_info(package_map, flag_map, flag_info_out) { + Ok(()) => ffi::FlagInfoCreationCXX { + success: true, + error_message: String::from(""), + }, + Err(errmsg) => ffi::FlagInfoCreationCXX { + success: false, + error_message: format!("{:?}", errmsg), + } + } +} + #[cfg(test)] mod tests { use super::*;