Add support for cc_binary in module_exports
Bug: 142920869
Test: m nothing
Change-Id: Ib7e16cb323806782c2186e73e13642e4485fc149
diff --git a/Android.bp b/Android.bp
index f425c3f..2a4653a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -204,6 +204,7 @@
"cc/linker.go",
"cc/binary.go",
+ "cc/binary_sdk_member.go",
"cc/fuzz.go",
"cc/library.go",
"cc/library_sdk_member.go",
diff --git a/cc/binary.go b/cc/binary.go
index 280d17b..661264e 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -200,6 +200,11 @@
module.compiler = NewBaseCompiler()
module.linker = binary
module.installer = binary
+
+ // Allow module to be added as member of an sdk/module_exports.
+ module.sdkMemberTypes = []android.SdkMemberType{
+ ccBinarySdkMemberType,
+ }
return module, binary
}
diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go
new file mode 100644
index 0000000..53bc065
--- /dev/null
+++ b/cc/binary_sdk_member.go
@@ -0,0 +1,143 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// 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 cc
+
+import (
+ "path/filepath"
+
+ "android/soong/android"
+ "github.com/google/blueprint"
+)
+
+func init() {
+ android.RegisterSdkMemberType(ccBinarySdkMemberType)
+}
+
+var ccBinarySdkMemberType = &binarySdkMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "native_binaries",
+ },
+}
+
+type binarySdkMemberType struct {
+ android.SdkMemberTypeBase
+}
+
+func (mt *binarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ targets := mctx.MultiTargets()
+ for _, lib := range names {
+ for _, target := range targets {
+ name, version := StubsLibNameAndVersion(lib)
+ if version == "" {
+ version = LatestStubsVersionFor(mctx.Config(), name)
+ }
+ mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ }...), dependencyTag, name)
+ }
+ }
+}
+
+func (mt *binarySdkMemberType) IsInstance(module android.Module) bool {
+ // Check the module to see if it can be used with this module type.
+ if m, ok := module.(*Module); ok {
+ for _, allowableMemberType := range m.sdkMemberTypes {
+ if allowableMemberType == mt {
+ return true
+ }
+ }
+ }
+
+ return false
+}
+
+func (mt *binarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ info := mt.organizeVariants(member)
+ buildSharedNativeBinarySnapshot(info, builder, member)
+}
+
+// Organize the variants by architecture.
+func (mt *binarySdkMemberType) organizeVariants(member android.SdkMember) *nativeBinaryInfo {
+ memberName := member.Name()
+ info := &nativeBinaryInfo{
+ name: memberName,
+ memberType: mt,
+ }
+
+ for _, variant := range member.Variants() {
+ ccModule := variant.(*Module)
+
+ info.archVariantProperties = append(info.archVariantProperties, nativeBinaryInfoProperties{
+ name: memberName,
+ archType: ccModule.Target().Arch.ArchType.String(),
+ outputFile: ccModule.OutputFile().Path(),
+ })
+ }
+
+ // Initialize the unexported properties that will not be set during the
+ // extraction process.
+ info.commonProperties.name = memberName
+
+ // Extract common properties from the arch specific properties.
+ extractCommonProperties(&info.commonProperties, info.archVariantProperties)
+
+ return info
+}
+
+func buildSharedNativeBinarySnapshot(info *nativeBinaryInfo, builder android.SnapshotBuilder, member android.SdkMember) {
+ pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_binary")
+ pbm.AddProperty("compile_multilib", "both")
+ archProperties := pbm.AddPropertySet("arch")
+ for _, av := range info.archVariantProperties {
+ archTypeProperties := archProperties.AddPropertySet(av.archType)
+ archTypeProperties.AddProperty("srcs", []string{nativeBinaryPathFor(av)})
+
+ builder.CopyToSnapshot(av.outputFile, nativeBinaryPathFor(av))
+ }
+}
+
+const (
+ nativeBinaryDir = "bin"
+)
+
+// path to the native binary. Relative to <sdk_root>/<api_dir>
+func nativeBinaryPathFor(lib nativeBinaryInfoProperties) string {
+ return filepath.Join(lib.archType,
+ nativeBinaryDir, lib.outputFile.Base())
+}
+
+// nativeBinaryInfoProperties represents properties of a native binary
+//
+// The exported (capitalized) fields will be examined and may be changed during common value extraction.
+// The unexported fields will be left untouched.
+type nativeBinaryInfoProperties struct {
+ // The name of the library, is not exported as this must not be changed during optimization.
+ name string
+
+ // archType is not exported as if set (to a non default value) it is always arch specific.
+ // This is "" for common properties.
+ archType string
+
+ // outputFile is not exported as it is always arch specific.
+ outputFile android.Path
+}
+
+// nativeBinaryInfo represents a collection of arch-specific modules having the same name
+type nativeBinaryInfo struct {
+ name string
+ memberType *binarySdkMemberType
+ archVariantProperties []nativeBinaryInfoProperties
+ commonProperties nativeBinaryInfoProperties
+}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 9a75610..8c32d8c 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -337,6 +337,68 @@
)
}
+func TestSnapshotWithCcBinary(t *testing.T) {
+ result := testSdkWithCc(t, `
+ module_exports {
+ name: "mymodule_exports",
+ native_binaries: ["mynativebinary"],
+ }
+
+ cc_binary {
+ name: "mynativebinary",
+ srcs: [
+ "Test.cpp",
+ ],
+ compile_multilib: "both",
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mymodule_exports", "android_common", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_binary {
+ name: "mymodule_exports_mynativebinary@current",
+ sdk_member_name: "mynativebinary",
+ compile_multilib: "both",
+ arch: {
+ arm64: {
+ srcs: ["arm64/bin/mynativebinary"],
+ },
+ arm: {
+ srcs: ["arm/bin/mynativebinary"],
+ },
+ },
+}
+
+cc_prebuilt_binary {
+ name: "mynativebinary",
+ prefer: false,
+ compile_multilib: "both",
+ arch: {
+ arm64: {
+ srcs: ["arm64/bin/mynativebinary"],
+ },
+ arm: {
+ srcs: ["arm/bin/mynativebinary"],
+ },
+ },
+}
+
+module_exports_snapshot {
+ name: "mymodule_exports@current",
+ native_binaries: ["mymodule_exports_mynativebinary@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativebinary/android_arm64_armv8-a/mynativebinary -> arm64/bin/mynativebinary
+.intermediates/mynativebinary/android_arm_armv7-a-neon/mynativebinary -> arm/bin/mynativebinary
+`),
+ )
+}
+
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
result := testSdkWithCc(t, `
sdk {