Merge "Pass correct --image argument to oatdump."
diff --git a/Android.bp b/Android.bp
index 6910d75..f72d624 100644
--- a/Android.bp
+++ b/Android.bp
@@ -508,7 +508,10 @@
"sdk/update.go",
],
testSrcs: [
+ "sdk/cc_sdk_test.go",
+ "sdk/java_sdk_test.go",
"sdk/sdk_test.go",
+ "sdk/testing.go",
],
pluginFor: ["soong_build"],
}
diff --git a/android/sdk.go b/android/sdk.go
index 01e18ed..b9220ca 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -17,6 +17,7 @@
import (
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -31,9 +32,6 @@
MemberName() string
BuildWithSdks(sdks SdkRefs)
RequiredSdks() SdkRefs
-
- // Build a snapshot of the module.
- BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder)
}
// SdkRef refers to a version of an SDK
@@ -203,3 +201,56 @@
type BpModule interface {
BpPropertySet
}
+
+// An individual member of the SDK, includes all of the variants that the SDK
+// requires.
+type SdkMember interface {
+ // The name of the member.
+ Name() string
+
+ // All the variants required by the SDK.
+ Variants() []SdkAware
+}
+
+// Interface that must be implemented for every type that can be a member of an
+// sdk.
+//
+// The basic implementation should look something like this, where ModuleType is
+// the name of the module type being supported.
+//
+// var ModuleTypeSdkMemberType = newModuleTypeSdkMemberType()
+//
+// func newModuleTypeSdkMemberType() android.SdkMemberType {
+// return &moduleTypeSdkMemberType{}
+// }
+//
+// type moduleTypeSdkMemberType struct {
+// }
+//
+// ...methods...
+//
+type SdkMemberType interface {
+ // Add dependencies from the SDK module to all the variants the member
+ // contributes to the SDK. The exact set of variants required is determined
+ // by the SDK and its properties. The dependencies must be added with the
+ // supplied tag.
+ //
+ // The BottomUpMutatorContext provided is for the SDK module.
+ AddDependencies(mctx BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string)
+
+ // Return true if the supplied module is an instance of this member type.
+ //
+ // This is used to check the type of each variant before added to the
+ // SdkMember. Returning false will cause an error to be logged expaining that
+ // the module is not allowed in whichever sdk property it was added.
+ IsInstance(module Module) bool
+
+ // Build the snapshot for the SDK member
+ //
+ // The ModuleContext provided is for the SDK module, so information for
+ // variants in the supplied member can be accessed using the Other... methods.
+ //
+ // The SdkMember is guaranteed to contain variants for which the
+ // IsInstance(Module) method returned true.
+ BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember)
+}
diff --git a/cc/library.go b/cc/library.go
index 98cae3d..60b00b1 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -24,6 +24,7 @@
"strings"
"sync"
+ "github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
"android/soong/android"
@@ -1403,3 +1404,230 @@
return outputFile
}
+
+var LibrarySdkMemberType = &librarySdkMemberType{}
+
+type librarySdkMemberType struct {
+}
+
+func (mt *librarySdkMemberType) 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: "image", Variation: android.CoreVariation},
+ {Mutator: "link", Variation: "shared"},
+ {Mutator: "version", Variation: version},
+ }...), dependencyTag, name)
+ }
+ }
+}
+
+func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Module)
+ return ok
+}
+
+// copy exported header files and stub *.so files
+func (mt *librarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ info := organizeVariants(member)
+ buildSharedNativeLibSnapshot(sdkModuleContext, info, builder)
+}
+
+func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
+ // a function for emitting include dirs
+ printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
+ includeDirs := lib.exportedIncludeDirs
+ includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
+ if len(includeDirs) == 0 {
+ return
+ }
+ for _, dir := range includeDirs {
+ if _, gen := dir.(android.WritablePath); gen {
+ // generated headers are copied via exportedDeps. See below.
+ continue
+ }
+ targetDir := nativeIncludeDir
+ if info.hasArchSpecificFlags {
+ targetDir = filepath.Join(lib.archType, targetDir)
+ }
+
+ // TODO(jiyong) copy headers having other suffixes
+ headers, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.h", nil)
+ for _, file := range headers {
+ src := android.PathForSource(sdkModuleContext, file)
+ dest := filepath.Join(targetDir, file)
+ builder.CopyToSnapshot(src, dest)
+ }
+ }
+
+ genHeaders := lib.exportedDeps
+ for _, file := range genHeaders {
+ targetDir := nativeGeneratedIncludeDir
+ if info.hasArchSpecificFlags {
+ targetDir = filepath.Join(lib.archType, targetDir)
+ }
+ dest := filepath.Join(targetDir, lib.name, file.Rel())
+ builder.CopyToSnapshot(file, dest)
+ }
+ }
+
+ if !info.hasArchSpecificFlags {
+ printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
+ }
+
+ // for each architecture
+ for _, av := range info.archVariants {
+ builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
+
+ if info.hasArchSpecificFlags {
+ printExportedDirCopyCommandsForNativeLibs(av)
+ }
+ }
+
+ info.generatePrebuiltLibrary(sdkModuleContext, builder)
+}
+
+func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) {
+
+ // a function for emitting include dirs
+ addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
+ includeDirs := nativeIncludeDirPathsFor(lib, systemInclude, info.hasArchSpecificFlags)
+ if len(includeDirs) == 0 {
+ return
+ }
+ var propertyName string
+ if !systemInclude {
+ propertyName = "export_include_dirs"
+ } else {
+ propertyName = "export_system_include_dirs"
+ }
+ properties.AddProperty(propertyName, includeDirs)
+ }
+
+ pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
+
+ if !info.hasArchSpecificFlags {
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
+ }
+
+ archProperties := pbm.AddPropertySet("arch")
+ for _, av := range info.archVariants {
+ archTypeProperties := archProperties.AddPropertySet(av.archType)
+ archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
+ if info.hasArchSpecificFlags {
+ // export_* properties are added inside the arch: {<arch>: {...}} block
+ addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
+ }
+ }
+ pbm.AddProperty("stl", "none")
+ pbm.AddProperty("system_shared_libs", []string{})
+}
+
+const (
+ nativeIncludeDir = "include"
+ nativeGeneratedIncludeDir = "include_gen"
+ nativeStubDir = "lib"
+ nativeStubFileSuffix = ".so"
+)
+
+// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
+func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
+ return filepath.Join(lib.archType,
+ nativeStubDir, lib.name+nativeStubFileSuffix)
+}
+
+// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
+func nativeIncludeDirPathsFor(lib archSpecificNativeLibInfo, systemInclude bool, archSpecific bool) []string {
+ var result []string
+ var includeDirs []android.Path
+ if !systemInclude {
+ includeDirs = lib.exportedIncludeDirs
+ } else {
+ includeDirs = lib.exportedSystemIncludeDirs
+ }
+ for _, dir := range includeDirs {
+ var path string
+ if _, gen := dir.(android.WritablePath); gen {
+ path = filepath.Join(nativeGeneratedIncludeDir, lib.name)
+ } else {
+ path = filepath.Join(nativeIncludeDir, dir.String())
+ }
+ if archSpecific {
+ path = filepath.Join(lib.archType, path)
+ }
+ result = append(result, path)
+ }
+ return result
+}
+
+// archSpecificNativeLibInfo represents an arch-specific variant of a native lib
+type archSpecificNativeLibInfo struct {
+ name string
+ archType string
+ exportedIncludeDirs android.Paths
+ exportedSystemIncludeDirs android.Paths
+ exportedFlags []string
+ exportedDeps android.Paths
+ outputFile android.Path
+}
+
+func (lib *archSpecificNativeLibInfo) signature() string {
+ return fmt.Sprintf("%v %v %v %v",
+ lib.name,
+ lib.exportedIncludeDirs.Strings(),
+ lib.exportedSystemIncludeDirs.Strings(),
+ lib.exportedFlags)
+}
+
+// nativeLibInfo represents a collection of arch-specific modules having the same name
+type nativeLibInfo struct {
+ name string
+ archVariants []archSpecificNativeLibInfo
+ // hasArchSpecificFlags is set to true if modules for each architecture all have the same
+ // include dirs, flags, etc, in which case only those of the first arch is selected.
+ hasArchSpecificFlags bool
+}
+
+// Organize the variants by architecture.
+func organizeVariants(member android.SdkMember) *nativeLibInfo {
+ info := &nativeLibInfo{name: member.Name()}
+
+ for _, variant := range member.Variants() {
+ ccModule := variant.(*Module)
+
+ info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
+ name: ccModule.BaseModuleName(),
+ archType: ccModule.Target().Arch.ArchType.String(),
+ exportedIncludeDirs: ccModule.ExportedIncludeDirs(),
+ exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
+ exportedFlags: ccModule.ExportedFlags(),
+ exportedDeps: ccModule.ExportedDeps(),
+ outputFile: ccModule.OutputFile().Path(),
+ })
+ }
+
+ // Determine if include dirs and flags for each variant are different across arch-specific
+ // variants or not. And set hasArchSpecificFlags accordingly
+ // by default, include paths and flags are assumed to be the same across arches
+ info.hasArchSpecificFlags = false
+ oldSignature := ""
+ for _, av := range info.archVariants {
+ newSignature := av.signature()
+ if oldSignature == "" {
+ oldSignature = newSignature
+ }
+ if oldSignature != newSignature {
+ info.hasArchSpecificFlags = true
+ break
+ }
+ }
+
+ return info
+}
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 40986c3..ee04dfd 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -495,8 +495,7 @@
}
for _, f := range global.PatternsOnSystemOther {
- // See comment of SYSTEM_OTHER_ODEX_FILTER for details on the matching.
- if makefileMatch("/"+f, dexLocation) || makefileMatch(filepath.Join(SystemPartition, f), dexLocation) {
+ if makefileMatch(filepath.Join(SystemPartition, f), dexLocation) {
return true
}
}
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 254be0a..3264d6a 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -104,12 +104,13 @@
{module: productModule, expectedPartition: "product"},
},
},
+ // product/app/% only applies to product apps inside the system partition
{
patterns: []string{"app/%", "product/app/%"},
moduleTests: []moduleTest{
{module: systemModule, expectedPartition: "system_other/system"},
{module: systemProductModule, expectedPartition: "system_other/system/product"},
- {module: productModule, expectedPartition: "system_other/product"},
+ {module: productModule, expectedPartition: "product"},
},
},
}
@@ -129,7 +130,7 @@
}
if rule.Installs().String() != wantInstalls.String() {
- t.Errorf("\npatterns: %v\nwant installs:\n %v\ngot:\n %v", test.patterns, wantInstalls, rule.Installs())
+ t.Errorf("\nwant installs:\n %v\ngot:\n %v", wantInstalls, rule.Installs())
}
}
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 16e6921..45a72e1 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -19,6 +19,7 @@
"path/filepath"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -1973,7 +1974,27 @@
return module
}
-func (d *Droidstubs) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) {
+var DroidStubsSdkMemberType = &droidStubsSdkMemberType{}
+
+type droidStubsSdkMemberType struct {
+}
+
+func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *droidStubsSdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Droidstubs)
+ return ok
+}
+
+func (mt *droidStubsSdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ variants := member.Variants()
+ if len(variants) != 1 {
+ sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name())
+ }
+ variant := variants[0]
+ d, _ := variant.(*Droidstubs)
stubsSrcJar := d.stubsSrcJar
snapshotRelativeDir := filepath.Join("java", d.Name()+"_stubs_sources")
diff --git a/java/java.go b/java/java.go
index 9c0fcba..0334ca4 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1721,7 +1721,31 @@
return filepath.Join(javaStubDir, j.Name()+javaStubFileSuffix)
}
-func (j *Library) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) {
+var LibrarySdkMemberType = &librarySdkMemberType{}
+
+type librarySdkMemberType struct {
+}
+
+func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) {
+ mctx.AddVariationDependencies(nil, dependencyTag, names...)
+}
+
+func (mt *librarySdkMemberType) IsInstance(module android.Module) bool {
+ _, ok := module.(*Library)
+ return ok
+}
+
+func (mt *librarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
+ variants := member.Variants()
+ if len(variants) != 1 {
+ sdkModuleContext.ModuleErrorf("sdk contains %d variants of member %q but only one is allowed", len(variants), member.Name())
+ for _, variant := range variants {
+ sdkModuleContext.ModuleErrorf(" %q", variant)
+ }
+ }
+ variant := variants[0]
+ j := variant.(*Library)
+
headerJars := j.HeaderJars()
if len(headerJars) != 1 {
panic(fmt.Errorf("there must be only one header jar from %q", j.Name()))
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
new file mode 100644
index 0000000..315669a
--- /dev/null
+++ b/sdk/cc_sdk_test.go
@@ -0,0 +1,340 @@
+// Copyright (C) 2019 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 sdk
+
+import (
+ "testing"
+
+ "android/soong/cc"
+)
+
+func testSdkWithCc(t *testing.T, bp string) *testSdkResult {
+ t.Helper()
+
+ fs := map[string][]byte{
+ "Test.cpp": nil,
+ "include/Test.h": nil,
+ "libfoo.so": nil,
+ "aidl/foo/bar/Test.aidl": nil,
+ }
+ return testSdkWithFs(t, bp, fs)
+}
+
+// Contains tests for SDK members provided by the cc package.
+
+func TestSdkIsCompileMultilibBoth(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["sdkmember"],
+ }
+
+ cc_library_shared {
+ name: "sdkmember",
+ srcs: ["Test.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ armOutput := result.Module("sdkmember", "android_arm_armv7-a-neon_core_shared").(*cc.Module).OutputFile()
+ arm64Output := result.Module("sdkmember", "android_arm64_armv8-a_core_shared").(*cc.Module).OutputFile()
+
+ var inputs []string
+ buildParams := result.Module("mysdk", "android_common").BuildParamsForTests()
+ for _, bp := range buildParams {
+ if bp.Input != nil {
+ inputs = append(inputs, bp.Input.String())
+ }
+ }
+
+ // ensure that both 32/64 outputs are inputs of the sdk snapshot
+ ensureListContains(t, inputs, armOutput.String())
+ ensureListContains(t, inputs, arm64Output.String())
+}
+
+func TestBasicSdkWithCc(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["sdkmember"],
+ }
+
+ sdk_snapshot {
+ name: "mysdk@1",
+ native_shared_libs: ["sdkmember_mysdk_1"],
+ }
+
+ sdk_snapshot {
+ name: "mysdk@2",
+ native_shared_libs: ["sdkmember_mysdk_2"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "sdkmember",
+ srcs: ["libfoo.so"],
+ prefer: false,
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_prebuilt_library_shared {
+ name: "sdkmember_mysdk_1",
+ sdk_member_name: "sdkmember",
+ srcs: ["libfoo.so"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_prebuilt_library_shared {
+ name: "sdkmember_mysdk_2",
+ sdk_member_name: "sdkmember",
+ srcs: ["libfoo.so"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library_shared {
+ name: "mycpplib",
+ srcs: ["Test.cpp"],
+ shared_libs: ["sdkmember"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ apex {
+ name: "myapex",
+ native_shared_libs: ["mycpplib"],
+ uses_sdks: ["mysdk@1"],
+ key: "myapex.key",
+ certificate: ":myapex.cert",
+ }
+
+ apex {
+ name: "myapex2",
+ native_shared_libs: ["mycpplib"],
+ uses_sdks: ["mysdk@2"],
+ key: "myapex.key",
+ certificate: ":myapex.cert",
+ }
+ `)
+
+ sdkMemberV1 := result.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_core_shared_myapex").Rule("toc").Output
+ sdkMemberV2 := result.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_core_shared_myapex2").Rule("toc").Output
+
+ cpplibForMyApex := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex")
+ cpplibForMyApex2 := result.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex2")
+
+ // Depending on the uses_sdks value, different libs are linked
+ ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
+ ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
+}
+
+func TestSnapshotWithCcShared(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["mynativelib"],
+ }
+
+ cc_library_shared {
+ name: "mynativelib",
+ srcs: [
+ "Test.cpp",
+ "aidl/foo/bar/Test.aidl",
+ ],
+ export_include_dirs: ["include"],
+ aidl: {
+ export_aidl_headers: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "android_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_mynativelib@current",
+ sdk_member_name: "mynativelib",
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "arm64/include/include",
+ "arm64/include_gen/mynativelib",
+ ],
+ },
+ arm: {
+ srcs: ["arm/lib/mynativelib.so"],
+ export_include_dirs: [
+ "arm/include/include",
+ "arm/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_shared {
+ name: "mynativelib",
+ prefer: false,
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "arm64/include/include",
+ "arm64/include_gen/mynativelib",
+ ],
+ },
+ arm: {
+ srcs: ["arm/lib/mynativelib.so"],
+ export_include_dirs: [
+ "arm/include/include",
+ "arm/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ native_shared_libs: ["mysdk_mynativelib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativelib/android_arm64_armv8-a_core_shared/mynativelib.so -> arm64/lib/mynativelib.so
+include/Test.h -> arm64/include/include/Test.h
+.intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/Test.h -> arm64/include_gen/mynativelib/aidl/foo/bar/Test.h
+.intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BnTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
+.intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BpTest.h -> arm64/include_gen/mynativelib/aidl/foo/bar/BpTest.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_core_shared/mynativelib.so -> arm/lib/mynativelib.so
+include/Test.h -> arm/include/include/Test.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_core_shared/gen/aidl/aidl/foo/bar/Test.h -> arm/include_gen/mynativelib/aidl/foo/bar/Test.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_core_shared/gen/aidl/aidl/foo/bar/BnTest.h -> arm/include_gen/mynativelib/aidl/foo/bar/BnTest.h
+.intermediates/mynativelib/android_arm_armv7-a-neon_core_shared/gen/aidl/aidl/foo/bar/BpTest.h -> arm/include_gen/mynativelib/aidl/foo/bar/BpTest.h
+`),
+ )
+}
+
+func TestHostSnapshotWithCcShared(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ device_supported: false,
+ host_supported: true,
+ native_shared_libs: ["mynativelib"],
+ }
+
+ cc_library_shared {
+ name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ srcs: [
+ "Test.cpp",
+ "aidl/foo/bar/Test.aidl",
+ ],
+ export_include_dirs: ["include"],
+ aidl: {
+ export_aidl_headers: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "linux_glibc_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_mynativelib@current",
+ sdk_member_name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86_64/include/include",
+ "x86_64/include_gen/mynativelib",
+ ],
+ },
+ x86: {
+ srcs: ["x86/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86/include/include",
+ "x86/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_shared {
+ name: "mynativelib",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86_64/include/include",
+ "x86_64/include_gen/mynativelib",
+ ],
+ },
+ x86: {
+ srcs: ["x86/lib/mynativelib.so"],
+ export_include_dirs: [
+ "x86/include/include",
+ "x86/include_gen/mynativelib",
+ ],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ native_shared_libs: ["mysdk_mynativelib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so -> x86_64/lib/mynativelib.so
+include/Test.h -> x86_64/include/include/Test.h
+.intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
+.intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
+.intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BpTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BpTest.h
+.intermediates/mynativelib/linux_glibc_x86_shared/mynativelib.so -> x86/lib/mynativelib.so
+include/Test.h -> x86/include/include/Test.h
+.intermediates/mynativelib/linux_glibc_x86_shared/gen/aidl/aidl/foo/bar/Test.h -> x86/include_gen/mynativelib/aidl/foo/bar/Test.h
+.intermediates/mynativelib/linux_glibc_x86_shared/gen/aidl/aidl/foo/bar/BnTest.h -> x86/include_gen/mynativelib/aidl/foo/bar/BnTest.h
+.intermediates/mynativelib/linux_glibc_x86_shared/gen/aidl/aidl/foo/bar/BpTest.h -> x86/include_gen/mynativelib/aidl/foo/bar/BpTest.h
+`),
+ )
+}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
new file mode 100644
index 0000000..e87a82c
--- /dev/null
+++ b/sdk/java_sdk_test.go
@@ -0,0 +1,352 @@
+// Copyright (C) 2019 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 sdk
+
+import (
+ "testing"
+)
+
+func testSdkWithJava(t *testing.T, bp string) *testSdkResult {
+ t.Helper()
+
+ fs := map[string][]byte{
+ "Test.java": nil,
+ "aidl/foo/bar/Test.aidl": nil,
+ }
+ return testSdkWithFs(t, bp, fs)
+}
+
+// Contains tests for SDK members provided by the java package.
+
+func TestBasicSdkWithJavaLibrary(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_libs: ["myjavalib"],
+ }
+
+ sdk_snapshot {
+ name: "mysdk@1",
+ java_libs: ["sdkmember_mysdk_1"],
+ }
+
+ sdk_snapshot {
+ name: "mysdk@2",
+ java_libs: ["sdkmember_mysdk_2"],
+ }
+
+ java_import {
+ name: "sdkmember",
+ prefer: false,
+ host_supported: true,
+ }
+
+ java_import {
+ name: "sdkmember_mysdk_1",
+ sdk_member_name: "sdkmember",
+ host_supported: true,
+ }
+
+ java_import {
+ name: "sdkmember_mysdk_2",
+ sdk_member_name: "sdkmember",
+ host_supported: true,
+ }
+
+ java_library {
+ name: "myjavalib",
+ srcs: ["Test.java"],
+ libs: ["sdkmember"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ host_supported: true,
+ }
+
+ apex {
+ name: "myapex",
+ java_libs: ["myjavalib"],
+ uses_sdks: ["mysdk@1"],
+ key: "myapex.key",
+ certificate: ":myapex.cert",
+ }
+
+ apex {
+ name: "myapex2",
+ java_libs: ["myjavalib"],
+ uses_sdks: ["mysdk@2"],
+ key: "myapex.key",
+ certificate: ":myapex.cert",
+ }
+ `)
+
+ sdkMemberV1 := result.ctx.ModuleForTests("sdkmember_mysdk_1", "android_common_myapex").Rule("combineJar").Output
+ sdkMemberV2 := result.ctx.ModuleForTests("sdkmember_mysdk_2", "android_common_myapex2").Rule("combineJar").Output
+
+ javalibForMyApex := result.ctx.ModuleForTests("myjavalib", "android_common_myapex")
+ javalibForMyApex2 := result.ctx.ModuleForTests("myjavalib", "android_common_myapex2")
+
+ // Depending on the uses_sdks value, different libs are linked
+ ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
+ ensureListContains(t, pathsToStrings(javalibForMyApex2.Rule("javac").Implicits), sdkMemberV2.String())
+}
+
+func TestSnapshotWithJavaLibrary(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_libs: ["myjavalib"],
+ }
+
+ java_library {
+ name: "myjavalib",
+ srcs: ["Test.java"],
+ aidl: {
+ export_include_dirs: ["aidl"],
+ },
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ host_supported: true,
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "android_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+ name: "myjavalib",
+ prefer: false,
+ jars: ["java/myjavalib.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ java_libs: ["mysdk_myjavalib@current"],
+}
+
+`),
+ checkAllCopyRules(`
+.intermediates/myjavalib/android_common/turbine-combined/myjavalib.jar -> java/myjavalib.jar
+aidl/foo/bar/Test.aidl -> aidl/aidl/foo/bar/Test.aidl
+`),
+ )
+}
+
+func TestHostSnapshotWithJavaLibrary(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ device_supported: false,
+ host_supported: true,
+ java_libs: ["myjavalib"],
+ }
+
+ java_library {
+ name: "myjavalib",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["Test.java"],
+ aidl: {
+ export_include_dirs: ["aidl"],
+ },
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "linux_glibc_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mysdk_myjavalib@current",
+ sdk_member_name: "myjavalib",
+ device_supported: false,
+ host_supported: true,
+ jars: ["java/myjavalib.jar"],
+}
+
+java_import {
+ name: "myjavalib",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ jars: ["java/myjavalib.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ java_libs: ["mysdk_myjavalib@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/myjavalib/linux_glibc_common/javac/myjavalib.jar -> java/myjavalib.jar
+aidl/foo/bar/Test.aidl -> aidl/aidl/foo/bar/Test.aidl
+`),
+ )
+}
+
+func testSdkWithDroidstubs(t *testing.T, bp string) *testSdkResult {
+ t.Helper()
+
+ fs := map[string][]byte{
+ "foo/bar/Foo.java": nil,
+ "stubs-sources/foo/bar/Foo.java": nil,
+ }
+ return testSdkWithFs(t, bp, fs)
+}
+
+// Note: This test does not verify that a droidstubs can be referenced, either
+// directly or indirectly from an APEX as droidstubs can never be a part of an
+// apex.
+func TestBasicSdkWithDroidstubs(t *testing.T) {
+ testSdkWithDroidstubs(t, `
+ sdk {
+ name: "mysdk",
+ stubs_sources: ["mystub"],
+ }
+ sdk_snapshot {
+ name: "mysdk@10",
+ stubs_sources: ["mystub_mysdk@10"],
+ }
+ prebuilt_stubs_sources {
+ name: "mystub_mysdk@10",
+ sdk_member_name: "mystub",
+ srcs: ["stubs-sources/foo/bar/Foo.java"],
+ }
+ droidstubs {
+ name: "mystub",
+ srcs: ["foo/bar/Foo.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ java_library {
+ name: "myjavalib",
+ srcs: [":mystub"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ `)
+}
+
+func TestSnapshotWithDroidstubs(t *testing.T) {
+ result := testSdkWithDroidstubs(t, `
+ sdk {
+ name: "mysdk",
+ stubs_sources: ["myjavaapistubs"],
+ }
+
+ droidstubs {
+ name: "myjavaapistubs",
+ srcs: ["foo/bar/Foo.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "android_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_stubs_sources {
+ name: "mysdk_myjavaapistubs@current",
+ sdk_member_name: "myjavaapistubs",
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+prebuilt_stubs_sources {
+ name: "myjavaapistubs",
+ prefer: false,
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ stubs_sources: ["mysdk_myjavaapistubs@current"],
+}
+
+`),
+ checkAllCopyRules(""),
+ checkMergeZip(".intermediates/mysdk/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
+ )
+}
+
+func TestHostSnapshotWithDroidstubs(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithDroidstubs(t, `
+ sdk {
+ name: "mysdk",
+ device_supported: false,
+ host_supported: true,
+ stubs_sources: ["myjavaapistubs"],
+ }
+
+ droidstubs {
+ name: "myjavaapistubs",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["foo/bar/Foo.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "linux_glibc_common",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+prebuilt_stubs_sources {
+ name: "mysdk_myjavaapistubs@current",
+ sdk_member_name: "myjavaapistubs",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+prebuilt_stubs_sources {
+ name: "myjavaapistubs",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ srcs: ["java/myjavaapistubs_stubs_sources"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ stubs_sources: ["mysdk_myjavaapistubs@current"],
+}
+`),
+ checkAllCopyRules(""),
+ checkMergeZip(".intermediates/mysdk/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"),
+ )
+}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 431ace9..75c8585 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -27,14 +27,25 @@
// registered before mutators in this package. See RegisterPostDepsMutators for more details.
_ "android/soong/apex"
"android/soong/cc"
+ "android/soong/java"
)
func init() {
pctx.Import("android/soong/android")
+ pctx.Import("android/soong/java/config")
+
android.RegisterModuleType("sdk", ModuleFactory)
android.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory)
android.PreDepsMutators(RegisterPreDepsMutators)
android.PostDepsMutators(RegisterPostDepsMutators)
+
+ // Populate the dependency tags for each member list property. This needs to
+ // be done here to break an initialization cycle.
+ for _, memberListProperty := range sdkMemberListProperties {
+ memberListProperty.dependencyTag = &sdkMemberDependencyTag{
+ memberListProperty: memberListProperty,
+ }
+ }
}
type sdk struct {
@@ -60,6 +71,52 @@
Snapshot bool `blueprint:"mutated"`
}
+type sdkMemberDependencyTag struct {
+ blueprint.BaseDependencyTag
+ memberListProperty *sdkMemberListProperty
+}
+
+// Contains information about the sdk properties that list sdk members, e.g.
+// Java_libs.
+type sdkMemberListProperty struct {
+ // the name of the property as used in a .bp file
+ name string
+
+ // getter for the list of member names
+ getter func(properties *sdkProperties) []string
+
+ // the type of member referenced in the list
+ memberType android.SdkMemberType
+
+ // the dependency tag used for items in this list.
+ dependencyTag *sdkMemberDependencyTag
+}
+
+// Information about how to handle each member list property.
+//
+// It is organized first by package and then by name within the package.
+// Packages are in alphabetical order and properties are in alphabetical order
+// within each package.
+var sdkMemberListProperties = []*sdkMemberListProperty{
+ // Members from cc package.
+ {
+ name: "native_shared_libs",
+ getter: func(properties *sdkProperties) []string { return properties.Native_shared_libs },
+ memberType: cc.LibrarySdkMemberType,
+ },
+ // Members from java package.
+ {
+ name: "java_libs",
+ getter: func(properties *sdkProperties) []string { return properties.Java_libs },
+ memberType: java.LibrarySdkMemberType,
+ },
+ {
+ name: "stubs_sources",
+ getter: func(properties *sdkProperties) []string { return properties.Stubs_sources },
+ memberType: java.DroidStubsSdkMemberType,
+ },
+}
+
// sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.)
// which Mainline modules like APEX can choose to build with.
func ModuleFactory() android.Module {
@@ -143,10 +200,6 @@
blueprint.BaseDependencyTag
}
-// For dependencies from an SDK module to its members
-// e.g. mysdk -> libfoo and libbar
-var sdkMemberDepTag dependencyTag
-
// For dependencies from an in-development version of an SDK member to frozen versions of the same member
// e.g. libfoo -> libfoo.mysdk.11 and libfoo.mysdk.12
type sdkMemberVesionedDepTag struct {
@@ -158,22 +211,10 @@
// Step 1: create dependencies from an SDK module to its members.
func memberMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*sdk); ok {
- mctx.AddVariationDependencies(nil, sdkMemberDepTag, m.properties.Java_libs...)
- mctx.AddVariationDependencies(nil, sdkMemberDepTag, m.properties.Stubs_sources...)
-
- targets := mctx.MultiTargets()
- for _, target := range targets {
- for _, lib := range m.properties.Native_shared_libs {
- name, version := cc.StubsLibNameAndVersion(lib)
- if version == "" {
- version = cc.LatestStubsVersionFor(mctx.Config(), name)
- }
- mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
- {Mutator: "image", Variation: android.CoreVariation},
- {Mutator: "link", Variation: "shared"},
- {Mutator: "version", Variation: version},
- }...), sdkMemberDepTag, name)
- }
+ for _, memberListProperty := range sdkMemberListProperties {
+ names := memberListProperty.getter(&m.properties)
+ tag := memberListProperty.dependencyTag
+ memberListProperty.memberType.AddDependencies(mctx, tag, names)
}
}
}
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 5435ef6..0a9dfb1 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -15,326 +15,12 @@
package sdk
import (
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
"testing"
-
- "android/soong/android"
- "android/soong/apex"
- "android/soong/cc"
- "android/soong/java"
)
-func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Config) {
- config := android.TestArchConfig(buildDir, nil)
- ctx := android.NewTestArchContext()
-
- // from android package
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
- })
- ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
- ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
- })
-
- // from java package
- ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
- ctx.RegisterModuleType("java_library", java.LibraryFactory)
- ctx.RegisterModuleType("java_import", java.ImportFactory)
- ctx.RegisterModuleType("droidstubs", java.DroidstubsFactory)
- ctx.RegisterModuleType("prebuilt_stubs_sources", java.PrebuiltStubsSourcesFactory)
-
- // from cc package
- ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
- ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
- ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
- ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
- ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
- ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
- ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
- ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("image", android.ImageMutator).Parallel()
- ctx.BottomUp("link", cc.LinkageMutator).Parallel()
- ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
- ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
- ctx.BottomUp("version", cc.VersionMutator).Parallel()
- ctx.BottomUp("begin", cc.BeginMutator).Parallel()
- })
-
- // from apex package
- ctx.RegisterModuleType("apex", apex.BundleFactory)
- ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
- ctx.PostDepsMutators(apex.RegisterPostDepsMutators)
-
- // from this package
- ctx.RegisterModuleType("sdk", ModuleFactory)
- ctx.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory)
- ctx.PreDepsMutators(RegisterPreDepsMutators)
- ctx.PostDepsMutators(RegisterPostDepsMutators)
-
- ctx.Register()
-
- bp = bp + `
- apex_key {
- name: "myapex.key",
- public_key: "myapex.avbpubkey",
- private_key: "myapex.pem",
- }
-
- android_app_certificate {
- name: "myapex.cert",
- certificate: "myapex",
- }
- ` + cc.GatherRequiredDepsForTest(android.Android)
-
- ctx.MockFileSystem(map[string][]byte{
- "Android.bp": []byte(bp),
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/myapex2-file_contexts": nil,
- "myapex.avbpubkey": nil,
- "myapex.pem": nil,
- "myapex.x509.pem": nil,
- "myapex.pk8": nil,
- "Test.java": nil,
- "Test.cpp": nil,
- "include/Test.h": nil,
- "aidl/foo/bar/Test.aidl": nil,
- "libfoo.so": nil,
- "stubs-sources/foo/bar/Foo.java": nil,
- "foo/bar/Foo.java": nil,
- })
-
- return ctx, config
-}
-
-func testSdk(t *testing.T, bp string) (*android.TestContext, android.Config) {
- ctx, config := testSdkContext(t, bp)
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
- return ctx, config
-}
-
-func testSdkError(t *testing.T, pattern, bp string) {
- t.Helper()
- ctx, config := testSdkContext(t, bp)
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
- if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, pattern, errs)
- return
- }
- _, errs = ctx.PrepareBuildActions(config)
- if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, pattern, errs)
- return
- }
-
- t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
-}
-
-func ensureListContains(t *testing.T, result []string, expected string) {
- t.Helper()
- if !android.InList(expected, result) {
- t.Errorf("%q is not found in %v", expected, result)
- }
-}
-
-func pathsToStrings(paths android.Paths) []string {
- ret := []string{}
- for _, p := range paths {
- ret = append(ret, p.String())
- }
- return ret
-}
-
-func TestBasicSdkWithJava(t *testing.T) {
- ctx, _ := testSdk(t, `
- sdk {
- name: "mysdk",
- java_libs: ["sdkmember"],
- }
-
- sdk_snapshot {
- name: "mysdk@1",
- java_libs: ["sdkmember_mysdk_1"],
- }
-
- sdk_snapshot {
- name: "mysdk@2",
- java_libs: ["sdkmember_mysdk_2"],
- }
-
- java_import {
- name: "sdkmember",
- prefer: false,
- host_supported: true,
- }
-
- java_import {
- name: "sdkmember_mysdk_1",
- sdk_member_name: "sdkmember",
- host_supported: true,
- }
-
- java_import {
- name: "sdkmember_mysdk_2",
- sdk_member_name: "sdkmember",
- host_supported: true,
- }
-
- java_library {
- name: "myjavalib",
- srcs: ["Test.java"],
- libs: ["sdkmember"],
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- host_supported: true,
- }
-
- apex {
- name: "myapex",
- java_libs: ["myjavalib"],
- uses_sdks: ["mysdk@1"],
- key: "myapex.key",
- certificate: ":myapex.cert",
- }
-
- apex {
- name: "myapex2",
- java_libs: ["myjavalib"],
- uses_sdks: ["mysdk@2"],
- key: "myapex.key",
- certificate: ":myapex.cert",
- }
- `)
-
- sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_common_myapex").Rule("combineJar").Output
- sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_common_myapex2").Rule("combineJar").Output
-
- javalibForMyApex := ctx.ModuleForTests("myjavalib", "android_common_myapex")
- javalibForMyApex2 := ctx.ModuleForTests("myjavalib", "android_common_myapex2")
-
- // Depending on the uses_sdks value, different libs are linked
- ensureListContains(t, pathsToStrings(javalibForMyApex.Rule("javac").Implicits), sdkMemberV1.String())
- ensureListContains(t, pathsToStrings(javalibForMyApex2.Rule("javac").Implicits), sdkMemberV2.String())
-}
-
-func TestBasicSdkWithCc(t *testing.T) {
- ctx, _ := testSdk(t, `
- sdk {
- name: "mysdk",
- native_shared_libs: ["sdkmember"],
- }
-
- sdk_snapshot {
- name: "mysdk@1",
- native_shared_libs: ["sdkmember_mysdk_1"],
- }
-
- sdk_snapshot {
- name: "mysdk@2",
- native_shared_libs: ["sdkmember_mysdk_2"],
- }
-
- cc_prebuilt_library_shared {
- name: "sdkmember",
- srcs: ["libfoo.so"],
- prefer: false,
- system_shared_libs: [],
- stl: "none",
- }
-
- cc_prebuilt_library_shared {
- name: "sdkmember_mysdk_1",
- sdk_member_name: "sdkmember",
- srcs: ["libfoo.so"],
- system_shared_libs: [],
- stl: "none",
- }
-
- cc_prebuilt_library_shared {
- name: "sdkmember_mysdk_2",
- sdk_member_name: "sdkmember",
- srcs: ["libfoo.so"],
- system_shared_libs: [],
- stl: "none",
- }
-
- cc_library_shared {
- name: "mycpplib",
- srcs: ["Test.cpp"],
- shared_libs: ["sdkmember"],
- system_shared_libs: [],
- stl: "none",
- }
-
- apex {
- name: "myapex",
- native_shared_libs: ["mycpplib"],
- uses_sdks: ["mysdk@1"],
- key: "myapex.key",
- certificate: ":myapex.cert",
- }
-
- apex {
- name: "myapex2",
- native_shared_libs: ["mycpplib"],
- uses_sdks: ["mysdk@2"],
- key: "myapex.key",
- certificate: ":myapex.cert",
- }
- `)
-
- sdkMemberV1 := ctx.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_core_shared_myapex").Rule("toc").Output
- sdkMemberV2 := ctx.ModuleForTests("sdkmember_mysdk_2", "android_arm64_armv8-a_core_shared_myapex2").Rule("toc").Output
-
- cpplibForMyApex := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex")
- cpplibForMyApex2 := ctx.ModuleForTests("mycpplib", "android_arm64_armv8-a_core_shared_myapex2")
-
- // Depending on the uses_sdks value, different libs are linked
- ensureListContains(t, pathsToStrings(cpplibForMyApex.Rule("ld").Implicits), sdkMemberV1.String())
- ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
-}
-
-// Note: This test does not verify that a droidstubs can be referenced, either
-// directly or indirectly from an APEX as droidstubs can never be a part of an
-// apex.
-func TestBasicSdkWithDroidstubs(t *testing.T) {
- testSdk(t, `
- sdk {
- name: "mysdk",
- stubs_sources: ["mystub"],
- }
- sdk_snapshot {
- name: "mysdk@10",
- stubs_sources: ["mystub_mysdk@10"],
- }
- prebuilt_stubs_sources {
- name: "mystub_mysdk@10",
- sdk_member_name: "mystub",
- srcs: ["stubs-sources/foo/bar/Foo.java"],
- }
- droidstubs {
- name: "mystub",
- srcs: ["foo/bar/Foo.java"],
- sdk_version: "none",
- system_modules: "none",
- }
- java_library {
- name: "myjavalib",
- srcs: [":mystub"],
- sdk_version: "none",
- system_modules: "none",
- }
- `)
+// Needed in an _test.go file in this package to ensure tests run correctly, particularly in IDE.
+func TestMain(m *testing.M) {
+ runTestWithBuildDir(m)
}
func TestDepNotInRequiredSdks(t *testing.T) {
@@ -393,440 +79,3 @@
}
`)
}
-
-func TestSdkIsCompileMultilibBoth(t *testing.T) {
- ctx, _ := testSdk(t, `
- sdk {
- name: "mysdk",
- native_shared_libs: ["sdkmember"],
- }
-
- cc_library_shared {
- name: "sdkmember",
- srcs: ["Test.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
- `)
-
- armOutput := ctx.ModuleForTests("sdkmember", "android_arm_armv7-a-neon_core_shared").Module().(*cc.Module).OutputFile()
- arm64Output := ctx.ModuleForTests("sdkmember", "android_arm64_armv8-a_core_shared").Module().(*cc.Module).OutputFile()
-
- var inputs []string
- buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
- for _, bp := range buildParams {
- if bp.Input != nil {
- inputs = append(inputs, bp.Input.String())
- }
- }
-
- // ensure that both 32/64 outputs are inputs of the sdk snapshot
- ensureListContains(t, inputs, armOutput.String())
- ensureListContains(t, inputs, arm64Output.String())
-}
-
-func TestSnapshot(t *testing.T) {
- ctx, config := testSdk(t, `
- sdk {
- name: "mysdk",
- java_libs: ["myjavalib"],
- native_shared_libs: ["mynativelib"],
- stubs_sources: ["myjavaapistubs"],
- }
-
- java_library {
- name: "myjavalib",
- srcs: ["Test.java"],
- aidl: {
- export_include_dirs: ["aidl"],
- },
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- host_supported: true,
- }
-
- cc_library_shared {
- name: "mynativelib",
- srcs: [
- "Test.cpp",
- "aidl/foo/bar/Test.aidl",
- ],
- export_include_dirs: ["include"],
- aidl: {
- export_aidl_headers: true,
- },
- system_shared_libs: [],
- stl: "none",
- }
-
- droidstubs {
- name: "myjavaapistubs",
- srcs: ["foo/bar/Foo.java"],
- system_modules: "none",
- sdk_version: "none",
- }
- `)
-
- sdk := ctx.ModuleForTests("mysdk", "android_common").Module().(*sdk)
-
- checkSnapshotAndroidBpContents(t, sdk, `// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "mysdk_myjavalib@current",
- sdk_member_name: "myjavalib",
- jars: ["java/myjavalib.jar"],
-}
-
-java_import {
- name: "myjavalib",
- prefer: false,
- jars: ["java/myjavalib.jar"],
-}
-
-prebuilt_stubs_sources {
- name: "mysdk_myjavaapistubs@current",
- sdk_member_name: "myjavaapistubs",
- srcs: ["java/myjavaapistubs_stubs_sources"],
-}
-
-prebuilt_stubs_sources {
- name: "myjavaapistubs",
- prefer: false,
- srcs: ["java/myjavaapistubs_stubs_sources"],
-}
-
-cc_prebuilt_library_shared {
- name: "mysdk_mynativelib@current",
- sdk_member_name: "mynativelib",
- arch: {
- arm64: {
- srcs: ["arm64/lib/mynativelib.so"],
- export_include_dirs: [
- "arm64/include/include",
- "arm64/include_gen/mynativelib",
- ],
- },
- arm: {
- srcs: ["arm/lib/mynativelib.so"],
- export_include_dirs: [
- "arm/include/include",
- "arm/include_gen/mynativelib",
- ],
- },
- },
- stl: "none",
- system_shared_libs: [],
-}
-
-cc_prebuilt_library_shared {
- name: "mynativelib",
- prefer: false,
- arch: {
- arm64: {
- srcs: ["arm64/lib/mynativelib.so"],
- export_include_dirs: [
- "arm64/include/include",
- "arm64/include_gen/mynativelib",
- ],
- },
- arm: {
- srcs: ["arm/lib/mynativelib.so"],
- export_include_dirs: [
- "arm/include/include",
- "arm/include_gen/mynativelib",
- ],
- },
- },
- stl: "none",
- system_shared_libs: [],
-}
-
-sdk_snapshot {
- name: "mysdk@current",
- java_libs: ["mysdk_myjavalib@current"],
- stubs_sources: ["mysdk_myjavaapistubs@current"],
- native_shared_libs: ["mysdk_mynativelib@current"],
-}
-
-`)
-
- var copySrcs []string
- var copyDests []string
- buildParams := sdk.BuildParamsForTests()
- var zipBp android.BuildParams
- for _, bp := range buildParams {
- ruleString := bp.Rule.String()
- if ruleString == "android/soong/android.Cp" {
- copySrcs = append(copySrcs, bp.Input.String())
- copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root
- } else if ruleString == "<local rule>:m.mysdk_android_common.snapshot" {
- zipBp = bp
- }
- }
-
- buildDir := config.BuildDir()
- ensureListContains(t, copySrcs, "aidl/foo/bar/Test.aidl")
- ensureListContains(t, copySrcs, "include/Test.h")
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BnTest.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/BpTest.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/gen/aidl/aidl/foo/bar/Test.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/myjavalib/android_common/turbine-combined/myjavalib.jar"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/android_arm64_armv8-a_core_shared/mynativelib.so"))
-
- ensureListContains(t, copyDests, "aidl/aidl/foo/bar/Test.aidl")
- ensureListContains(t, copyDests, "arm64/include/include/Test.h")
- ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BnTest.h")
- ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/BpTest.h")
- ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/Test.h")
- ensureListContains(t, copyDests, "java/myjavalib.jar")
- ensureListContains(t, copyDests, "arm64/lib/mynativelib.so")
-
- // Ensure that the droidstubs .srcjar as repackaged into a temporary zip file
- // and then merged together with the intermediate snapshot zip.
- snapshotCreationInputs := zipBp.Implicits.Strings()
- ensureListContains(t, snapshotCreationInputs,
- filepath.Join(buildDir, ".intermediates/mysdk/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"))
- ensureListContains(t, snapshotCreationInputs,
- filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.unmerged.zip"))
- actual := zipBp.Output.String()
- expected := filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.zip")
- if actual != expected {
- t.Errorf("Expected snapshot output to be %q but was %q", expected, actual)
- }
-}
-
-func TestHostSnapshot(t *testing.T) {
- // b/145598135 - Generating host snapshots for anything other than linux is not supported.
- SkipIfNotLinux(t)
-
- ctx, config := testSdk(t, `
- sdk {
- name: "mysdk",
- device_supported: false,
- host_supported: true,
- java_libs: ["myjavalib"],
- native_shared_libs: ["mynativelib"],
- stubs_sources: ["myjavaapistubs"],
- }
-
- java_library {
- name: "myjavalib",
- device_supported: false,
- host_supported: true,
- srcs: ["Test.java"],
- aidl: {
- export_include_dirs: ["aidl"],
- },
- system_modules: "none",
- sdk_version: "none",
- compile_dex: true,
- }
-
- cc_library_shared {
- name: "mynativelib",
- device_supported: false,
- host_supported: true,
- srcs: [
- "Test.cpp",
- "aidl/foo/bar/Test.aidl",
- ],
- export_include_dirs: ["include"],
- aidl: {
- export_aidl_headers: true,
- },
- system_shared_libs: [],
- stl: "none",
- }
-
- droidstubs {
- name: "myjavaapistubs",
- device_supported: false,
- host_supported: true,
- srcs: ["foo/bar/Foo.java"],
- system_modules: "none",
- sdk_version: "none",
- }
- `)
-
- sdk := ctx.ModuleForTests("mysdk", "linux_glibc_common").Module().(*sdk)
-
- checkSnapshotAndroidBpContents(t, sdk, `// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "mysdk_myjavalib@current",
- sdk_member_name: "myjavalib",
- device_supported: false,
- host_supported: true,
- jars: ["java/myjavalib.jar"],
-}
-
-java_import {
- name: "myjavalib",
- prefer: false,
- device_supported: false,
- host_supported: true,
- jars: ["java/myjavalib.jar"],
-}
-
-prebuilt_stubs_sources {
- name: "mysdk_myjavaapistubs@current",
- sdk_member_name: "myjavaapistubs",
- device_supported: false,
- host_supported: true,
- srcs: ["java/myjavaapistubs_stubs_sources"],
-}
-
-prebuilt_stubs_sources {
- name: "myjavaapistubs",
- prefer: false,
- device_supported: false,
- host_supported: true,
- srcs: ["java/myjavaapistubs_stubs_sources"],
-}
-
-cc_prebuilt_library_shared {
- name: "mysdk_mynativelib@current",
- sdk_member_name: "mynativelib",
- device_supported: false,
- host_supported: true,
- arch: {
- x86_64: {
- srcs: ["x86_64/lib/mynativelib.so"],
- export_include_dirs: [
- "x86_64/include/include",
- "x86_64/include_gen/mynativelib",
- ],
- },
- x86: {
- srcs: ["x86/lib/mynativelib.so"],
- export_include_dirs: [
- "x86/include/include",
- "x86/include_gen/mynativelib",
- ],
- },
- },
- stl: "none",
- system_shared_libs: [],
-}
-
-cc_prebuilt_library_shared {
- name: "mynativelib",
- prefer: false,
- device_supported: false,
- host_supported: true,
- arch: {
- x86_64: {
- srcs: ["x86_64/lib/mynativelib.so"],
- export_include_dirs: [
- "x86_64/include/include",
- "x86_64/include_gen/mynativelib",
- ],
- },
- x86: {
- srcs: ["x86/lib/mynativelib.so"],
- export_include_dirs: [
- "x86/include/include",
- "x86/include_gen/mynativelib",
- ],
- },
- },
- stl: "none",
- system_shared_libs: [],
-}
-
-sdk_snapshot {
- name: "mysdk@current",
- device_supported: false,
- host_supported: true,
- java_libs: ["mysdk_myjavalib@current"],
- stubs_sources: ["mysdk_myjavaapistubs@current"],
- native_shared_libs: ["mysdk_mynativelib@current"],
-}
-
-`)
-
- var copySrcs []string
- var copyDests []string
- buildParams := sdk.BuildParamsForTests()
- var zipBp android.BuildParams
- for _, bp := range buildParams {
- ruleString := bp.Rule.String()
- if ruleString == "android/soong/android.Cp" {
- copySrcs = append(copySrcs, bp.Input.String())
- copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root
- } else if ruleString == "<local rule>:m.mysdk_linux_glibc_common.snapshot" {
- zipBp = bp
- }
- }
-
- buildDir := config.BuildDir()
- ensureListContains(t, copySrcs, "aidl/foo/bar/Test.aidl")
- ensureListContains(t, copySrcs, "include/Test.h")
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BnTest.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/BpTest.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/gen/aidl/aidl/foo/bar/Test.h"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/myjavalib/linux_glibc_common/javac/myjavalib.jar"))
- ensureListContains(t, copySrcs, filepath.Join(buildDir, ".intermediates/mynativelib/linux_glibc_x86_64_shared/mynativelib.so"))
-
- ensureListContains(t, copyDests, "aidl/aidl/foo/bar/Test.aidl")
- ensureListContains(t, copyDests, "x86_64/include/include/Test.h")
- ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h")
- ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/BpTest.h")
- ensureListContains(t, copyDests, "x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h")
- ensureListContains(t, copyDests, "java/myjavalib.jar")
- ensureListContains(t, copyDests, "x86_64/lib/mynativelib.so")
-
- // Ensure that the droidstubs .srcjar as repackaged into a temporary zip file
- // and then merged together with the intermediate snapshot zip.
- snapshotCreationInputs := zipBp.Implicits.Strings()
- ensureListContains(t, snapshotCreationInputs,
- filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"))
- ensureListContains(t, snapshotCreationInputs,
- filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/mysdk-current.unmerged.zip"))
- actual := zipBp.Output.String()
- expected := filepath.Join(buildDir, ".intermediates/mysdk/linux_glibc_common/mysdk-current.zip")
- if actual != expected {
- t.Errorf("Expected snapshot output to be %q but was %q", expected, actual)
- }
-}
-
-func checkSnapshotAndroidBpContents(t *testing.T, s *sdk, expectedContents string) {
- t.Helper()
- androidBpContents := strings.NewReplacer("\\n", "\n").Replace(s.GetAndroidBpContentsForTests())
- if androidBpContents != expectedContents {
- t.Errorf("Android.bp contents do not match, expected %s, actual %s", expectedContents, androidBpContents)
- }
-}
-
-var buildDir string
-
-func setUp() {
- var err error
- buildDir, err = ioutil.TempDir("", "soong_sdk_test")
- if err != nil {
- panic(err)
- }
-}
-
-func tearDown() {
- os.RemoveAll(buildDir)
-}
-
-func TestMain(m *testing.M) {
- run := func() int {
- setUp()
- defer tearDown()
-
- return m.Run()
- }
-
- os.Exit(run())
-}
-
-func SkipIfNotLinux(t *testing.T) {
- t.Helper()
- if android.BuildOs != android.Linux {
- t.Skipf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs)
- }
-}
diff --git a/sdk/testing.go b/sdk/testing.go
new file mode 100644
index 0000000..47a58b1
--- /dev/null
+++ b/sdk/testing.go
@@ -0,0 +1,397 @@
+// Copyright 2019 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 sdk
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/apex"
+ "android/soong/cc"
+ "android/soong/java"
+)
+
+func testSdkContext(bp string, fs map[string][]byte) (*android.TestContext, android.Config) {
+ config := android.TestArchConfig(buildDir, nil)
+ ctx := android.NewTestArchContext()
+
+ // from android package
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
+ })
+ ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("prebuilt_select", android.PrebuiltSelectModuleMutator).Parallel()
+ ctx.BottomUp("prebuilt_postdeps", android.PrebuiltPostDepsMutator).Parallel()
+ })
+
+ // from java package
+ ctx.RegisterModuleType("android_app_certificate", java.AndroidAppCertificateFactory)
+ ctx.RegisterModuleType("java_library", java.LibraryFactory)
+ ctx.RegisterModuleType("java_import", java.ImportFactory)
+ ctx.RegisterModuleType("droidstubs", java.DroidstubsFactory)
+ ctx.RegisterModuleType("prebuilt_stubs_sources", java.PrebuiltStubsSourcesFactory)
+
+ // from cc package
+ ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("cc_library_shared", cc.LibrarySharedFactory)
+ ctx.RegisterModuleType("cc_object", cc.ObjectFactory)
+ ctx.RegisterModuleType("cc_prebuilt_library_shared", cc.PrebuiltSharedLibraryFactory)
+ ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
+ ctx.RegisterModuleType("llndk_library", cc.LlndkLibraryFactory)
+ ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory)
+ ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("image", android.ImageMutator).Parallel()
+ ctx.BottomUp("link", cc.LinkageMutator).Parallel()
+ ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
+ ctx.BottomUp("test_per_src", cc.TestPerSrcMutator).Parallel()
+ ctx.BottomUp("version", cc.VersionMutator).Parallel()
+ ctx.BottomUp("begin", cc.BeginMutator).Parallel()
+ })
+
+ // from apex package
+ ctx.RegisterModuleType("apex", apex.BundleFactory)
+ ctx.RegisterModuleType("apex_key", apex.ApexKeyFactory)
+ ctx.PostDepsMutators(apex.RegisterPostDepsMutators)
+
+ // from this package
+ ctx.RegisterModuleType("sdk", ModuleFactory)
+ ctx.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory)
+ ctx.PreDepsMutators(RegisterPreDepsMutators)
+ ctx.PostDepsMutators(RegisterPostDepsMutators)
+
+ ctx.Register()
+
+ bp = bp + `
+ apex_key {
+ name: "myapex.key",
+ public_key: "myapex.avbpubkey",
+ private_key: "myapex.pem",
+ }
+
+ android_app_certificate {
+ name: "myapex.cert",
+ certificate: "myapex",
+ }
+ ` + cc.GatherRequiredDepsForTest(android.Android)
+
+ mockFS := map[string][]byte{
+ "Android.bp": []byte(bp),
+ "build/make/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/myapex2-file_contexts": nil,
+ "myapex.avbpubkey": nil,
+ "myapex.pem": nil,
+ "myapex.x509.pem": nil,
+ "myapex.pk8": nil,
+ }
+
+ for k, v := range fs {
+ mockFS[k] = v
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ return ctx, config
+}
+
+func testSdkWithFs(t *testing.T, bp string, fs map[string][]byte) *testSdkResult {
+ t.Helper()
+ ctx, config := testSdkContext(bp, fs)
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+ return &testSdkResult{
+ TestHelper: TestHelper{t: t},
+ ctx: ctx,
+ config: config,
+ }
+}
+
+func testSdkError(t *testing.T, pattern, bp string) {
+ t.Helper()
+ ctx, config := testSdkContext(bp, nil)
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+ _, errs = ctx.PrepareBuildActions(config)
+ if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+
+ t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
+}
+
+func ensureListContains(t *testing.T, result []string, expected string) {
+ t.Helper()
+ if !android.InList(expected, result) {
+ t.Errorf("%q is not found in %v", expected, result)
+ }
+}
+
+func pathsToStrings(paths android.Paths) []string {
+ var ret []string
+ for _, p := range paths {
+ ret = append(ret, p.String())
+ }
+ return ret
+}
+
+// Provides general test support.
+type TestHelper struct {
+ t *testing.T
+}
+
+func (h *TestHelper) AssertStringEquals(message string, expected string, actual string) {
+ h.t.Helper()
+ if actual != expected {
+ h.t.Errorf("%s: expected %s, actual %s", message, expected, actual)
+ }
+}
+
+func (h *TestHelper) AssertTrimmedStringEquals(message string, expected string, actual string) {
+ h.t.Helper()
+ h.AssertStringEquals(message, strings.TrimSpace(expected), strings.TrimSpace(actual))
+}
+
+// Encapsulates result of processing an SDK definition. Provides support for
+// checking the state of the build structures.
+type testSdkResult struct {
+ TestHelper
+ ctx *android.TestContext
+ config android.Config
+}
+
+// Analyse the sdk build rules to extract information about what it is doing.
+
+// e.g. find the src/dest pairs from each cp command, the various zip files
+// generated, etc.
+func (r *testSdkResult) getSdkSnapshotBuildInfo(sdk *sdk) *snapshotBuildInfo {
+ androidBpContents := strings.NewReplacer("\\n", "\n").Replace(sdk.GetAndroidBpContentsForTests())
+
+ info := &snapshotBuildInfo{
+ r: r,
+ androidBpContents: androidBpContents,
+ }
+
+ buildParams := sdk.BuildParamsForTests()
+ copyRules := &strings.Builder{}
+ for _, bp := range buildParams {
+ switch bp.Rule.String() {
+ case android.Cp.String():
+ // Get source relative to build directory.
+ src := r.pathRelativeToBuildDir(bp.Input)
+ // Get destination relative to the snapshot root
+ dest := bp.Output.Rel()
+ _, _ = fmt.Fprintf(copyRules, "%s -> %s\n", src, dest)
+ info.snapshotContents = append(info.snapshotContents, dest)
+
+ case repackageZip.String():
+ // Add the destdir to the snapshot contents as that is effectively where
+ // the content of the repackaged zip is copied.
+ dest := bp.Args["destdir"]
+ info.snapshotContents = append(info.snapshotContents, dest)
+
+ case zipFiles.String():
+ // This could be an intermediate zip file and not the actual output zip.
+ // In that case this will be overridden when the rule to merge the zips
+ // is processed.
+ info.outputZip = r.pathRelativeToBuildDir(bp.Output)
+
+ case mergeZips.String():
+ // Copy the current outputZip to the intermediateZip.
+ info.intermediateZip = info.outputZip
+ mergeInput := r.pathRelativeToBuildDir(bp.Input)
+ if info.intermediateZip != mergeInput {
+ r.t.Errorf("Expected intermediate zip %s to be an input to merge zips but found %s instead",
+ info.intermediateZip, mergeInput)
+ }
+
+ // Override output zip (which was actually the intermediate zip file) with the actual
+ // output zip.
+ info.outputZip = r.pathRelativeToBuildDir(bp.Output)
+
+ // Save the zips to be merged into the intermediate zip.
+ info.mergeZips = r.pathsRelativeToBuildDir(bp.Inputs)
+ }
+ }
+
+ info.copyRules = copyRules.String()
+
+ return info
+}
+
+func (r *testSdkResult) Module(name string, variant string) android.Module {
+ return r.ctx.ModuleForTests(name, variant).Module()
+}
+
+func (r *testSdkResult) ModuleForTests(name string, variant string) android.TestingModule {
+ return r.ctx.ModuleForTests(name, variant)
+}
+
+func (r *testSdkResult) pathRelativeToBuildDir(path android.Path) string {
+ buildDir := filepath.Clean(r.config.BuildDir()) + "/"
+ return strings.TrimPrefix(filepath.Clean(path.String()), buildDir)
+}
+
+func (r *testSdkResult) pathsRelativeToBuildDir(paths android.Paths) []string {
+ var result []string
+ for _, path := range paths {
+ result = append(result, r.pathRelativeToBuildDir(path))
+ }
+ return result
+}
+
+// Check the snapshot build rules.
+//
+// Takes a list of functions which check different facets of the snapshot build rules.
+// Allows each test to customize what is checked without duplicating lots of code
+// or proliferating check methods of different flavors.
+func (r *testSdkResult) CheckSnapshot(name string, variant string, checkers ...snapshotBuildInfoChecker) {
+ r.t.Helper()
+
+ sdk := r.Module(name, variant).(*sdk)
+
+ snapshotBuildInfo := r.getSdkSnapshotBuildInfo(sdk)
+
+ // Check state of the snapshot build.
+ for _, checker := range checkers {
+ checker(snapshotBuildInfo)
+ }
+
+ // Make sure that the generated zip file is in the correct place.
+ actual := snapshotBuildInfo.outputZip
+ r.AssertStringEquals("Snapshot zip file in wrong place",
+ fmt.Sprintf(".intermediates/%s/%s/%s-current.zip", name, variant, name), actual)
+
+ // Populate a mock filesystem with the files that would have been copied by
+ // the rules.
+ fs := make(map[string][]byte)
+ for _, dest := range snapshotBuildInfo.snapshotContents {
+ fs[dest] = nil
+ }
+
+ // Process the generated bp file to make sure it is valid.
+ testSdkWithFs(r.t, snapshotBuildInfo.androidBpContents, fs)
+}
+
+type snapshotBuildInfoChecker func(info *snapshotBuildInfo)
+
+// Check that the snapshot's generated Android.bp is correct.
+//
+// Both the expected and actual string are both trimmed before comparing.
+func checkAndroidBpContents(expected string) snapshotBuildInfoChecker {
+ return func(info *snapshotBuildInfo) {
+ info.r.t.Helper()
+ info.r.AssertTrimmedStringEquals("Android.bp contents do not match", expected, info.androidBpContents)
+ }
+}
+
+// Check that the snapshot's copy rules are correct.
+//
+// The copy rules are formatted as <src> -> <dest>, one per line and then compared
+// to the supplied expected string. Both the expected and actual string are trimmed
+// before comparing.
+func checkAllCopyRules(expected string) snapshotBuildInfoChecker {
+ return func(info *snapshotBuildInfo) {
+ info.r.t.Helper()
+ info.r.AssertTrimmedStringEquals("Incorrect copy rules", expected, info.copyRules)
+ }
+}
+
+// Check that the specified path is in the list of zips to merge with the intermediate zip.
+func checkMergeZip(expected string) snapshotBuildInfoChecker {
+ return func(info *snapshotBuildInfo) {
+ info.r.t.Helper()
+ if info.intermediateZip == "" {
+ info.r.t.Errorf("No intermediate zip file was created")
+ }
+ ensureListContains(info.r.t, info.mergeZips, expected)
+ }
+}
+
+// Encapsulates information about the snapshot build structure in order to insulate tests from
+// knowing too much about internal structures.
+//
+// All source/input paths are relative either the build directory. All dest/output paths are
+// relative to the snapshot root directory.
+type snapshotBuildInfo struct {
+ r *testSdkResult
+
+ // The contents of the generated Android.bp file
+ androidBpContents string
+
+ // The paths, relative to the snapshot root, of all files and directories copied into the
+ // snapshot.
+ snapshotContents []string
+
+ // A formatted representation of the src/dest pairs, one pair per line, of the format
+ // src -> dest
+ copyRules string
+
+ // The path to the intermediate zip, which is a zip created from the source files copied
+ // into the snapshot directory and which will be merged with other zips to form the final output.
+ // Is am empty string if there is no intermediate zip because there are no zips to merge in.
+ intermediateZip string
+
+ // The paths to the zips to merge into the output zip, does not include the intermediate
+ // zip.
+ mergeZips []string
+
+ // The final output zip.
+ outputZip string
+}
+
+var buildDir string
+
+func setUp() {
+ var err error
+ buildDir, err = ioutil.TempDir("", "soong_sdk_test")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func tearDown() {
+ _ = os.RemoveAll(buildDir)
+}
+
+func runTestWithBuildDir(m *testing.M) {
+ run := func() int {
+ setUp()
+ defer tearDown()
+
+ return m.Run()
+ }
+
+ os.Exit(run())
+}
+
+func SkipIfNotLinux(t *testing.T) {
+ t.Helper()
+ if android.BuildOs != android.Linux {
+ t.Skipf("Skipping as sdk snapshot generation is only supported on %s not %s", android.Linux, android.BuildOs)
+ }
+}
diff --git a/sdk/update.go b/sdk/update.go
index 8159d3b..7731fbb 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -16,19 +16,47 @@
import (
"fmt"
- "path/filepath"
"reflect"
"strings"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
- "android/soong/cc"
- "android/soong/java"
)
var pctx = android.NewPackageContext("android/soong/sdk")
+var (
+ repackageZip = pctx.AndroidStaticRule("SnapshotRepackageZip",
+ blueprint.RuleParams{
+ Command: `${config.Zip2ZipCmd} -i $in -o $out "**/*:$destdir"`,
+ CommandDeps: []string{
+ "${config.Zip2ZipCmd}",
+ },
+ },
+ "destdir")
+
+ zipFiles = pctx.AndroidStaticRule("SnapshotZipFiles",
+ blueprint.RuleParams{
+ Command: `${config.SoongZipCmd} -C $basedir -l $out.rsp -o $out`,
+ CommandDeps: []string{
+ "${config.SoongZipCmd}",
+ },
+ Rspfile: "$out.rsp",
+ RspfileContent: "$in",
+ },
+ "basedir")
+
+ mergeZips = pctx.AndroidStaticRule("SnapshotMergeZips",
+ blueprint.RuleParams{
+ Command: `${config.MergeZipsCmd} $out $in`,
+ CommandDeps: []string{
+ "${config.MergeZipsCmd}",
+ },
+ })
+)
+
type generatedContents struct {
content strings.Builder
indentLevel int
@@ -74,105 +102,46 @@
rb.Build(pctx, ctx, gf.path.Base(), "Build "+gf.path.Base())
}
-func (s *sdk) javaLibs(ctx android.ModuleContext) []android.SdkAware {
- result := []android.SdkAware{}
+// Collect all the members.
+//
+// The members are first grouped by type and then grouped by name. The order of
+// the types is the order they are referenced in sdkMemberListProperties. The
+// names are in order in which the dependencies were added.
+func collectMembers(ctx android.ModuleContext) []*sdkMember {
+ byType := make(map[android.SdkMemberType][]*sdkMember)
+ byName := make(map[string]*sdkMember)
+
ctx.VisitDirectDeps(func(m android.Module) {
- if j, ok := m.(*java.Library); ok {
- result = append(result, j)
- }
- })
- return result
-}
+ tag := ctx.OtherModuleDependencyTag(m)
+ if memberTag, ok := tag.(*sdkMemberDependencyTag); ok {
+ memberListProperty := memberTag.memberListProperty
+ memberType := memberListProperty.memberType
-func (s *sdk) stubsSources(ctx android.ModuleContext) []android.SdkAware {
- result := []android.SdkAware{}
- ctx.VisitDirectDeps(func(m android.Module) {
- if j, ok := m.(*java.Droidstubs); ok {
- result = append(result, j)
- }
- })
- return result
-}
-
-// archSpecificNativeLibInfo represents an arch-specific variant of a native lib
-type archSpecificNativeLibInfo struct {
- name string
- archType string
- exportedIncludeDirs android.Paths
- exportedSystemIncludeDirs android.Paths
- exportedFlags []string
- exportedDeps android.Paths
- outputFile android.Path
-}
-
-func (lib *archSpecificNativeLibInfo) signature() string {
- return fmt.Sprintf("%v %v %v %v",
- lib.name,
- lib.exportedIncludeDirs.Strings(),
- lib.exportedSystemIncludeDirs.Strings(),
- lib.exportedFlags)
-}
-
-// nativeLibInfo represents a collection of arch-specific modules having the same name
-type nativeLibInfo struct {
- name string
- archVariants []archSpecificNativeLibInfo
- // hasArchSpecificFlags is set to true if modules for each architecture all have the same
- // include dirs, flags, etc, in which case only those of the first arch is selected.
- hasArchSpecificFlags bool
-}
-
-// nativeMemberInfos collects all cc.Modules that are member of an SDK.
-func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo {
- infoMap := make(map[string]*nativeLibInfo)
-
- // Collect cc.Modules
- ctx.VisitDirectDeps(func(m android.Module) {
- ccModule, ok := m.(*cc.Module)
- if !ok {
- return
- }
- depName := ctx.OtherModuleName(m)
-
- if _, ok := infoMap[depName]; !ok {
- infoMap[depName] = &nativeLibInfo{name: depName}
- }
-
- info := infoMap[depName]
- info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
- name: ccModule.BaseModuleName(),
- archType: ccModule.Target().Arch.ArchType.String(),
- exportedIncludeDirs: ccModule.ExportedIncludeDirs(),
- exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
- exportedFlags: ccModule.ExportedFlags(),
- exportedDeps: ccModule.ExportedDeps(),
- outputFile: ccModule.OutputFile().Path(),
- })
- })
-
- // Determine if include dirs and flags for each module are different across arch-specific
- // modules or not. And set hasArchSpecificFlags accordingly
- for _, info := range infoMap {
- // by default, include paths and flags are assumed to be the same across arches
- info.hasArchSpecificFlags = false
- oldSignature := ""
- for _, av := range info.archVariants {
- newSignature := av.signature()
- if oldSignature == "" {
- oldSignature = newSignature
+ // Make sure that the resolved module is allowed in the member list property.
+ if !memberType.IsInstance(m) {
+ ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(m), memberListProperty.name)
}
- if oldSignature != newSignature {
- info.hasArchSpecificFlags = true
- break
+
+ name := ctx.OtherModuleName(m)
+
+ member := byName[name]
+ if member == nil {
+ member = &sdkMember{memberType: memberType, name: name}
+ byName[name] = member
+ byType[memberType] = append(byType[memberType], member)
}
+
+ member.variants = append(member.variants, m.(android.SdkAware))
}
+ })
+
+ var members []*sdkMember
+ for _, memberListProperty := range sdkMemberListProperties {
+ membersOfType := byType[memberListProperty.memberType]
+ members = append(members, membersOfType...)
}
- var list []*nativeLibInfo
- for _, v := range infoMap {
- list = append(list, v)
- }
- return list
+ return members
}
// SDK directory structure
@@ -193,44 +162,6 @@
// <arch>/lib/
// libFoo.so : a stub library
-const (
- nativeIncludeDir = "include"
- nativeGeneratedIncludeDir = "include_gen"
- nativeStubDir = "lib"
- nativeStubFileSuffix = ".so"
-)
-
-// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
-func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
- return filepath.Join(lib.archType,
- nativeStubDir, lib.name+nativeStubFileSuffix)
-}
-
-// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
-func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeLibInfo,
- systemInclude bool, archSpecific bool) []string {
- var result []string
- var includeDirs []android.Path
- if !systemInclude {
- includeDirs = lib.exportedIncludeDirs
- } else {
- includeDirs = lib.exportedSystemIncludeDirs
- }
- for _, dir := range includeDirs {
- var path string
- if _, gen := dir.(android.WritablePath); gen {
- path = filepath.Join(nativeGeneratedIncludeDir, lib.name)
- } else {
- path = filepath.Join(nativeIncludeDir, dir.String())
- }
- if archSpecific {
- path = filepath.Join(lib.archType, path)
- }
- result = append(result, path)
- }
- return result
-}
-
// A name that uniquely identifies a prebuilt SDK member for a version of SDK snapshot
// This isn't visible to users, so could be changed in future.
func versionedSdkMemberName(ctx android.ModuleContext, memberName string, version string) string {
@@ -259,22 +190,8 @@
}
s.builderForTests = builder
- // copy exported AIDL files and stub jar files
- javaLibs := s.javaLibs(ctx)
- for _, m := range javaLibs {
- m.BuildSnapshot(ctx, builder)
- }
-
- // copy stubs sources
- stubsSources := s.stubsSources(ctx)
- for _, m := range stubsSources {
- m.BuildSnapshot(ctx, builder)
- }
-
- // copy exported header files and stub *.so files
- nativeLibInfos := s.nativeMemberInfos(ctx)
- for _, info := range nativeLibInfos {
- buildSharedNativeLibSnapshot(ctx, info, builder)
+ for _, member := range collectMembers(ctx) {
+ member.memberType.BuildSnapshot(ctx, builder, member)
}
for _, unversioned := range builder.prebuiltOrder {
@@ -295,14 +212,11 @@
snapshotModule := bpFile.newModule("sdk_snapshot")
snapshotModule.AddProperty("name", snapshotName)
addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule)
- if len(s.properties.Java_libs) > 0 {
- snapshotModule.AddProperty("java_libs", builder.versionedSdkMemberNames(s.properties.Java_libs))
- }
- if len(s.properties.Stubs_sources) > 0 {
- snapshotModule.AddProperty("stubs_sources", builder.versionedSdkMemberNames(s.properties.Stubs_sources))
- }
- if len(s.properties.Native_shared_libs) > 0 {
- snapshotModule.AddProperty("native_shared_libs", builder.versionedSdkMemberNames(s.properties.Native_shared_libs))
+ for _, memberListProperty := range sdkMemberListProperties {
+ names := memberListProperty.getter(&s.properties)
+ if len(names) > 0 {
+ snapshotModule.AddProperty(memberListProperty.name, builder.versionedSdkMemberNames(names))
+ }
}
bpFile.AddModule(snapshotModule)
@@ -316,41 +230,39 @@
// zip them all
outputZipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
- outputRuleName := "snapshot"
outputDesc := "Building snapshot for " + ctx.ModuleName()
// If there are no zips to merge then generate the output zip directly.
// Otherwise, generate an intermediate zip file into which other zips can be
// merged.
var zipFile android.OutputPath
- var ruleName string
var desc string
if len(builder.zipsToMerge) == 0 {
zipFile = outputZipFile
- ruleName = outputRuleName
desc = outputDesc
} else {
zipFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.unmerged.zip").OutputPath
- ruleName = "intermediate snapshot"
desc = "Building intermediate snapshot for " + ctx.ModuleName()
}
- rb := android.NewRuleBuilder()
- rb.Command().
- BuiltTool(ctx, "soong_zip").
- FlagWithArg("-C ", builder.snapshotDir.String()).
- FlagWithRspFileInputList("-l ", filesToZip).
- FlagWithOutput("-o ", zipFile)
- rb.Build(pctx, ctx, ruleName, desc)
+ ctx.Build(pctx, android.BuildParams{
+ Description: desc,
+ Rule: zipFiles,
+ Inputs: filesToZip,
+ Output: zipFile,
+ Args: map[string]string{
+ "basedir": builder.snapshotDir.String(),
+ },
+ })
if len(builder.zipsToMerge) != 0 {
- rb := android.NewRuleBuilder()
- rb.Command().
- BuiltTool(ctx, "merge_zips").
- Output(outputZipFile).
- Input(zipFile).
- Inputs(builder.zipsToMerge)
- rb.Build(pctx, ctx, outputRuleName, outputDesc)
+ ctx.Build(pctx, android.BuildParams{
+ Description: outputDesc,
+ Rule: mergeZips,
+ Input: zipFile,
+ Inputs: builder.zipsToMerge,
+ Output: outputZipFile,
+ })
}
return outputZipFile
@@ -364,7 +276,6 @@
outputPropertySet(contents, &bpModule.bpPropertySet)
contents.Printfln("}")
}
- contents.Printfln("")
}
func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
@@ -413,98 +324,6 @@
return contents.content.String()
}
-func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
- // a function for emitting include dirs
- printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
- includeDirs := lib.exportedIncludeDirs
- includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
- if len(includeDirs) == 0 {
- return
- }
- for _, dir := range includeDirs {
- if _, gen := dir.(android.WritablePath); gen {
- // generated headers are copied via exportedDeps. See below.
- continue
- }
- targetDir := nativeIncludeDir
- if info.hasArchSpecificFlags {
- targetDir = filepath.Join(lib.archType, targetDir)
- }
-
- // TODO(jiyong) copy headers having other suffixes
- headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil)
- for _, file := range headers {
- src := android.PathForSource(ctx, file)
- dest := filepath.Join(targetDir, file)
- builder.CopyToSnapshot(src, dest)
- }
- }
-
- genHeaders := lib.exportedDeps
- for _, file := range genHeaders {
- targetDir := nativeGeneratedIncludeDir
- if info.hasArchSpecificFlags {
- targetDir = filepath.Join(lib.archType, targetDir)
- }
- dest := filepath.Join(targetDir, lib.name, file.Rel())
- builder.CopyToSnapshot(file, dest)
- }
- }
-
- if !info.hasArchSpecificFlags {
- printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
- }
-
- // for each architecture
- for _, av := range info.archVariants {
- builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
-
- if info.hasArchSpecificFlags {
- printExportedDirCopyCommandsForNativeLibs(av)
- }
- }
-
- info.generatePrebuiltLibrary(ctx, builder)
-}
-
-func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder) {
-
- // a function for emitting include dirs
- addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
- includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
- if len(includeDirs) == 0 {
- return
- }
- var propertyName string
- if !systemInclude {
- propertyName = "export_include_dirs"
- } else {
- propertyName = "export_system_include_dirs"
- }
- properties.AddProperty(propertyName, includeDirs)
- }
-
- pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
-
- if !info.hasArchSpecificFlags {
- addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
- addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
- }
-
- archProperties := pbm.AddPropertySet("arch")
- for _, av := range info.archVariants {
- archTypeProperties := archProperties.AddPropertySet(av.archType)
- archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
- if info.hasArchSpecificFlags {
- // export_* properties are added inside the arch: {<arch>: {...}} block
- addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
- addExportedDirsForNativeLibs(av, archTypeProperties, true /*systemInclude*/)
- }
- }
- pbm.AddProperty("stl", "none")
- pbm.AddProperty("system_shared_libs", []string{})
-}
-
type snapshotBuilder struct {
ctx android.ModuleContext
sdk *sdk
@@ -534,14 +353,16 @@
// Repackage the zip file so that the entries are in the destDir directory.
// This will allow the zip file to be merged into the snapshot.
tmpZipPath := android.PathForModuleOut(ctx, "tmp", destDir+".zip").OutputPath
- rb := android.NewRuleBuilder()
- rb.Command().
- BuiltTool(ctx, "zip2zip").
- FlagWithInput("-i ", zipPath).
- FlagWithOutput("-o ", tmpZipPath).
- Flag("**/*:" + destDir)
- rb.Build(pctx, ctx, "repackaging "+destDir,
- "Repackaging zip file "+destDir+" for snapshot "+ctx.ModuleName())
+
+ ctx.Build(pctx, android.BuildParams{
+ Description: "Repackaging zip file " + destDir + " for snapshot " + ctx.ModuleName(),
+ Rule: repackageZip,
+ Input: zipPath,
+ Output: tmpZipPath,
+ Args: map[string]string{
+ "destdir": destDir,
+ },
+ })
// Add the repackaged zip file to the files to merge.
s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
@@ -582,3 +403,19 @@
}
return references
}
+
+var _ android.SdkMember = (*sdkMember)(nil)
+
+type sdkMember struct {
+ memberType android.SdkMemberType
+ name string
+ variants []android.SdkAware
+}
+
+func (m *sdkMember) Name() string {
+ return m.name
+}
+
+func (m *sdkMember) Variants() []android.SdkAware {
+ return m.variants
+}