Move logic for detecting different kinds of externs to cargo_out.
This will work differently when not running cargo.
Bug: 293289578
Test: atest cargo_embargo.test
Change-Id: I6c7b1f6266d7d66bcbb68387d06f59306695008e
diff --git a/tools/cargo_embargo/src/cargo.rs b/tools/cargo_embargo/src/cargo.rs
index 23e6447..9a9949c 100644
--- a/tools/cargo_embargo/src/cargo.rs
+++ b/tools/cargo_embargo/src/cargo.rs
@@ -72,11 +72,11 @@
pub package_name: String,
pub version: Option<String>,
pub types: Vec<CrateType>,
- pub target: Option<String>, // --target
- pub features: Vec<String>, // --cfg feature=
- pub cfgs: Vec<String>, // non-feature --cfg
- pub externs: Vec<(String, Option<String>)>, // name => rlib file
- pub codegens: Vec<String>, // -C
+ pub target: Option<String>, // --target
+ pub features: Vec<String>, // --cfg feature=
+ pub cfgs: Vec<String>, // non-feature --cfg
+ pub externs: Vec<Extern>,
+ pub codegens: Vec<String>, // -C
pub cap_lints: String,
pub static_libs: Vec<String>,
pub shared_libs: Vec<String>,
@@ -84,3 +84,17 @@
pub package_dir: PathBuf, // canonicalized
pub main_src: PathBuf, // relative to package_dir
}
+
+/// A dependency of a Rust crate.
+#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
+pub struct Extern {
+ pub name: String,
+ pub lib_name: String,
+ pub extern_type: ExternType,
+}
+
+#[derive(Debug, Deserialize, Eq, PartialEq, Serialize)]
+pub enum ExternType {
+ Rust,
+ ProcMacro,
+}
diff --git a/tools/cargo_embargo/src/cargo/cargo_out.rs b/tools/cargo_embargo/src/cargo/cargo_out.rs
index 74acf5c..f04c013 100644
--- a/tools/cargo_embargo/src/cargo/cargo_out.rs
+++ b/tools/cargo_embargo/src/cargo/cargo_out.rs
@@ -13,7 +13,7 @@
// limitations under the License.
use super::metadata::WorkspaceMetadata;
-use super::{Crate, CrateType};
+use super::{Crate, CrateType, Extern, ExternType};
use anyhow::anyhow;
use anyhow::bail;
use anyhow::Context;
@@ -236,12 +236,32 @@
// example: memoffset=/some/path/libmemoffset-2cfda327d156e680.rmeta
let arg = arg_iter.next().unwrap();
if let Some((name, path)) = arg.split_once('=') {
- out.externs.push((
- name.to_string(),
- Some(path.split('/').last().unwrap().to_string()),
- ));
- } else {
- out.externs.push((arg.to_string(), None));
+ let filename = path.split('/').last().unwrap();
+
+ // Example filename: "libgetrandom-fd8800939535fc59.rmeta"
+ static REGEX: Lazy<Regex> = Lazy::new(|| {
+ Regex::new(r"^lib(.*)-[0-9a-f]*.(rlib|so|rmeta)$").unwrap()
+ });
+
+ let Some(lib_name) = REGEX.captures(filename).and_then(|x| x.get(1)) else {
+ bail!("bad filename for extern {}: {}", name, filename);
+ };
+ let extern_type =
+ if filename.ends_with(".rlib") || filename.ends_with(".rmeta") {
+ ExternType::Rust
+ } else if filename.ends_with(".so") {
+ // Assume .so files are always proc_macros. May not always be right.
+ ExternType::ProcMacro
+ } else {
+ bail!("Unexpected extension for extern filename {}", filename);
+ };
+ out.externs.push(Extern {
+ name: name.to_string(),
+ lib_name: lib_name.as_str().to_string(),
+ extern_type,
+ });
+ } else if arg != "proc_macro" {
+ panic!("No filename for {}", arg);
}
}
_ if arg.starts_with("-C") => {
diff --git a/tools/cargo_embargo/src/main.rs b/tools/cargo_embargo/src/main.rs
index cbcac39..84638ca 100644
--- a/tools/cargo_embargo/src/main.rs
+++ b/tools/cargo_embargo/src/main.rs
@@ -36,10 +36,8 @@
use anyhow::Context;
use anyhow::Result;
use bp::*;
-use cargo::{cargo_out::parse_cargo_out, Crate, CrateType};
+use cargo::{cargo_out::parse_cargo_out, Crate, CrateType, ExternType};
use clap::Parser;
-use once_cell::sync::Lazy;
-use regex::Regex;
use std::collections::BTreeMap;
use std::collections::VecDeque;
use std::fs::File;
@@ -505,27 +503,10 @@
let mut rust_libs = Vec::new();
let mut proc_macro_libs = Vec::new();
- for (extern_name, filename) in &crate_.externs {
- if extern_name == "proc_macro" {
- continue;
- }
- let filename =
- filename.as_ref().unwrap_or_else(|| panic!("no filename for {}", extern_name));
- // Example filename: "libgetrandom-fd8800939535fc59.rmeta"
- static REGEX: Lazy<Regex> =
- Lazy::new(|| Regex::new(r"^lib(.*)-[0-9a-f]*.(rlib|so|rmeta)$").unwrap());
- let lib_name = if let Some(x) = REGEX.captures(filename).and_then(|x| x.get(1)) {
- x
- } else {
- bail!("bad filename for extern {}: {}", extern_name, filename);
- };
- if filename.ends_with(".rlib") || filename.ends_with(".rmeta") {
- rust_libs.push(lib_name.as_str().to_string());
- } else if filename.ends_with(".so") {
- // Assume .so files are always proc_macros. May not always be right.
- proc_macro_libs.push(lib_name.as_str().to_string());
- } else {
- unreachable!();
+ for extern_dep in &crate_.externs {
+ match extern_dep.extern_type {
+ ExternType::Rust => rust_libs.push(extern_dep.lib_name.clone()),
+ ExternType::ProcMacro => proc_macro_libs.push(extern_dep.lib_name.clone()),
}
}
diff --git a/tools/cargo_embargo/testdata/either/crates.json b/tools/cargo_embargo/testdata/either/crates.json
index aa38632..27f5977 100644
--- a/tools/cargo_embargo/testdata/either/crates.json
+++ b/tools/cargo_embargo/testdata/either/crates.json
@@ -24,7 +24,9 @@
"target": "x86_64-unknown-linux-gnu",
"features": ["default", "use_std"],
"cfgs": [],
- "externs": [["serde_json", "libserde_json-a330ac0e36ca324c.rlib"]],
+ "externs": [
+ { "name": "serde_json", "lib_name": "serde_json", "extern_type": "Rust" }
+ ],
"codegens": [],
"cap_lints": "",
"static_libs": [],
diff --git a/tools/cargo_embargo/testdata/plotters/crates.json b/tools/cargo_embargo/testdata/plotters/crates.json
index 04851c9..b65bbf9 100644
--- a/tools/cargo_embargo/testdata/plotters/crates.json
+++ b/tools/cargo_embargo/testdata/plotters/crates.json
@@ -8,9 +8,17 @@
"features": ["area_series", "line_series", "plotters-svg", "svg_backend"],
"cfgs": [],
"externs": [
- ["num_traits", "libnum_traits-93a69c224ed38166.rmeta"],
- ["plotters_backend", "libplotters_backend-4110c43be89cf520.rmeta"],
- ["plotters_svg", "libplotters_svg-e0f639cce7c4701c.rmeta"]
+ { "name": "num_traits", "lib_name": "num_traits", "extern_type": "Rust" },
+ {
+ "name": "plotters_backend",
+ "lib_name": "plotters_backend",
+ "extern_type": "Rust"
+ },
+ {
+ "name": "plotters_svg",
+ "lib_name": "plotters_svg",
+ "extern_type": "Rust"
+ }
],
"codegens": [],
"cap_lints": "",