Add `aliases` property for renaming Rust dependencies.
This is equivalent to specifying a dependency name different to the
package name in cargo, which some external crates do.
Bug: 308790322
Test: Built libgrpcio with aliases for protobuf
Change-Id: I2801222051fdd962460cc7f4900cec357f63b974
diff --git a/rust/compiler.go b/rust/compiler.go
index c1bdbeb..03fdf2b 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -75,6 +75,8 @@
strippedOutputFilePath() android.OptionalPath
checkedCrateRootPath() (android.Path, error)
+
+ Aliases() map[string]string
}
func (compiler *baseCompiler) edition() string {
@@ -140,6 +142,12 @@
// flags to pass to the linker
Ld_flags []string `android:"arch_variant"`
+ // Rust crate dependencies to rename. Each entry should be a string of the form "dependencyname:alias".
+ //
+ // "dependencyname" here should be the name of the crate, not the Android module. This is
+ // equivalent to writing `alias = { package = "dependencyname" }` in a `Cargo.toml`.
+ Aliases []string
+
// list of rust rlib crate dependencies
Rlibs []string `android:"arch_variant"`
@@ -281,6 +289,18 @@
return Bool(compiler.Properties.Prefer_rlib)
}
+func (compiler *baseCompiler) Aliases() map[string]string {
+ aliases := map[string]string{}
+ for _, entry := range compiler.Properties.Aliases {
+ dep, alias, found := strings.Cut(entry, ":")
+ if !found {
+ panic(fmt.Errorf("invalid aliases entry %q missing ':'", entry))
+ }
+ aliases[dep] = alias
+ }
+ return aliases
+}
+
func (compiler *baseCompiler) stdLinkage(ctx *depsContext) RustLinkage {
// For devices, we always link stdlibs in as dylibs by default.
if compiler.preferRlib() {
diff --git a/rust/rust.go b/rust/rust.go
index 668dd8f..7d81c72 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1142,6 +1142,7 @@
}
}
}
+
func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
@@ -1433,16 +1434,29 @@
mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
var rlibDepFiles RustLibraries
+ aliases := mod.compiler.Aliases()
for _, dep := range directRlibDeps {
- rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var dylibDepFiles RustLibraries
for _, dep := range directDylibDeps {
- dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var procMacroDepFiles RustLibraries
for _, dep := range directProcMacroDeps {
- procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
+ crateName := dep.CrateName()
+ if alias, aliased := aliases[crateName]; aliased {
+ crateName = alias
+ }
+ procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: crateName})
}
var staticLibDepFiles android.Paths
diff --git a/rust/rust_test.go b/rust/rust_test.go
index d609c2f..295a734 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -470,6 +470,35 @@
m.Output("libwaldo.dylib.so.bloaty.csv")
}
+// Test that aliases are respected.
+func TestRustAliases(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library {
+ name: "libbar",
+ crate_name: "bar",
+ srcs: ["src/lib.rs"],
+ }
+ rust_library {
+ name: "libbaz",
+ crate_name: "baz",
+ srcs: ["src/lib.rs"],
+ }
+ rust_binary {
+ name: "foo",
+ srcs: ["src/main.rs"],
+ rustlibs: ["libbar", "libbaz"],
+ aliases: ["bar:bar_renamed"],
+ }`)
+
+ fooRustc := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so") {
+ t.Errorf("--extern bar_renamed=out/soong/.intermediates/libbar/android_arm64_armv8-a_dylib/unstripped/libbar.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ }
+ if !strings.Contains(fooRustc.Args["libFlags"], "--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so") {
+ t.Errorf("--extern baz=out/soong/.intermediates/libbaz/android_arm64_armv8-a_dylib/unstripped/libbaz.dylib.so flag not being passed to rustc for rust_binary with aliases. libFlags: %#v", fooRustc.Args["libFlags"])
+ }
+}
+
func assertString(t *testing.T, got, expected string) {
t.Helper()
if got != expected {