Rust rlib vendor snapshot support.
Adds support for snapshotting Rust rlibs. This allows us
vendor-specific code that uses rlib-only linkage until dylib
snapshot support is added.
Bug: 184042776
Test: m nothing # new Soong tests pass
Test: Example test Rust vendor module builds
Test: m dist vendor-snapshot # includes rlibs
Change-Id: I4976d3e1efec0ee778cc97730d45be471dffb678
diff --git a/rust/Android.bp b/rust/Android.bp
index 6398390..11069d1 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -32,6 +32,7 @@
"rust.go",
"sanitize.go",
"source_provider.go",
+ "snapshot_prebuilt.go",
"snapshot_utils.go",
"strip.go",
"test.go",
diff --git a/rust/image.go b/rust/image.go
index 6cfb42c..3b54f12 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -82,7 +82,12 @@
}
func (mod *Module) SnapshotVersion(mctx android.BaseModuleContext) string {
- panic("Rust modules do not support snapshotting: " + mod.BaseModuleName())
+ if snapshot, ok := mod.compiler.(cc.SnapshotInterface); ok {
+ return snapshot.Version()
+ } else {
+ mctx.ModuleErrorf("version is unknown for snapshot prebuilt")
+ return ""
+ }
}
func (mod *Module) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool {
@@ -110,7 +115,9 @@
}
func (mod *Module) IsSnapshotPrebuilt() bool {
- // Rust does not support prebuilts in its snapshots
+ if p, ok := mod.compiler.(cc.SnapshotInterface); ok {
+ return p.IsSnapshotPrebuilt()
+ }
return false
}
@@ -220,7 +227,9 @@
}
}
if vendorSpecific {
- mctx.PropertyErrorf("vendor", "Vendor-only non-rust_ffi Rust modules are not supported.")
+ if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() {
+ mctx.PropertyErrorf("vendor", "Vendor-only dylibs are not yet supported, use rust_library_rlib.")
+ }
}
cc.MutateImage(mctx, mod)
diff --git a/rust/library.go b/rust/library.go
index 7421817..1a56ef6 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -124,7 +124,8 @@
setStatic()
setSource()
- // Set libstd linkage
+ // libstd linkage functions
+ rlibStd() bool
setRlibStd()
setDylibStd()
@@ -195,6 +196,10 @@
library.MutatedProperties.VariantIsShared = false
}
+func (library *libraryDecorator) rlibStd() bool {
+ return library.MutatedProperties.VariantIsStaticStd
+}
+
func (library *libraryDecorator) setRlibStd() {
library.MutatedProperties.VariantIsStaticStd = true
}
@@ -680,9 +685,10 @@
dylib := modules[1].(*Module)
rlib.compiler.(libraryInterface).setRlibStd()
dylib.compiler.(libraryInterface).setDylibStd()
- if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation {
+ if dylib.ModuleBase.ImageVariation().Variation == android.VendorRamdiskVariation ||
+ strings.HasPrefix(dylib.ModuleBase.ImageVariation().Variation, cc.VendorVariationPrefix) {
// TODO(b/165791368)
- // Disable rlibs that link against dylib-std on vendor ramdisk variations until those dylib
+ // Disable rlibs that link against dylib-std on vendor and vendor ramdisk variations until those dylib
// variants are properly supported.
dylib.Disable()
}
diff --git a/rust/rust.go b/rust/rust.go
index 7a8687c..b8c8be5 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1209,10 +1209,14 @@
}
// rlibs
- actx.AddVariationDependencies(
- append(rlibDepVariations, []blueprint.Variation{
- {Mutator: "rust_libraries", Variation: rlibVariation}}...),
- rlibDepTag, deps.Rlibs...)
+ for _, lib := range deps.Rlibs {
+ depTag := rlibDepTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+
+ actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
+ {Mutator: "rust_libraries", Variation: rlibVariation},
+ }...), depTag, lib)
+ }
// dylibs
actx.AddVariationDependencies(
@@ -1224,9 +1228,13 @@
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
if autoDep.depTag == rlibDepTag {
- actx.AddVariationDependencies(
- append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
- autoDep.depTag, deps.Rustlibs...)
+ for _, lib := range deps.Rustlibs {
+ depTag := autoDep.depTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+ actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
+ {Mutator: "rust_libraries", Variation: autoDep.variation},
+ }...), depTag, lib)
+ }
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
@@ -1237,9 +1245,13 @@
// stdlibs
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
- actx.AddVariationDependencies(
- append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
- rlibDepTag, deps.Stdlibs...)
+ for _, lib := range deps.Stdlibs {
+ depTag := rlibDepTag
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+
+ actx.AddVariationDependencies(append(commonDepVariations, []blueprint.Variation{{Mutator: "rust_libraries", Variation: "rlib"}}...),
+ depTag, lib)
+ }
} else {
actx.AddVariationDependencies(
append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: "dylib"}),
diff --git a/rust/rust_test.go b/rust/rust_test.go
index f07f86b..80f693e 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -59,6 +59,7 @@
"liby.so": nil,
"libz.so": nil,
"data.txt": nil,
+ "liblog.map.txt": nil,
}
// testRust returns a TestContext in which a basic environment has been setup.
@@ -77,18 +78,25 @@
return testRustVndkFs(t, bp, rustMockedFiles)
}
-const vendorVariant = "android_vendor.29_arm64_armv8-a_shared"
+const (
+ sharedVendorVariant = "android_vendor.29_arm64_armv8-a_shared"
+ rlibVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std"
+)
func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext {
+ return testRustVndkFsVersions(t, bp, fs, "current", "current", "29")
+}
+
+func testRustVndkFsVersions(t *testing.T, bp string, fs android.MockFS, device_version, product_version, vndk_version string) *android.TestContext {
skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers(
prepareForRustTest,
fs.AddToFixture(),
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
- variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
- variables.Platform_vndk_version = StringPtr("29")
+ variables.DeviceVndkVersion = StringPtr(device_version)
+ variables.ProductVndkVersion = StringPtr(product_version)
+ variables.Platform_vndk_version = StringPtr(vndk_version)
},
),
).RunTestWithBp(t, bp)
diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go
new file mode 100644
index 0000000..2f54973
--- /dev/null
+++ b/rust/snapshot_prebuilt.go
@@ -0,0 +1,121 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package rust
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ snapshotRlibSuffix = "_rlib."
+)
+
+type snapshotLibraryDecorator struct {
+ cc.BaseSnapshotDecorator
+ *libraryDecorator
+ properties cc.SnapshotLibraryProperties
+ sanitizerProperties struct {
+ CfiEnabled bool `blueprint:"mutated"`
+
+ // Library flags for cfi variant.
+ Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
+ }
+}
+
+func init() {
+ registerRustSnapshotModules(android.InitRegistrationContext)
+}
+
+func registerRustSnapshotModules(ctx android.RegistrationContext) {
+ cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
+ "vendor_snapshot_rlib", VendorSnapshotRlibFactory)
+}
+
+func snapshotLibraryFactory(image cc.SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
+ module, library := NewRustLibrary(android.DeviceSupported)
+
+ module.sanitize = nil
+ library.stripper.StripProperties.Strip.None = proptools.BoolPtr(true)
+
+ prebuilt := &snapshotLibraryDecorator{
+ libraryDecorator: library,
+ }
+
+ module.compiler = prebuilt
+
+ prebuilt.Init(module, image, moduleSuffix)
+ module.AddProperties(
+ &prebuilt.properties,
+ &prebuilt.sanitizerProperties,
+ )
+
+ return module, prebuilt
+}
+
+func (library *snapshotLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
+ var variant string
+ if library.static() {
+ variant = cc.SnapshotStaticSuffix
+ } else if library.shared() {
+ variant = cc.SnapshotSharedSuffix
+ } else if library.rlib() {
+ variant = cc.SnapshotRlibSuffix
+ }
+
+ if !library.dylib() {
+ // TODO(184042776): Remove this check when dylibs are supported in snapshots.
+ library.SetSnapshotAndroidMkSuffix(ctx, variant)
+ }
+
+ if !library.MatchesWithDevice(ctx.DeviceConfig()) {
+ return nil
+ }
+
+ return android.PathForModuleSrc(ctx, *library.properties.Src)
+}
+
+func (library *snapshotLibraryDecorator) rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath {
+ return android.OptionalPath{}
+}
+
+// vendor_snapshot_rlib is a special prebuilt rlib library which is auto-generated by
+// development/vendor_snapshot/update.py. As a part of vendor snapshot, vendor_snapshot_rlib
+// overrides the vendor variant of the rust rlib library with the same name, if BOARD_VNDK_VERSION
+// is set.
+func VendorSnapshotRlibFactory() android.Module {
+ module, prebuilt := snapshotLibraryFactory(cc.VendorSnapshotImageSingleton, cc.SnapshotRlibSuffix)
+ prebuilt.libraryDecorator.BuildOnlyRlib()
+ prebuilt.libraryDecorator.setNoStdlibs()
+ return module.Init()
+}
+
+func (library *snapshotLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
+ arches := config.Arches()
+ if len(arches) == 0 || arches[0].ArchType.String() != library.Arch() {
+ return false
+ }
+ if library.properties.Src == nil {
+ return false
+ }
+ return true
+}
+
+func (library *snapshotLibraryDecorator) IsSnapshotPrebuilt() bool {
+ return true
+}
+
+var _ cc.SnapshotInterface = (*snapshotLibraryDecorator)(nil)
diff --git a/rust/snapshot_utils.go b/rust/snapshot_utils.go
index 9d5154c..bd7ca7f 100644
--- a/rust/snapshot_utils.go
+++ b/rust/snapshot_utils.go
@@ -42,9 +42,8 @@
func (mod *Module) IsSnapshotLibrary() bool {
if lib, ok := mod.compiler.(libraryInterface); ok {
- // Rust-native dylibs and rlibs are not snapshot supported yet, so only
- // return true if this module produces a C shared or static library.
- return lib.shared() || lib.static()
+ // Rust-native dylibs are not snapshot supported yet. Only snapshot the rlib-std variants of rlibs.
+ return lib.shared() || lib.static() || (lib.rlib() && lib.rlibStd())
}
return false
}
diff --git a/rust/testing.go b/rust/testing.go
index a7cbf54..72f87e1 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -135,6 +135,9 @@
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
vendor_available: true,
+ llndk: {
+ symbol_file: "liblog.map.txt",
+ },
}
cc_library {
name: "libprotobuf-cpp-full",
@@ -245,4 +248,5 @@
ctx.BottomUp("rust_begin", BeginMutator).Parallel()
})
ctx.RegisterSingletonType("rust_project_generator", rustProjectGeneratorSingleton)
+ registerRustSnapshotModules(ctx)
}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index c5183f7..815f80e 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "reflect"
"strings"
"testing"
@@ -27,6 +28,22 @@
func TestVendorSnapshotCapture(t *testing.T) {
bp := `
rust_ffi {
+ name: "libffivendor_available",
+ crate_name: "ffivendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_ffi {
+ name: "libffivendor",
+ crate_name: "ffivendor",
+ srcs: ["lib.rs"],
+ vendor: true,
+ include_dirs: ["rust_headers/"],
+ }
+
+ rust_library {
name: "librustvendor_available",
crate_name: "rustvendor_available",
srcs: ["lib.rs"],
@@ -34,13 +51,26 @@
include_dirs: ["rust_headers/"],
}
+ rust_library_rlib {
+ name: "librustvendor",
+ crate_name: "rustvendor",
+ srcs: ["lib.rs"],
+ vendor: true,
+ include_dirs: ["rust_headers/"],
+ }
+
rust_binary {
name: "vendor_available_bin",
vendor_available: true,
srcs: ["srcs/lib.rs"],
}
-`
+ rust_binary {
+ name: "vendor_bin",
+ vendor: true,
+ srcs: ["srcs/lib.rs"],
+ }
+ `
skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers(
prepareForRustTest,
@@ -71,24 +101,40 @@
// For shared libraries, only non-VNDK vendor_available modules are captured
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
jsonFiles = append(jsonFiles,
- filepath.Join(sharedDir, "librustvendor_available.so.json"))
+ filepath.Join(sharedDir, "libffivendor_available.so.json"))
// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
staticVariant := fmt.Sprintf("android_vendor.29_%s_%s_static", archType, archVariant)
staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.a", staticDir, staticVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.a", staticDir, staticVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor", "libffivendor.a", staticDir, staticVariant)
jsonFiles = append(jsonFiles,
- filepath.Join(staticDir, "librustvendor_available.a.json"))
+ filepath.Join(staticDir, "libffivendor_available.a.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(staticDir, "libffivendor.a.json"))
- // For binary executables, all vendor_available modules are captured.
+ // For rlib libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor", "librustvendor.rlib", rlibDir, rlibVariant)
+ jsonFiles = append(jsonFiles,
+ filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(rlibDir, "librustvendor.rlib.json"))
+
+ // For binary executables, all vendor:true and vendor_available modules are captured.
if archType == "arm64" {
binaryVariant := fmt.Sprintf("android_vendor.29_%s_%s", archType, archVariant)
binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
jsonFiles = append(jsonFiles,
filepath.Join(binaryDir, "vendor_available_bin.json"))
+ jsonFiles = append(jsonFiles,
+ filepath.Join(binaryDir, "vendor_bin.json"))
}
}
@@ -113,6 +159,13 @@
func TestVendorSnapshotDirected(t *testing.T) {
bp := `
rust_ffi_shared {
+ name: "libffivendor_available",
+ crate_name: "ffivendor_available",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+
+ rust_library {
name: "librustvendor_available",
crate_name: "rustvendor_available",
srcs: ["lib.rs"],
@@ -120,6 +173,13 @@
}
rust_ffi_shared {
+ name: "libffivendor_exclude",
+ crate_name: "ffivendor_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ }
+
+ rust_library {
name: "librustvendor_exclude",
crate_name: "rustvendor_exclude",
srcs: ["lib.rs"],
@@ -129,6 +189,7 @@
ctx := testRustVndk(t, bp)
ctx.Config().TestProductVariables.VendorSnapshotModules = make(map[string]bool)
ctx.Config().TestProductVariables.VendorSnapshotModules["librustvendor_available"] = true
+ ctx.Config().TestProductVariables.VendorSnapshotModules["libffivendor_available"] = true
ctx.Config().TestProductVariables.DirectedVendorSnapshot = true
// Check Vendor snapshot output.
@@ -148,16 +209,22 @@
archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
// Included modules
- cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_available.so.json"))
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librustvendor_available", "librustvendor_available.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "libffivendor_available", "libffivendor_available.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_available.rlib.json"))
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_available.so.json"))
// Excluded modules. Modules not included in the directed vendor snapshot
// are still include as fake modules.
- cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.so", sharedDir, sharedVariant)
- includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "librustvendor_exclude.so.json"))
+ cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "librustvendor_exclude", "librustvendor_exclude.rlib", rlibDir, rlibVariant)
+ cc.CheckSnapshotRule(t, ctx, snapshotSingleton, "libffivendor_exclude", "libffivendor_exclude.so", sharedDir, sharedVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librustvendor_exclude.rlib.json"))
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libffivendor_exclude.so.json"))
}
// Verify that each json file for an included module has a rule.
@@ -176,10 +243,6 @@
// excluded in the vendor snapshot based on their path (framework or
// vendor) and the exclude_from_vendor_snapshot property.
- // When vendor-specific Rust modules are available, make sure to test
- // that they're excluded by path here. See cc.TestVendorSnapshotExclude
- // for an example.
-
frameworkBp := `
rust_ffi_shared {
name: "libinclude",
@@ -192,7 +255,7 @@
name: "libexclude",
crate_name: "exclude",
srcs: ["exclude.rs"],
- vendor_available: true,
+ vendor: true,
exclude_from_vendor_snapshot: true,
}
@@ -203,6 +266,29 @@
vendor_available: true,
exclude_from_vendor_snapshot: true,
}
+
+ rust_library {
+ name: "librust_include",
+ crate_name: "rust_include",
+ srcs: ["include.rs"],
+ vendor_available: true,
+ }
+
+ rust_library_rlib {
+ name: "librust_exclude",
+ crate_name: "rust_exclude",
+ srcs: ["exclude.rs"],
+ vendor: true,
+ exclude_from_vendor_snapshot: true,
+ }
+
+ rust_library {
+ name: "librust_available_exclude",
+ crate_name: "rust_available_exclude",
+ srcs: ["lib.rs"],
+ vendor_available: true,
+ exclude_from_vendor_snapshot: true,
+ }
`
mockFS := map[string][]byte{
@@ -214,9 +300,13 @@
ctx := testRustVndkFs(t, "", mockFS)
// Test an include and exclude framework module.
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, vendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, vendorVariant)
- cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, vendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false, sharedVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true, sharedVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true, sharedVendorVariant)
+
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_include", false, rlibVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_exclude", true, rlibVendorVariant)
+ cc.AssertExcludeFromVendorSnapshotIs(t, ctx, "librust_available_exclude", true, rlibVendorVariant)
// Verify the content of the vendor snapshot.
@@ -237,16 +327,24 @@
sharedVariant := fmt.Sprintf("android_vendor.29_%s_%s_shared", archType, archVariant)
sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
+ rlibVariant := fmt.Sprintf("android_vendor.29_%s_%s_rlib_rlib-std", archType, archVariant)
+ rlibDir := filepath.Join(snapshotVariantPath, archDir, "rlib")
// Included modules
cc.CheckSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
+ cc.CheckSnapshot(t, ctx, snapshotSingleton, "librust_include", "librust_include.rlib", rlibDir, rlibVariant)
+ includeJsonFiles = append(includeJsonFiles, filepath.Join(rlibDir, "librust_include.rlib.json"))
// Excluded modules
cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_exclude", "librust_exclude.rlib", rlibDir, rlibVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_exclude.rlib.json"))
+ cc.CheckSnapshotExclude(t, ctx, snapshotSingleton, "librust_available_exclude", "librust_available_exclude.rlib", rlibDir, rlibVariant)
+ excludeJsonFiles = append(excludeJsonFiles, filepath.Join(rlibDir, "librust_available_exclude.rlib.json"))
}
// Verify that each json file for an included module has a rule.
@@ -263,3 +361,655 @@
}
}
}
+
+func TestVendorSnapshotUse(t *testing.T) {
+ frameworkBp := `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ cc_library {
+ name: "libvendor_available",
+ vendor_available: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ cc_library {
+ name: "lib32",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ compile_multilib: "32",
+ }
+
+ cc_library {
+ name: "lib64",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ compile_multilib: "64",
+ }
+
+ rust_binary {
+ name: "bin",
+ vendor: true,
+ srcs: ["bin.rs"],
+ }
+
+ rust_binary {
+ name: "bin32",
+ vendor: true,
+ compile_multilib: "32",
+ srcs: ["bin.rs"],
+ }
+`
+
+ vndkBp := `
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm64",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm64: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+
+ // old snapshot module which has to be ignored
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "26",
+ target_arch: "arm64",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm64: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+
+ // different arch snapshot which has to be ignored
+ vndk_prebuilt_shared {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm",
+ vendor_available: true,
+ product_available: true,
+ vndk: {
+ enabled: true,
+ },
+ arch: {
+ arm: {
+ srcs: ["libvndk.so"],
+ export_include_dirs: ["include/libvndk"],
+ },
+ },
+ }
+`
+
+ vendorProprietaryBp := `
+ cc_library {
+ name: "libvendor_without_snapshot",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ }
+
+ rust_library {
+ name: "librust_vendor_available",
+ crate_name: "rust_vendor",
+ vendor_available: true,
+ srcs: ["client.rs"],
+ }
+
+ rust_ffi_shared {
+ name: "libclient",
+ crate_name: "client",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor_available"],
+ static_libs: ["libvendor", "libvendor_without_snapshot"],
+ rustlibs: ["librust_vendor_available"],
+ arch: {
+ arm64: {
+ shared_libs: ["lib64"],
+ },
+ arm: {
+ shared_libs: ["lib32"],
+ },
+ },
+ srcs: ["client.rs"],
+ }
+
+ rust_library_rlib {
+ name: "libclient_rust",
+ crate_name: "client_rust",
+ vendor: true,
+ shared_libs: ["libvndk", "libvendor_available"],
+ static_libs: ["libvendor", "libvendor_without_snapshot"],
+ rustlibs: ["librust_vendor_available"],
+ arch: {
+ arm64: {
+ shared_libs: ["lib64"],
+ },
+ arm: {
+ shared_libs: ["lib32"],
+ },
+ },
+ srcs: ["client.rs"],
+ }
+
+ rust_binary {
+ name: "bin_without_snapshot",
+ vendor: true,
+ static_libs: ["libvndk"],
+ srcs: ["bin.rs"],
+ rustlibs: ["librust_vendor_available"],
+ }
+
+ vendor_snapshot {
+ name: "vendor_snapshot",
+ version: "30",
+ arch: {
+ arm64: {
+ vndk_libs: [
+ "libvndk",
+ ],
+ static_libs: [
+ "libvendor",
+ "libvndk",
+ "libclang_rt.builtins-aarch64-android",
+ ],
+ shared_libs: [
+ "libvendor_available",
+ "lib64",
+ ],
+ rlibs: [
+ "libstd",
+ "libtest",
+ "librust_vendor_available",
+ ],
+ binaries: [
+ "bin",
+ ],
+ objects: [
+ "crtend_so",
+ "crtbegin_so",
+ "crtbegin_dynamic",
+ "crtend_android"
+ ],
+ },
+ arm: {
+ vndk_libs: [
+ "libvndk",
+ ],
+ static_libs: [
+ "libvendor",
+ "libvndk",
+ "libclang_rt.builtins-arm-android",
+ ],
+ shared_libs: [
+ "libvendor_available",
+ "lib32",
+ ],
+ rlibs: [
+ "libstd",
+ "libtest",
+ "librust_vendor_available",
+ ],
+ binaries: [
+ "bin32",
+ ],
+ objects: [
+ "crtend_so",
+ "crtbegin_so",
+ "crtbegin_dynamic",
+ "crtend_android"
+ ],
+
+ },
+ }
+ }
+
+ vendor_snapshot_object {
+ name: "crtend_so",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtend_so.o",
+ },
+ arm: {
+ src: "crtend_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtbegin_so",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtbegin_so.o",
+ },
+ arm: {
+ src: "crtbegin_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_rlib {
+ name: "libstd",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ sysroot: true,
+ arch: {
+ arm64: {
+ src: "libstd.rlib",
+ },
+ arm: {
+ src: "libstd.rlib",
+ },
+ },
+ }
+
+ vendor_snapshot_rlib {
+ name: "libtest",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ sysroot: true,
+ arch: {
+ arm64: {
+ src: "libtest.rlib",
+ },
+ arm: {
+ src: "libtest.rlib",
+ },
+ },
+ }
+
+ vendor_snapshot_rlib {
+ name: "librust_vendor_available",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "librust_vendor_available.rlib",
+ },
+ arm: {
+ src: "librust_vendor_available.rlib",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtend_android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtend_so.o",
+ },
+ arm: {
+ src: "crtend_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_object {
+ name: "crtbegin_dynamic",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ stl: "none",
+ crt: true,
+ arch: {
+ arm64: {
+ src: "crtbegin_so.o",
+ },
+ arm: {
+ src: "crtbegin_so.o",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libvndk",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvndk.a",
+ },
+ arm: {
+ src: "libvndk.a",
+ },
+ },
+ shared_libs: ["libvndk"],
+ export_shared_lib_headers: ["libvndk"],
+ }
+
+ vendor_snapshot_static {
+ name: "libclang_rt.builtins-aarch64-android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libclang_rt.builtins-aarch64-android.a",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libclang_rt.builtins-arm-android",
+ version: "30",
+ target_arch: "arm64",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "libclang_rt.builtins-arm-android.a",
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "lib32",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "32",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "lib32.so",
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "lib64",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "lib64.so",
+ },
+ },
+ }
+ vendor_snapshot_shared {
+ name: "liblog",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "liblog.so",
+ },
+ },
+ }
+
+ vendor_snapshot_static {
+ name: "libvendor",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvendor.a",
+ export_include_dirs: ["include/libvendor"],
+ },
+ arm: {
+ src: "libvendor.a",
+ export_include_dirs: ["include/libvendor"],
+ },
+ },
+ }
+
+ vendor_snapshot_shared {
+ name: "libvendor_available",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "both",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "libvendor_available.so",
+ export_include_dirs: ["include/libvendor"],
+ },
+ arm: {
+ src: "libvendor_available.so",
+ export_include_dirs: ["include/libvendor"],
+ },
+ },
+ }
+
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "64",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+
+ vendor_snapshot_binary {
+ name: "bin32",
+ version: "30",
+ target_arch: "arm64",
+ compile_multilib: "32",
+ vendor: true,
+ arch: {
+ arm: {
+ src: "bin32",
+ },
+ },
+ }
+
+ // old snapshot module which has to be ignored
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "26",
+ target_arch: "arm64",
+ compile_multilib: "first",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+
+ // different arch snapshot which has to be ignored
+ vendor_snapshot_binary {
+ name: "bin",
+ version: "30",
+ target_arch: "arm",
+ compile_multilib: "first",
+ vendor: true,
+ arch: {
+ arm64: {
+ src: "bin",
+ },
+ },
+ }
+`
+
+ mockFS := android.MockFS{
+ "framework/Android.bp": []byte(frameworkBp),
+ "framework/bin.rs": nil,
+ "vendor/Android.bp": []byte(vendorProprietaryBp),
+ "vendor/bin": nil,
+ "vendor/bin32": nil,
+ "vendor/bin.rs": nil,
+ "vendor/client.rs": nil,
+ "vendor/include/libvndk/a.h": nil,
+ "vendor/include/libvendor/b.h": nil,
+ "vendor/libvndk.a": nil,
+ "vendor/libvendor.a": nil,
+ "vendor/libvendor.so": nil,
+ "vendor/lib32.so": nil,
+ "vendor/lib64.so": nil,
+ "vendor/liblog.so": nil,
+ "vendor/libstd.rlib": nil,
+ "vendor/libtest.rlib": nil,
+ "vendor/librust_vendor_available.rlib": nil,
+ "vendor/crtbegin_so.o": nil,
+ "vendor/crtend_so.o": nil,
+ "vendor/libclang_rt.builtins-aarch64-android.a": nil,
+ "vendor/libclang_rt.builtins-arm-android.a": nil,
+ "vndk/Android.bp": []byte(vndkBp),
+ "vndk/include/libvndk/a.h": nil,
+ "vndk/libvndk.so": nil,
+ }
+
+ sharedVariant := "android_vendor.30_arm64_armv8-a_shared"
+ rlibVariant := "android_vendor.30_arm64_armv8-a_rlib_rlib-std"
+ staticVariant := "android_vendor.30_arm64_armv8-a_static"
+ binaryVariant := "android_vendor.30_arm64_armv8-a"
+
+ shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared"
+ binary32Variant := "android_vendor.30_arm_armv7-a-neon"
+
+ ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
+
+ // libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
+ libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"]
+ for _, input := range [][]string{
+ []string{sharedVariant, "libvndk.vndk.30.arm64"},
+ []string{staticVariant, "libvendor.vendor_static.30.arm64"},
+ []string{staticVariant, "libvendor_without_snapshot"},
+ } {
+ outputPaths := cc.GetOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
+ if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
+ t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
+ }
+ }
+
+ libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
+ if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib64", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
+ if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot", "libclang_rt.builtins-aarch64-android.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkRlibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkRlibs
+ if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
+ }
+
+ libclientAndroidMkDylibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkDylibs
+ if len(libclientAndroidMkDylibs) > 0 {
+ t.Errorf("wanted libclient libclientAndroidMkDylibs [], got %q", libclientAndroidMkDylibs)
+ }
+
+ libclient32AndroidMkSharedLibs := ctx.ModuleForTests("libclient", shared32Variant).Module().(*Module).Properties.AndroidMkSharedLibs
+ if g, w := libclient32AndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor", "lib32", "liblog.vendor", "libc.vendor", "libm.vendor", "libdl.vendor"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
+ }
+
+ libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs
+ if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) {
+ t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g)
+ }
+
+ binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"]
+ libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
+ if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
+ t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
+ libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
+ }
+
+ // bin is installed by bin.vendor_binary.30.arm64
+ ctx.ModuleForTests("bin.vendor_binary.30.arm64", binaryVariant).Output("bin")
+
+ // bin32 is installed by bin32.vendor_binary.30.arm64
+ ctx.ModuleForTests("bin32.vendor_binary.30.arm64", binary32Variant).Output("bin32")
+
+ // bin_without_snapshot is installed by bin_without_snapshot
+ ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
+
+ // libvendor, libvendor_available and bin don't have vendor.30 variant
+ libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
+ if android.InList(sharedVariant, libvendorVariants) {
+ t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
+ }
+
+ libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
+ if android.InList(sharedVariant, libvendorAvailableVariants) {
+ t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
+ }
+
+ binVariants := ctx.ModuleVariantsForTests("bin")
+ if android.InList(binaryVariant, binVariants) {
+ t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
+ }
+}