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/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)