From e6d3098c1b95b94a9a7c03e9ade9b2cbf3ac10e2 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Fri, 5 Feb 2021 10:57:43 -0500 Subject: [PATCH] rust: Add rust_ffi_static vendor ramdisk Support Similar to our vendor support, this adds support for linking rust static libraries to vendor ramdisk cc modules. A bug fix is also included where a restriction against setting rust_ffi vendor-specific was not being enforced. Bug: 179397942 Test: Example modules link, Soong tests pass. Change-Id: I737cdf0c2f49ab349bcea2a0429e6298ebc1313e --- cc/androidmk.go | 4 ++-- cc/cc.go | 8 ++++---- cc/snapshot_prebuilt.go | 2 +- cc/testing.go | 12 +++++++++++ rust/image.go | 26 ++++++++++++++++++++---- rust/image_test.go | 45 +++++++++++++++++++++++++++++++++++++++-- rust/rust.go | 16 ++++++++++++--- rust/testing.go | 2 ++ 8 files changed, 99 insertions(+), 16 deletions(-) diff --git a/cc/androidmk.go b/cc/androidmk.go index ddb81d99b..8652c1042 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -26,9 +26,9 @@ import ( var ( nativeBridgeSuffix = ".native_bridge" productSuffix = ".product" - vendorSuffix = ".vendor" + VendorSuffix = ".vendor" ramdiskSuffix = ".ramdisk" - vendorRamdiskSuffix = ".vendor_ramdisk" + VendorRamdiskSuffix = ".vendor_ramdisk" recoverySuffix = ".recovery" sdkSuffix = ".sdk" ) diff --git a/cc/cc.go b/cc/cc.go index df384996d..7f59158f6 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -1544,7 +1544,7 @@ func (c *Module) getNameSuffixWithVndkVersion(ctx android.ModuleContext) string nameSuffix = productSuffix } else { vndkVersion = ctx.DeviceConfig().VndkVersion() - nameSuffix = vendorSuffix + nameSuffix = VendorSuffix } if vndkVersion == "current" { vndkVersion = ctx.DeviceConfig().PlatformVndkVersion() @@ -1591,11 +1591,11 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { // .vendor suffix is added for backward compatibility with VNDK snapshot whose names with // such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp. - c.Properties.SubName += vendorSuffix + c.Properties.SubName += VendorSuffix } else if c.InRamdisk() && !c.OnlyInRamdisk() { c.Properties.SubName += ramdiskSuffix } else if c.InVendorRamdisk() && !c.OnlyInVendorRamdisk() { - c.Properties.SubName += vendorRamdiskSuffix + c.Properties.SubName += VendorRamdiskSuffix } else if c.InRecovery() && !c.OnlyInRecovery() { c.Properties.SubName += recoverySuffix } else if c.IsSdkVariant() && (c.Properties.SdkAndPlatformVariantVisibleToMake || c.SplitPerApiLevel()) { @@ -2927,7 +2927,7 @@ func (c *Module) makeLibName(ctx android.ModuleContext, ccDep LinkableInterface, } else if ccDep.InRamdisk() && !ccDep.OnlyInRamdisk() { return libName + ramdiskSuffix } else if ccDep.InVendorRamdisk() && !ccDep.OnlyInVendorRamdisk() { - return libName + vendorRamdiskSuffix + return libName + VendorRamdiskSuffix } else if ccDep.InRecovery() && !ccDep.OnlyInRecovery() { return libName + recoverySuffix } else if ccDep.Target().NativeBridge == android.NativeBridgeEnabled { diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index ffaed8e55..b82628ccb 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -144,7 +144,7 @@ func (vendorSnapshotImage) imageVariantName(cfg android.DeviceConfig) string { } func (vendorSnapshotImage) moduleNameSuffix() string { - return vendorSuffix + return VendorSuffix } func (recoverySnapshotImage) init(ctx android.RegistrationContext) { diff --git a/cc/testing.go b/cc/testing.go index 3a5bd1762..45e531208 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -43,6 +43,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { name: "libatomic", defaults: ["linux_bionic_supported"], vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -52,6 +53,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { toolchain_library { name: "libcompiler_rt-extras", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, src: "", @@ -60,6 +62,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { toolchain_library { name: "libclang_rt.builtins-arm-android", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -69,6 +72,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { toolchain_library { name: "libclang_rt.builtins-aarch64-android", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -93,6 +97,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { toolchain_library { name: "libclang_rt.builtins-i686-android", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -103,6 +108,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { name: "libclang_rt.builtins-x86_64-android", defaults: ["linux_bionic_supported"], vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -113,6 +119,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { name: "libunwind", defaults: ["linux_bionic_supported"], vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_bridge_supported: true, @@ -238,6 +245,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { cc_library { name: "libprofile-extras", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_coverage: false, @@ -248,6 +256,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { cc_library { name: "libprofile-clang-extras", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, native_coverage: false, @@ -319,6 +328,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { system_shared_libs: [], stl: "none", vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, host_supported: true, @@ -356,6 +366,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { stl: "none", host_supported: false, vendor_available: true, + vendor_ramdisk_available: true, product_available: true, recovery_available: true, min_sdk_version: "29", @@ -380,6 +391,7 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { defaults: ["linux_bionic_supported"], recovery_available: true, vendor_available: true, + vendor_ramdisk_available: true, product_available: true, native_bridge_supported: true, stl: "none", diff --git a/rust/image.go b/rust/image.go index ac8c1b32c..628aca3e4 100644 --- a/rust/image.go +++ b/rust/image.go @@ -24,7 +24,7 @@ import ( var _ android.ImageInterface = (*Module)(nil) func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { - return false + return mod.Properties.VendorRamdiskVariantNeeded } func (mod *Module) CoreVariantNeeded(ctx android.BaseModuleContext) bool { @@ -52,6 +52,10 @@ func (mod *Module) InRecovery() bool { return false } +func (mod *Module) InVendorRamdisk() bool { + return mod.ModuleBase.InVendorRamdisk() || mod.ModuleBase.InstallInVendorRamdisk() +} + func (mod *Module) OnlyInRamdisk() bool { // TODO(b/165791368) return false @@ -86,7 +90,9 @@ func (c *Module) InProduct() bool { func (mod *Module) SetImageVariation(ctx android.BaseModuleContext, variant string, module android.Module) { m := module.(*Module) - if strings.HasPrefix(variant, cc.VendorVariationPrefix) { + if variant == android.VendorRamdiskVariation { + m.MakeAsPlatform() + } else if strings.HasPrefix(variant, cc.VendorVariationPrefix) { m.Properties.ImageVariationPrefix = cc.VendorVariationPrefix m.Properties.VndkVersion = strings.TrimPrefix(variant, cc.VendorVariationPrefix) @@ -117,6 +123,8 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { } coreVariantNeeded := true + vendorRamdiskVariantNeeded := false + var vendorVariants []string if mod.HasVendorVariant() { @@ -138,15 +146,23 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { // We can't check shared() here because image mutator is called before the library mutator, so we need to // check buildShared() if lib.buildShared() { - mctx.PropertyErrorf(prop, "can only be set for rust_ffi_static modules.") + mctx.PropertyErrorf(prop, "cannot be set for rust_ffi or rust_ffi_shared modules.") } else { vendorVariants = append(vendorVariants, platformVndkVersion) } } } + if Bool(mod.Properties.Vendor_ramdisk_available) { + if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && lib.buildShared()) { + mctx.PropertyErrorf("vendor_ramdisk_available", "cannot be set for rust_ffi or rust_ffi_shared modules.") + } else { + vendorRamdiskVariantNeeded = true + } + } + if vendorSpecific { - if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && !lib.static()) { + if lib, ok := mod.compiler.(libraryInterface); !ok || (ok && (lib.buildShared() || lib.buildDylib() || lib.buildRlib())) { mctx.ModuleErrorf("Rust vendor specific modules are currently only supported for rust_ffi_static modules.") } else { coreVariantNeeded = false @@ -155,6 +171,8 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { } mod.Properties.CoreVariantNeeded = coreVariantNeeded + mod.Properties.VendorRamdiskVariantNeeded = vendorRamdiskVariantNeeded + for _, variant := range android.FirstUniqueStrings(vendorVariants) { mod.Properties.ExtraVariants = append(mod.Properties.ExtraVariants, cc.VendorVariationPrefix+variant) } diff --git a/rust/image_test.go b/rust/image_test.go index fd719628b..1515aa264 100644 --- a/rust/image_test.go +++ b/rust/image_test.go @@ -21,7 +21,7 @@ import ( "android/soong/cc" ) -// Test that cc_binaries can link against rust_ffi_static libraries. +// Test that cc modules can link against vendor_available rust_ffi_static libraries. func TestVendorLinkage(t *testing.T) { ctx := testRust(t, ` cc_binary { @@ -44,9 +44,33 @@ func TestVendorLinkage(t *testing.T) { } } +// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries. +func TestVendorRamdiskLinkage(t *testing.T) { + ctx := testRust(t, ` + cc_library_static { + name: "libcc_vendor_ramdisk", + static_libs: ["libfoo_vendor_ramdisk"], + system_shared_libs: [], + vendor_ramdisk_available: true, + } + rust_ffi_static { + name: "libfoo_vendor_ramdisk", + crate_name: "foo", + srcs: ["foo.rs"], + vendor_ramdisk_available: true, + } + `) + + vendorRamdiskLibrary := ctx.ModuleForTests("libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_static").Module().(*cc.Module) + + if !android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { + t.Errorf("libcc_vendor_ramdisk should have a dependency on libfoo_vendor_ramdisk") + } +} + // Test that shared libraries cannot be made vendor available until proper support is added. func TestForbiddenVendorLinkage(t *testing.T) { - testRustError(t, "can only be set for rust_ffi_static modules", ` + testRustError(t, "cannot be set for rust_ffi or rust_ffi_shared modules.", ` rust_ffi_shared { name: "libfoo_vendor", crate_name: "foo", @@ -54,6 +78,14 @@ func TestForbiddenVendorLinkage(t *testing.T) { vendor_available: true, } `) + testRustError(t, "cannot be set for rust_ffi or rust_ffi_shared modules.", ` + rust_ffi_shared { + name: "libfoo_vendor", + crate_name: "foo", + srcs: ["foo.rs"], + vendor_ramdisk_available: true, + } + `) testRustError(t, "Rust vendor specific modules are currently only supported for rust_ffi_static modules.", ` rust_ffi { name: "libfoo_vendor", @@ -70,4 +102,13 @@ func TestForbiddenVendorLinkage(t *testing.T) { vendor: true, } `) + testRustError(t, "Rust vendor specific modules are currently only supported for rust_ffi_static modules.", ` + rust_binary { + name: "foo_vendor", + crate_name: "foo", + srcs: ["foo.rs"], + vendor: true, + } + `) + } diff --git a/rust/rust.go b/rust/rust.go index e1af77692..47db1cebb 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -74,8 +74,16 @@ type BaseProperties struct { SubName string `blueprint:"mutated"` // Set by imageMutator - CoreVariantNeeded bool `blueprint:"mutated"` - ExtraVariants []string `blueprint:"mutated"` + CoreVariantNeeded bool `blueprint:"mutated"` + VendorRamdiskVariantNeeded bool `blueprint:"mutated"` + ExtraVariants []string `blueprint:"mutated"` + + // Make this module available when building for vendor ramdisk. + // On device without a dedicated recovery partition, the module is only + // available after switching root into + // /first_stage_ramdisk. To expose the module before switching root, install + // the recovery variant instead (TODO(b/165791368) recovery not yet supported) + Vendor_ramdisk_available *bool // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). Min_sdk_version *string @@ -658,7 +666,9 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { // Differentiate static libraries that are vendor available if mod.UseVndk() { - mod.Properties.SubName += ".vendor" + mod.Properties.SubName += cc.VendorSuffix + } else if mod.InVendorRamdisk() && !mod.OnlyInVendorRamdisk() { + mod.Properties.SubName += cc.VendorRamdiskSuffix } if !toolchain.Supported() { diff --git a/rust/testing.go b/rust/testing.go index bb511b648..4c4df4a6d 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -101,6 +101,7 @@ func GatherRequiredDepsForTest() string { no_stdlibs: true, host_supported: true, vendor_available: true, + vendor_ramdisk_available: true, native_coverage: false, sysroot: true, apex_available: ["//apex_available:platform", "//apex_available:anyapex"], @@ -113,6 +114,7 @@ func GatherRequiredDepsForTest() string { no_stdlibs: true, host_supported: true, vendor_available: true, + vendor_ramdisk_available: true, native_coverage: false, sysroot: true, apex_available: ["//apex_available:platform", "//apex_available:anyapex"],