Snap for 12406339 from 3961bb8fb2
to 24Q4-release
Change-Id: Icd8dd382b78f5e451a2a4bb1a5d59037d0e024bd
This commit is contained in:
@@ -15,7 +15,6 @@
|
|||||||
package android
|
package android
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
@@ -109,10 +108,6 @@ func (i DeapexerInfo) GetExportedModuleNames() []string {
|
|||||||
return i.exportedModuleNames
|
return i.exportedModuleNames
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provider that can be used from within the `GenerateAndroidBuildActions` of a module that depends
|
|
||||||
// on a `deapexer` module to retrieve its `DeapexerInfo`.
|
|
||||||
var DeapexerProvider = blueprint.NewProvider[DeapexerInfo]()
|
|
||||||
|
|
||||||
// NewDeapexerInfo creates and initializes a DeapexerInfo that is suitable
|
// NewDeapexerInfo creates and initializes a DeapexerInfo that is suitable
|
||||||
// for use with a prebuilt_apex module.
|
// for use with a prebuilt_apex module.
|
||||||
//
|
//
|
||||||
@@ -169,45 +164,6 @@ type RequiresFilesFromPrebuiltApexTag interface {
|
|||||||
RequiresFilesFromPrebuiltApex()
|
RequiresFilesFromPrebuiltApex()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindDeapexerProviderForModule searches through the direct dependencies of the current context
|
|
||||||
// module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous
|
|
||||||
// deapexer module isn't found then it returns it an error
|
|
||||||
// clients should check the value of error and call ctx.ModuleErrof if a non nil error is received
|
|
||||||
func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) {
|
|
||||||
var di *DeapexerInfo
|
|
||||||
var err error
|
|
||||||
ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) {
|
|
||||||
if err != nil {
|
|
||||||
// An err has been found. Do not visit further.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c, ok := OtherModuleProvider(ctx, m, DeapexerProvider)
|
|
||||||
if !ok {
|
|
||||||
ctx.ModuleErrorf("Expected all deps with DeapexerTag to have a DeapexerProvider, but module %q did not", m.Name())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p := &c
|
|
||||||
if di != nil {
|
|
||||||
// If two DeapexerInfo providers have been found then check if they are
|
|
||||||
// equivalent. If they are then use the selected one, otherwise fail.
|
|
||||||
if selected := equivalentDeapexerInfoProviders(di, p); selected != nil {
|
|
||||||
di = selected
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = fmt.Errorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", di.ApexModuleName(), p.ApexModuleName())
|
|
||||||
}
|
|
||||||
di = p
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if di != nil {
|
|
||||||
return di, nil
|
|
||||||
}
|
|
||||||
ai, _ := ModuleProvider(ctx, ApexInfoProvider)
|
|
||||||
return nil, fmt.Errorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// removeCompressedApexSuffix removes the _compressed suffix from the name if present.
|
// removeCompressedApexSuffix removes the _compressed suffix from the name if present.
|
||||||
func removeCompressedApexSuffix(name string) string {
|
func removeCompressedApexSuffix(name string) string {
|
||||||
return strings.TrimSuffix(name, "_compressed")
|
return strings.TrimSuffix(name, "_compressed")
|
||||||
|
11
apex/apex.go
11
apex/apex.go
@@ -49,15 +49,10 @@ func registerApexBuildComponents(ctx android.RegistrationContext) {
|
|||||||
ctx.RegisterModuleType("override_apex", OverrideApexFactory)
|
ctx.RegisterModuleType("override_apex", OverrideApexFactory)
|
||||||
ctx.RegisterModuleType("apex_set", apexSetFactory)
|
ctx.RegisterModuleType("apex_set", apexSetFactory)
|
||||||
|
|
||||||
ctx.PreArchMutators(registerPreArchMutators)
|
|
||||||
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
ctx.PreDepsMutators(RegisterPreDepsMutators)
|
||||||
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
ctx.PostDepsMutators(RegisterPostDepsMutators)
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerPreArchMutators(ctx android.RegisterMutatorsContext) {
|
|
||||||
ctx.BottomUp("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel()
|
|
||||||
}
|
|
||||||
|
|
||||||
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
|
||||||
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
|
ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
|
||||||
}
|
}
|
||||||
@@ -2745,6 +2740,12 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporarily bypass /product APEXes with a specific prefix.
|
||||||
|
// TODO: b/352818241 - Remove this after APEX availability is enforced for /product APEXes.
|
||||||
|
if a.ProductSpecific() && strings.HasPrefix(a.ApexVariationName(), "com.sdv.") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Coverage build adds additional dependencies for the coverage-only runtime libraries.
|
// Coverage build adds additional dependencies for the coverage-only runtime libraries.
|
||||||
// Requiring them and their transitive depencies with apex_available is not right
|
// Requiring them and their transitive depencies with apex_available is not right
|
||||||
// because they just add noise.
|
// because they just add noise.
|
||||||
|
@@ -3685,7 +3685,7 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, var
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) {
|
func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) {
|
||||||
deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Description("deapex")
|
deapexer := ctx.ModuleForTests(moduleName, variant).Description("deapex")
|
||||||
outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1)
|
outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1)
|
||||||
if deapexer.Output != nil {
|
if deapexer.Output != nil {
|
||||||
outputs = append(outputs, deapexer.Output.String())
|
outputs = append(outputs, deapexer.Output.String())
|
||||||
@@ -4907,23 +4907,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
|
|
||||||
t.Helper()
|
|
||||||
s := ctx.ModuleForTests("dex_bootjars", "android_common")
|
|
||||||
foundLibfooJar := false
|
|
||||||
base := stem + ".jar"
|
|
||||||
for _, output := range s.AllOutputs() {
|
|
||||||
if filepath.Base(output) == base {
|
|
||||||
foundLibfooJar = true
|
|
||||||
buildRule := s.Output(output)
|
|
||||||
android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundLibfooJar {
|
|
||||||
t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().SoongOutDir(), s.AllOutputs()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
|
checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
|
platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common")
|
||||||
@@ -4976,12 +4959,14 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_sdk_library_import {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
jars: ["libfoo.jar"],
|
public: {
|
||||||
|
jars: ["libfoo.jar"],
|
||||||
|
},
|
||||||
apex_available: ["myapex"],
|
apex_available: ["myapex"],
|
||||||
|
shared_library: false,
|
||||||
permitted_packages: ["foo"],
|
permitted_packages: ["foo"],
|
||||||
sdk_version: "core_current",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java_sdk_library_import {
|
java_sdk_library_import {
|
||||||
@@ -4996,8 +4981,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
||||||
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
|
|
||||||
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
|
|
||||||
|
|
||||||
// Verify the correct module jars contribute to the hiddenapi index file.
|
// Verify the correct module jars contribute to the hiddenapi index file.
|
||||||
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
||||||
@@ -5037,13 +5020,17 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
apex_available: ["myapex"],
|
apex_available: ["myapex"],
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_sdk_library_import {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
jars: ["libfoo.jar"],
|
public: {
|
||||||
|
jars: ["libfoo.jar"],
|
||||||
|
},
|
||||||
apex_available: ["myapex"],
|
apex_available: ["myapex"],
|
||||||
permitted_packages: ["foo"],
|
shared_library: false,
|
||||||
|
permitted_packages: ["libfoo"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
java_sdk_library_import {
|
java_sdk_library_import {
|
||||||
name: "libbar",
|
name: "libbar",
|
||||||
public: {
|
public: {
|
||||||
@@ -5066,8 +5053,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
||||||
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
|
|
||||||
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
|
|
||||||
|
|
||||||
// Verify the correct module jars contribute to the hiddenapi index file.
|
// Verify the correct module jars contribute to the hiddenapi index file.
|
||||||
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
||||||
@@ -5221,13 +5206,15 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_sdk_library_import {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
prefer: true,
|
prefer: true,
|
||||||
jars: ["libfoo.jar"],
|
public: {
|
||||||
|
jars: ["libfoo.jar"],
|
||||||
|
},
|
||||||
apex_available: ["myapex"],
|
apex_available: ["myapex"],
|
||||||
permitted_packages: ["foo"],
|
shared_library: false,
|
||||||
sdk_version: "core_current",
|
permitted_packages: ["libfoo"],
|
||||||
}
|
}
|
||||||
|
|
||||||
java_library {
|
java_library {
|
||||||
@@ -5259,8 +5246,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
||||||
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
|
|
||||||
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
|
|
||||||
|
|
||||||
// Verify the correct module jars contribute to the hiddenapi index file.
|
// Verify the correct module jars contribute to the hiddenapi index file.
|
||||||
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
||||||
@@ -5359,8 +5344,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
`
|
`
|
||||||
|
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment)
|
||||||
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/hiddenapi-modular/encoded/libfoo.jar")
|
|
||||||
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/hiddenapi-modular/encoded/libbar.jar")
|
|
||||||
|
|
||||||
// Verify the correct module jars contribute to the hiddenapi index file.
|
// Verify the correct module jars contribute to the hiddenapi index file.
|
||||||
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
||||||
@@ -5472,8 +5455,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
ctx := testDexpreoptWithApexes(t, bp, "", preparer2, fragment)
|
ctx := testDexpreoptWithApexes(t, bp, "", preparer2, fragment)
|
||||||
checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
|
|
||||||
checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
|
|
||||||
|
|
||||||
// Verify the correct module jars contribute to the hiddenapi index file.
|
// Verify the correct module jars contribute to the hiddenapi index file.
|
||||||
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`)
|
||||||
@@ -6032,6 +6013,87 @@ func TestApexAvailable_DirectDep(t *testing.T) {
|
|||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
apex_available: ["otherapex"],
|
apex_available: ["otherapex"],
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
|
// 'apex_available' check is bypassed for /product apex with a specific prefix.
|
||||||
|
// TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes.
|
||||||
|
testApex(t, `
|
||||||
|
apex {
|
||||||
|
name: "com.sdv.myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
product_specific: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "com.any.otherapex",
|
||||||
|
key: "otherapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "otherapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.any.otherapex"],
|
||||||
|
product_specific: true,
|
||||||
|
}`,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/com.sdv.myapex-file_contexts": nil,
|
||||||
|
"system/sepolicy/apex/com.any.otherapex-file_contexts": nil,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 'apex_available' check is not bypassed for non-product apex with a specific prefix.
|
||||||
|
testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", `
|
||||||
|
apex {
|
||||||
|
name: "com.sdv.myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "com.any.otherapex",
|
||||||
|
key: "otherapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "otherapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.any.otherapex"],
|
||||||
|
}`,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/com.sdv.myapex-file_contexts": nil,
|
||||||
|
"system/sepolicy/apex/com.any.otherapex-file_contexts": nil,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexAvailable_IndirectDep(t *testing.T) {
|
func TestApexAvailable_IndirectDep(t *testing.T) {
|
||||||
@@ -6077,6 +6139,91 @@ func TestApexAvailable_IndirectDep(t *testing.T) {
|
|||||||
stl: "none",
|
stl: "none",
|
||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
}`)
|
}`)
|
||||||
|
|
||||||
|
// 'apex_available' check is bypassed for /product apex with a specific prefix.
|
||||||
|
// TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes.
|
||||||
|
testApex(t, `
|
||||||
|
apex {
|
||||||
|
name: "com.sdv.myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
product_specific: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
shared_libs: ["libbar"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.sdv.myapex"],
|
||||||
|
product_specific: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
stl: "none",
|
||||||
|
shared_libs: ["libbaz"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.sdv.myapex"],
|
||||||
|
product_specific: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbaz",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
product_specific: true,
|
||||||
|
}`,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/com.sdv.myapex-file_contexts": nil,
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 'apex_available' check is not bypassed for non-product apex with a specific prefix.
|
||||||
|
testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.`, `
|
||||||
|
apex {
|
||||||
|
name: "com.sdv.myapex",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
updatable: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
stl: "none",
|
||||||
|
shared_libs: ["libbar"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.sdv.myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbar",
|
||||||
|
stl: "none",
|
||||||
|
shared_libs: ["libbaz"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
apex_available: ["com.sdv.myapex"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libbaz",
|
||||||
|
stl: "none",
|
||||||
|
system_shared_libs: [],
|
||||||
|
}`,
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"system/sepolicy/apex/com.sdv.myapex-file_contexts": nil,
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexAvailable_IndirectStaticDep(t *testing.T) {
|
func TestApexAvailable_IndirectStaticDep(t *testing.T) {
|
||||||
@@ -7880,9 +8027,9 @@ func TestAppSetBundlePrebuilt(t *testing.T) {
|
|||||||
ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
|
ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
|
||||||
|
|
||||||
// Check that the extractor produces the correct output file from the correct input file.
|
// Check that the extractor produces the correct output file from the correct input file.
|
||||||
extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
|
extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.hwasan.apks"
|
||||||
|
|
||||||
m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
|
m := ctx.ModuleForTests("myapex", "android_common_myapex")
|
||||||
extractedApex := m.Output(extractorOutput)
|
extractedApex := m.Output(extractorOutput)
|
||||||
|
|
||||||
android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
|
android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
|
||||||
@@ -7907,10 +8054,10 @@ func TestApexSetApksModuleAssignment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
|
m := ctx.ModuleForTests("myapex", "android_common_myapex")
|
||||||
|
|
||||||
// Check that the extractor produces the correct apks file from the input module
|
// Check that the extractor produces the correct apks file from the input module
|
||||||
extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.apks"
|
extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.apks"
|
||||||
extractedApex := m.Output(extractorOutput)
|
extractedApex := m.Output(extractorOutput)
|
||||||
|
|
||||||
android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings())
|
android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings())
|
||||||
@@ -7972,189 +8119,6 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F
|
|||||||
return result.TestContext
|
return result.TestContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) {
|
|
||||||
preparers := android.GroupFixturePreparers(
|
|
||||||
java.PrepareForTestWithJavaDefaultModules,
|
|
||||||
prepareForTestWithBootclasspathFragment,
|
|
||||||
dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:libfoo"),
|
|
||||||
PrepareForTestWithApexBuildComponents,
|
|
||||||
).
|
|
||||||
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
|
|
||||||
"Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art"))
|
|
||||||
|
|
||||||
bpBase := `
|
|
||||||
apex_set {
|
|
||||||
name: "com.android.art",
|
|
||||||
installable: true,
|
|
||||||
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
|
||||||
set: "myapex.apks",
|
|
||||||
}
|
|
||||||
|
|
||||||
apex_set {
|
|
||||||
name: "com.mycompany.android.art",
|
|
||||||
apex_name: "com.android.art",
|
|
||||||
installable: true,
|
|
||||||
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
|
||||||
set: "company-myapex.apks",
|
|
||||||
}
|
|
||||||
|
|
||||||
prebuilt_bootclasspath_fragment {
|
|
||||||
name: "art-bootclasspath-fragment",
|
|
||||||
apex_available: ["com.android.art"],
|
|
||||||
hidden_api: {
|
|
||||||
annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv",
|
|
||||||
metadata: "my-bootclasspath-fragment/metadata.csv",
|
|
||||||
index: "my-bootclasspath-fragment/index.csv",
|
|
||||||
stub_flags: "my-bootclasspath-fragment/stub-flags.csv",
|
|
||||||
all_flags: "my-bootclasspath-fragment/all-flags.csv",
|
|
||||||
},
|
|
||||||
%s
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
t.Run("java_import", func(t *testing.T) {
|
|
||||||
_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
|
||||||
java_import {
|
|
||||||
name: "libfoo",
|
|
||||||
jars: ["libfoo.jar"],
|
|
||||||
apex_available: ["com.android.art"],
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("java_sdk_library_import", func(t *testing.T) {
|
|
||||||
_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
|
||||||
java_sdk_library_import {
|
|
||||||
name: "libfoo",
|
|
||||||
public: {
|
|
||||||
jars: ["libbar.jar"],
|
|
||||||
},
|
|
||||||
shared_library: false,
|
|
||||||
apex_available: ["com.android.art"],
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
|
|
||||||
_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
|
|
||||||
image_name: "art",
|
|
||||||
contents: ["libfoo"],
|
|
||||||
`)+`
|
|
||||||
java_sdk_library_import {
|
|
||||||
name: "libfoo",
|
|
||||||
public: {
|
|
||||||
jars: ["libbar.jar"],
|
|
||||||
},
|
|
||||||
shared_library: false,
|
|
||||||
apex_available: ["com.android.art"],
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) {
|
|
||||||
preparers := android.GroupFixturePreparers(
|
|
||||||
java.PrepareForTestWithJavaDefaultModules,
|
|
||||||
PrepareForTestWithApexBuildComponents,
|
|
||||||
)
|
|
||||||
|
|
||||||
errCtx := moduleErrorfTestCtx{}
|
|
||||||
|
|
||||||
bpBase := `
|
|
||||||
apex_set {
|
|
||||||
name: "com.android.myapex",
|
|
||||||
installable: true,
|
|
||||||
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
|
|
||||||
set: "myapex.apks",
|
|
||||||
}
|
|
||||||
|
|
||||||
apex_set {
|
|
||||||
name: "com.android.myapex_compressed",
|
|
||||||
apex_name: "com.android.myapex",
|
|
||||||
installable: true,
|
|
||||||
exported_bootclasspath_fragments: ["my-bootclasspath-fragment"],
|
|
||||||
set: "myapex_compressed.apks",
|
|
||||||
}
|
|
||||||
|
|
||||||
prebuilt_bootclasspath_fragment {
|
|
||||||
name: "my-bootclasspath-fragment",
|
|
||||||
apex_available: [
|
|
||||||
"com.android.myapex",
|
|
||||||
"com.android.myapex_compressed",
|
|
||||||
],
|
|
||||||
hidden_api: {
|
|
||||||
annotation_flags: "annotation-flags.csv",
|
|
||||||
metadata: "metadata.csv",
|
|
||||||
index: "index.csv",
|
|
||||||
signature_patterns: "signature_patterns.csv",
|
|
||||||
},
|
|
||||||
%s
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
t.Run("java_import", func(t *testing.T) {
|
|
||||||
result := preparers.RunTestWithBp(t,
|
|
||||||
fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
|
||||||
java_import {
|
|
||||||
name: "libfoo",
|
|
||||||
jars: ["libfoo.jar"],
|
|
||||||
apex_available: [
|
|
||||||
"com.android.myapex",
|
|
||||||
"com.android.myapex_compressed",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
module := result.Module("libfoo", "android_common_com.android.myapex")
|
|
||||||
usesLibraryDep := module.(java.UsesLibraryDependency)
|
|
||||||
android.AssertPathRelativeToTopEquals(t, "dex jar path",
|
|
||||||
"out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
|
|
||||||
usesLibraryDep.DexJarBuildPath(errCtx).Path())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("java_sdk_library_import", func(t *testing.T) {
|
|
||||||
result := preparers.RunTestWithBp(t,
|
|
||||||
fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+`
|
|
||||||
java_sdk_library_import {
|
|
||||||
name: "libfoo",
|
|
||||||
public: {
|
|
||||||
jars: ["libbar.jar"],
|
|
||||||
},
|
|
||||||
apex_available: [
|
|
||||||
"com.android.myapex",
|
|
||||||
"com.android.myapex_compressed",
|
|
||||||
],
|
|
||||||
compile_dex: true,
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
module := result.Module("libfoo", "android_common_com.android.myapex")
|
|
||||||
usesLibraryDep := module.(java.UsesLibraryDependency)
|
|
||||||
android.AssertPathRelativeToTopEquals(t, "dex jar path",
|
|
||||||
"out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar",
|
|
||||||
usesLibraryDep.DexJarBuildPath(errCtx).Path())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) {
|
|
||||||
_ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `
|
|
||||||
image_name: "art",
|
|
||||||
contents: ["libfoo"],
|
|
||||||
`)+`
|
|
||||||
java_sdk_library_import {
|
|
||||||
name: "libfoo",
|
|
||||||
public: {
|
|
||||||
jars: ["libbar.jar"],
|
|
||||||
},
|
|
||||||
apex_available: [
|
|
||||||
"com.android.myapex",
|
|
||||||
"com.android.myapex_compressed",
|
|
||||||
],
|
|
||||||
compile_dex: true,
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
|
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
|
||||||
testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
|
testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, `
|
||||||
apex {
|
apex {
|
||||||
@@ -8266,12 +8230,16 @@ func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_sdk_library_import {
|
||||||
name: "libfoo",
|
name: "libfoo",
|
||||||
|
prefer: true,
|
||||||
|
public: {
|
||||||
jars: ["libfoo.jar"],
|
jars: ["libfoo.jar"],
|
||||||
apex_available: ["myapex"],
|
},
|
||||||
permitted_packages: ["libfoo"],
|
apex_available: ["myapex"],
|
||||||
}
|
shared_library: false,
|
||||||
|
permitted_packages: ["libfoo"],
|
||||||
|
}
|
||||||
`, "", preparer, fragment)
|
`, "", preparer, fragment)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -8651,7 +8619,7 @@ func TestApexSet(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
|
m := ctx.ModuleForTests("myapex", "android_common_myapex")
|
||||||
|
|
||||||
// Check extract_apks tool parameters.
|
// Check extract_apks tool parameters.
|
||||||
extractedApex := m.Output("extracted/myapex.apks")
|
extractedApex := m.Output("extracted/myapex.apks")
|
||||||
@@ -8692,7 +8660,7 @@ func TestApexSet_NativeBridge(t *testing.T) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common")
|
m := ctx.ModuleForTests("myapex", "android_common_myapex")
|
||||||
|
|
||||||
// Check extract_apks tool parameters. No native bridge arch expected
|
// Check extract_apks tool parameters. No native bridge arch expected
|
||||||
extractedApex := m.Output("extracted/myapex.apks")
|
extractedApex := m.Output("extracted/myapex.apks")
|
||||||
@@ -10958,12 +10926,12 @@ func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt",
|
desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt",
|
||||||
selectedApexContributions: "foo.prebuilt.contributions",
|
selectedApexContributions: "foo.prebuilt.contributions",
|
||||||
expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.deapexer/android_common/deapexer/javalib/framework-foo.jar",
|
expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_com.android.foo/deapexer/javalib/framework-foo.jar",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt",
|
desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt",
|
||||||
selectedApexContributions: "foo.prebuilt.v2.contributions",
|
selectedApexContributions: "foo.prebuilt.v2.contributions",
|
||||||
expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.v2.deapexer/android_common/deapexer/javalib/framework-foo.jar",
|
expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_com.android.foo/deapexer/javalib/framework-foo.jar",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -398,11 +398,20 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
|||||||
|
|
||||||
// Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
|
// Make sure that a preferred prebuilt with consistent contents doesn't affect the apex.
|
||||||
addPrebuilt(true, "foo", "bar"),
|
addPrebuilt(true, "foo", "bar"),
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"apex_contributions/Android.bp": []byte(`
|
||||||
|
apex_contributions {
|
||||||
|
name: "prebuilt_art_contributions",
|
||||||
|
contents: ["prebuilt_com.android.art"],
|
||||||
|
api_domain: "com.android.art",
|
||||||
|
}
|
||||||
|
`)}),
|
||||||
|
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
|
||||||
|
|
||||||
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
|
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
|
||||||
).RunTest(t)
|
).RunTest(t)
|
||||||
|
|
||||||
ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common", []string{
|
ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_com.android.art", []string{
|
||||||
"etc/boot-image.prof",
|
"etc/boot-image.prof",
|
||||||
"javalib/bar.jar",
|
"javalib/bar.jar",
|
||||||
"javalib/foo.jar",
|
"javalib/foo.jar",
|
||||||
@@ -495,6 +504,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
|
java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
|
||||||
dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
|
dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"),
|
||||||
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
|
java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"),
|
||||||
|
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
|
||||||
)
|
)
|
||||||
|
|
||||||
bp := `
|
bp := `
|
||||||
@@ -552,6 +562,12 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
src: "com.mycompany.android.art.apex",
|
src: "com.mycompany.android.art.apex",
|
||||||
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apex_contributions {
|
||||||
|
name: "prebuilt_art_contributions",
|
||||||
|
contents: ["prebuilt_com.android.art"],
|
||||||
|
api_domain: "com.android.art",
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
t.Run("disabled alternative APEX", func(t *testing.T) {
|
t.Run("disabled alternative APEX", func(t *testing.T) {
|
||||||
@@ -561,27 +577,18 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
`all_apex_contributions`,
|
`all_apex_contributions`,
|
||||||
`dex2oatd`,
|
`dex2oatd`,
|
||||||
`prebuilt_art-bootclasspath-fragment`,
|
`prebuilt_art-bootclasspath-fragment`,
|
||||||
`prebuilt_com.android.art.apex.selector`,
|
|
||||||
`prebuilt_com.android.art.deapexer`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{
|
java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{
|
||||||
`all_apex_contributions`,
|
`all_apex_contributions`,
|
||||||
`dex2oatd`,
|
`dex2oatd`,
|
||||||
`prebuilt_bar`,
|
`prebuilt_bar`,
|
||||||
`prebuilt_com.android.art.deapexer`,
|
|
||||||
`prebuilt_foo`,
|
`prebuilt_foo`,
|
||||||
})
|
})
|
||||||
|
|
||||||
module := result.ModuleForTests("dex_bootjars", "android_common")
|
module := result.ModuleForTests("dex_bootjars", "android_common")
|
||||||
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("enabled alternative APEX", func(t *testing.T) {
|
|
||||||
preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
|
|
||||||
"Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art")).
|
|
||||||
RunTestWithBp(t, fmt.Sprintf(bp, ""))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
|
// checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the
|
||||||
|
@@ -15,37 +15,9 @@
|
|||||||
package apex
|
package apex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Contains 'deapexer' a private module type used by 'prebuilt_apex' to make dex files contained
|
|
||||||
// within a .apex file referenced by `prebuilt_apex` available for use by their associated
|
|
||||||
// `java_import` modules.
|
|
||||||
//
|
|
||||||
// An 'apex' module references `java_library` modules from which .dex files are obtained that are
|
|
||||||
// stored in the resulting `.apex` file. The resulting `.apex` file is then made available as a
|
|
||||||
// prebuilt by referencing it from a `prebuilt_apex`. For each such `java_library` that is used by
|
|
||||||
// modules outside the `.apex` file a `java_import` prebuilt is made available referencing a jar
|
|
||||||
// that contains the Java classes.
|
|
||||||
//
|
|
||||||
// When building a Java module type, e.g. `java_module` or `android_app` against such prebuilts the
|
|
||||||
// `java_import` provides the classes jar (jar containing `.class` files) against which the
|
|
||||||
// module's `.java` files are compiled. That classes jar usually contains only stub classes. The
|
|
||||||
// resulting classes jar is converted into a dex jar (jar containing `.dex` files). Then if
|
|
||||||
// necessary the dex jar is further processed by `dexpreopt` to produce an optimized form of the
|
|
||||||
// library specific to the current Android version. This process requires access to implementation
|
|
||||||
// dex jars for each `java_import`. The `java_import` will obtain the implementation dex jar from
|
|
||||||
// the `.apex` file in the associated `prebuilt_apex`.
|
|
||||||
//
|
|
||||||
// This is intentionally not registered by name as it is not intended to be used from within an
|
|
||||||
// `Android.bp` file.
|
|
||||||
|
|
||||||
// DeapexerProperties specifies the properties supported by the deapexer module.
|
|
||||||
//
|
|
||||||
// As these are never intended to be supplied in a .bp file they use a different naming convention
|
|
||||||
// to make it clear that they are different.
|
|
||||||
type DeapexerProperties struct {
|
type DeapexerProperties struct {
|
||||||
// List of common modules that may need access to files exported by this module.
|
// List of common modules that may need access to files exported by this module.
|
||||||
//
|
//
|
||||||
@@ -72,46 +44,9 @@ type SelectedApexProperties struct {
|
|||||||
Selected_apex *string `android:"path" blueprint:"mutated"`
|
Selected_apex *string `android:"path" blueprint:"mutated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Deapexer struct {
|
// deapex creates the build rules to deapex a prebuilt .apex file
|
||||||
android.ModuleBase
|
// it returns a pointer to a DeapexerInfo object
|
||||||
|
func deapex(ctx android.ModuleContext, apexFile android.Path, deapexerProps DeapexerProperties) *android.DeapexerInfo {
|
||||||
properties DeapexerProperties
|
|
||||||
selectedApexProperties SelectedApexProperties
|
|
||||||
|
|
||||||
inputApex android.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the name of the deapexer module corresponding to an APEX module with the given name.
|
|
||||||
func deapexerModuleName(apexModuleName string) string {
|
|
||||||
return apexModuleName + ".deapexer"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the name of the APEX module corresponding to an deapexer module with
|
|
||||||
// the given name. This reverses deapexerModuleName.
|
|
||||||
func apexModuleName(deapexerModuleName string) string {
|
|
||||||
return strings.TrimSuffix(deapexerModuleName, ".deapexer")
|
|
||||||
}
|
|
||||||
|
|
||||||
func privateDeapexerFactory() android.Module {
|
|
||||||
module := &Deapexer{}
|
|
||||||
module.AddProperties(&module.properties, &module.selectedApexProperties)
|
|
||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
// Add dependencies from the java modules to which this exports files from the `.apex` file onto
|
|
||||||
// this module so that they can access the `DeapexerInfo` object that this provides.
|
|
||||||
// TODO: b/308174306 - Once all the mainline modules have been flagged, drop this dependency edge
|
|
||||||
for _, lib := range p.properties.CommonModules {
|
|
||||||
dep := prebuiltApexExportedModuleName(ctx, lib)
|
|
||||||
ctx.AddReverseDependency(ctx.Module(), android.DeapexerTag, dep)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
p.inputApex = android.OptionalPathForModuleSrc(ctx, p.selectedApexProperties.Selected_apex).Path()
|
|
||||||
|
|
||||||
// Create and remember the directory into which the .apex file's contents will be unpacked.
|
// Create and remember the directory into which the .apex file's contents will be unpacked.
|
||||||
deapexerOutput := android.PathForModuleOut(ctx, "deapexer")
|
deapexerOutput := android.PathForModuleOut(ctx, "deapexer")
|
||||||
|
|
||||||
@@ -119,7 +54,7 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
// Create mappings from apex relative path to the extracted file's path.
|
// Create mappings from apex relative path to the extracted file's path.
|
||||||
exportedPaths := make(android.Paths, 0, len(exports))
|
exportedPaths := make(android.Paths, 0, len(exports))
|
||||||
for _, path := range p.properties.ExportedFiles {
|
for _, path := range deapexerProps.ExportedFiles {
|
||||||
// Populate the exports that this makes available.
|
// Populate the exports that this makes available.
|
||||||
extractedPath := deapexerOutput.Join(ctx, path)
|
extractedPath := deapexerOutput.Join(ctx, path)
|
||||||
exports[path] = extractedPath
|
exports[path] = extractedPath
|
||||||
@@ -131,9 +66,8 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
// apex relative path to extracted file path available for other modules.
|
// apex relative path to extracted file path available for other modules.
|
||||||
if len(exports) > 0 {
|
if len(exports) > 0 {
|
||||||
// Make the information available for other modules.
|
// Make the information available for other modules.
|
||||||
di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports, p.properties.CommonModules)
|
di := android.NewDeapexerInfo(ctx.ModuleName(), exports, deapexerProps.CommonModules)
|
||||||
di.AddDexpreoptProfileGuidedExportedModuleNames(p.properties.DexpreoptProfileGuidedModules...)
|
di.AddDexpreoptProfileGuidedExportedModuleNames(deapexerProps.DexpreoptProfileGuidedModules...)
|
||||||
android.SetProvider(ctx, android.DeapexerProvider, di)
|
|
||||||
|
|
||||||
// Create a sorted list of the files that this exports.
|
// Create a sorted list of the files that this exports.
|
||||||
exportedPaths = android.SortedUniquePaths(exportedPaths)
|
exportedPaths = android.SortedUniquePaths(exportedPaths)
|
||||||
@@ -147,11 +81,13 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
BuiltTool("deapexer").
|
BuiltTool("deapexer").
|
||||||
BuiltTool("debugfs").
|
BuiltTool("debugfs").
|
||||||
BuiltTool("fsck.erofs").
|
BuiltTool("fsck.erofs").
|
||||||
Input(p.inputApex).
|
Input(apexFile).
|
||||||
Text(deapexerOutput.String())
|
Text(deapexerOutput.String())
|
||||||
for _, p := range exportedPaths {
|
for _, p := range exportedPaths {
|
||||||
command.Output(p.(android.WritablePath))
|
command.Output(p.(android.WritablePath))
|
||||||
}
|
}
|
||||||
builder.Build("deapexer", "deapex "+apexModuleName(ctx.ModuleName()))
|
builder.Build("deapexer", "deapex "+ctx.ModuleName())
|
||||||
|
return &di
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -127,16 +127,29 @@ func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOu
|
|||||||
src: "com.android.art-arm.apex",
|
src: "com.android.art-arm.apex",
|
||||||
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
exported_bootclasspath_fragments: ["art-bootclasspath-fragment"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apex_contributions {
|
||||||
|
name: "prebuilt_art_contributions",
|
||||||
|
contents: ["prebuilt_com.android.art"],
|
||||||
|
api_domain: "com.android.art",
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
result := android.GroupFixturePreparers(
|
fixture := android.GroupFixturePreparers(
|
||||||
java.PrepareForTestWithDexpreopt,
|
java.PrepareForTestWithDexpreopt,
|
||||||
java.PrepareForTestWithJavaSdkLibraryFiles,
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
java.FixtureWithLastReleaseApis("foo"),
|
java.FixtureWithLastReleaseApis("foo"),
|
||||||
java.FixtureConfigureBootJars("com.android.art:core-oj", "platform:foo", "system_ext:bar", "platform:baz"),
|
java.FixtureConfigureBootJars("com.android.art:core-oj", "platform:foo", "system_ext:bar", "platform:baz"),
|
||||||
PrepareForTestWithApexBuildComponents,
|
PrepareForTestWithApexBuildComponents,
|
||||||
prepareForTestWithArtApex,
|
prepareForTestWithArtApex,
|
||||||
).RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt))
|
)
|
||||||
|
if preferPrebuilt {
|
||||||
|
fixture = android.GroupFixturePreparers(
|
||||||
|
fixture,
|
||||||
|
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt))
|
||||||
|
|
||||||
dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
|
dexBootJars := result.ModuleForTests("dex_bootjars", "android_common")
|
||||||
rule := dexBootJars.Output(ruleFile)
|
rule := dexBootJars.Output(ruleFile)
|
||||||
@@ -200,7 +213,7 @@ func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) {
|
|||||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
|
"out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar",
|
||||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
|
"out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar",
|
||||||
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
|
"out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar",
|
||||||
"out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
|
"out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof",
|
||||||
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
|
"out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof",
|
||||||
"out/soong/dexpreopt/uffd_gc_flag.txt",
|
"out/soong/dexpreopt/uffd_gc_flag.txt",
|
||||||
}
|
}
|
||||||
@@ -384,12 +397,12 @@ func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) {
|
|||||||
{
|
{
|
||||||
desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt",
|
desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt",
|
||||||
selectedArtApexContributions: "art.prebuilt.contributions",
|
selectedArtApexContributions: "art.prebuilt.contributions",
|
||||||
expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof",
|
expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt",
|
desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt",
|
||||||
selectedArtApexContributions: "art.prebuilt.v2.contributions",
|
selectedArtApexContributions: "art.prebuilt.v2.contributions",
|
||||||
expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.v2.deapexer/android_common/deapexer/etc/boot-image.prof",
|
expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_com.android.art/deapexer/etc/boot-image.prof",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
312
apex/prebuilt.go
312
apex/prebuilt.go
@@ -194,9 +194,8 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex
|
// If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex
|
||||||
func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) {
|
func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext, di *android.DeapexerInfo) {
|
||||||
// If this apex does not export anything, return
|
if di == nil {
|
||||||
if !p.hasExportedDeps() {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// If this prebuilt apex has not been selected, return
|
// If this prebuilt apex has not been selected, return
|
||||||
@@ -205,10 +204,7 @@ func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
// Use apex_name to determine the api domain of this prebuilt apex
|
// Use apex_name to determine the api domain of this prebuilt apex
|
||||||
apexName := p.ApexVariationName()
|
apexName := p.ApexVariationName()
|
||||||
di, err := android.FindDeapexerProviderForModule(ctx)
|
// TODO: do not compute twice
|
||||||
if err != nil {
|
|
||||||
ctx.ModuleErrorf(err.Error())
|
|
||||||
}
|
|
||||||
dc := dexpreopt.GetGlobalConfig(ctx)
|
dc := dexpreopt.GetGlobalConfig(ctx)
|
||||||
systemServerJarList := dc.AllApexSystemServerJars(ctx)
|
systemServerJarList := dc.AllApexSystemServerJars(ctx)
|
||||||
|
|
||||||
@@ -257,26 +253,6 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
|
|||||||
return entriesList
|
return entriesList
|
||||||
}
|
}
|
||||||
|
|
||||||
// prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and
|
|
||||||
// apex_set in order to create the modules needed to provide access to the prebuilt .apex file.
|
|
||||||
type prebuiltApexModuleCreator interface {
|
|
||||||
createPrebuiltApexModules(ctx android.BottomUpMutatorContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
// prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the
|
|
||||||
// prebuiltApexModuleCreator's createPrebuiltApexModules method.
|
|
||||||
//
|
|
||||||
// It is registered as a pre-arch mutator as it must run after the ComponentDepsMutator because it
|
|
||||||
// will need to access dependencies added by that (exported modules) but must run before the
|
|
||||||
// DepsMutator so that the deapexer module it creates can add dependencies onto itself from the
|
|
||||||
// exported modules.
|
|
||||||
func prebuiltApexModuleCreatorMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
module := ctx.Module()
|
|
||||||
if creator, ok := module.(prebuiltApexModuleCreator); ok {
|
|
||||||
creator.createPrebuiltApexModules(ctx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *prebuiltCommon) hasExportedDeps() bool {
|
func (p *prebuiltCommon) hasExportedDeps() bool {
|
||||||
return len(p.prebuiltCommonProperties.Exported_bootclasspath_fragments) > 0 ||
|
return len(p.prebuiltCommonProperties.Exported_bootclasspath_fragments) > 0 ||
|
||||||
len(p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments) > 0
|
len(p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments) > 0
|
||||||
@@ -403,34 +379,6 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prebuiltApexSelectorModule is a private module type that is only created by the prebuilt_apex
|
|
||||||
// module. It selects the apex to use and makes it available for use by prebuilt_apex and the
|
|
||||||
// deapexer.
|
|
||||||
type prebuiltApexSelectorModule struct {
|
|
||||||
android.ModuleBase
|
|
||||||
|
|
||||||
apexFileProperties ApexFileProperties
|
|
||||||
|
|
||||||
inputApex android.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
func privateApexSelectorModuleFactory() android.Module {
|
|
||||||
module := &prebuiltApexSelectorModule{}
|
|
||||||
module.AddProperties(
|
|
||||||
&module.apexFileProperties,
|
|
||||||
)
|
|
||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *prebuiltApexSelectorModule) Srcs() android.Paths {
|
|
||||||
return android.Paths{p.inputApex}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *prebuiltApexSelectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
p.inputApex = android.SingleSourcePathFromSupplier(ctx, p.apexFileProperties.prebuiltApexSelector, "src")
|
|
||||||
}
|
|
||||||
|
|
||||||
type Prebuilt struct {
|
type Prebuilt struct {
|
||||||
prebuiltCommon
|
prebuiltCommon
|
||||||
|
|
||||||
@@ -473,11 +421,11 @@ type ApexFileProperties struct {
|
|||||||
// to use methods on it that are specific to the current module.
|
// to use methods on it that are specific to the current module.
|
||||||
//
|
//
|
||||||
// See the ApexFileProperties.Src property.
|
// See the ApexFileProperties.Src property.
|
||||||
func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) []string {
|
func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) string {
|
||||||
multiTargets := prebuilt.MultiTargets()
|
multiTargets := prebuilt.MultiTargets()
|
||||||
if len(multiTargets) != 1 {
|
if len(multiTargets) != 1 {
|
||||||
ctx.OtherModuleErrorf(prebuilt, "compile_multilib shouldn't be \"both\" for prebuilt_apex")
|
ctx.OtherModuleErrorf(prebuilt, "compile_multilib shouldn't be \"both\" for prebuilt_apex")
|
||||||
return nil
|
return ""
|
||||||
}
|
}
|
||||||
var src string
|
var src string
|
||||||
switch multiTargets[0].Arch.ArchType {
|
switch multiTargets[0].Arch.ArchType {
|
||||||
@@ -510,7 +458,7 @@ func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext,
|
|||||||
// logic from reporting a more general, less useful message.
|
// logic from reporting a more general, less useful message.
|
||||||
}
|
}
|
||||||
|
|
||||||
return []string{src}
|
return src
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrebuiltProperties struct {
|
type PrebuiltProperties struct {
|
||||||
@@ -527,35 +475,19 @@ func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool {
|
|||||||
func PrebuiltFactory() android.Module {
|
func PrebuiltFactory() android.Module {
|
||||||
module := &Prebuilt{}
|
module := &Prebuilt{}
|
||||||
module.AddProperties(&module.properties)
|
module.AddProperties(&module.properties)
|
||||||
module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties)
|
module.prebuiltCommon.prebuiltCommonProperties = &module.properties.PrebuiltCommonProperties
|
||||||
|
|
||||||
|
// init the module as a prebuilt
|
||||||
|
// even though this module type has srcs, use `InitPrebuiltModuleWithoutSrcs`, since the existing
|
||||||
|
// InitPrebuiltModule* are not friendly with Sources of Configurable type.
|
||||||
|
// The actual src will be evaluated in GenerateAndroidBuildActions.
|
||||||
|
android.InitPrebuiltModuleWithoutSrcs(module)
|
||||||
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, apexFileProperties *ApexFileProperties) {
|
func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext) DeapexerProperties {
|
||||||
props := struct {
|
|
||||||
Name *string
|
|
||||||
}{
|
|
||||||
Name: proptools.StringPtr(name),
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.CreateModule(privateApexSelectorModuleFactory,
|
|
||||||
&props,
|
|
||||||
apexFileProperties,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// createDeapexerModuleIfNeeded will create a deapexer module if it is needed.
|
|
||||||
//
|
|
||||||
// A deapexer module is only needed when the prebuilt apex specifies one or more modules in either
|
|
||||||
// the `exported_bootclasspath_fragments` properties as that indicates that
|
|
||||||
// the listed modules need access to files from within the prebuilt .apex file.
|
|
||||||
func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutatorContext, deapexerName string, apexFileSource string) {
|
|
||||||
// Only create the deapexer module if it is needed.
|
|
||||||
if !p.hasExportedDeps() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the deapexer properties from the transitive dependencies of this module.
|
// Compute the deapexer properties from the transitive dependencies of this module.
|
||||||
commonModules := []string{}
|
commonModules := []string{}
|
||||||
dexpreoptProfileGuidedModules := []string{}
|
dexpreoptProfileGuidedModules := []string{}
|
||||||
@@ -589,7 +521,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutato
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Create properties for deapexer module.
|
// Create properties for deapexer module.
|
||||||
deapexerProperties := &DeapexerProperties{
|
deapexerProperties := DeapexerProperties{
|
||||||
// Remove any duplicates from the common modules lists as a module may be included via a direct
|
// Remove any duplicates from the common modules lists as a module may be included via a direct
|
||||||
// dependency as well as transitive ones.
|
// dependency as well as transitive ones.
|
||||||
CommonModules: android.SortedUniqueStrings(commonModules),
|
CommonModules: android.SortedUniqueStrings(commonModules),
|
||||||
@@ -598,22 +530,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutato
|
|||||||
|
|
||||||
// Populate the exported files property in a fixed order.
|
// Populate the exported files property in a fixed order.
|
||||||
deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles)
|
deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles)
|
||||||
|
return deapexerProperties
|
||||||
props := struct {
|
|
||||||
Name *string
|
|
||||||
Selected_apex *string
|
|
||||||
}{
|
|
||||||
Name: proptools.StringPtr(deapexerName),
|
|
||||||
Selected_apex: proptools.StringPtr(apexFileSource),
|
|
||||||
}
|
|
||||||
ctx.CreateModule(privateDeapexerFactory,
|
|
||||||
&props,
|
|
||||||
deapexerProperties,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func apexSelectorModuleName(baseModuleName string) string {
|
|
||||||
return baseModuleName + ".apex.selector"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name string) string {
|
func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name string) string {
|
||||||
@@ -659,92 +576,46 @@ var (
|
|||||||
exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
|
exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"}
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
|
|
||||||
|
|
||||||
// createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the
|
|
||||||
// build.
|
|
||||||
//
|
|
||||||
// If this needs to make files from within a `.apex` file available for use by other Soong modules,
|
|
||||||
// e.g. make dex implementation jars available for `contents` listed in exported_bootclasspath_fragments,
|
|
||||||
// it does so as follows:
|
|
||||||
//
|
|
||||||
// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and
|
|
||||||
// makes them available for use by other modules, at both Soong and ninja levels.
|
|
||||||
//
|
|
||||||
// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what
|
|
||||||
// an `apex` module does. That ensures that code which looks for specific apex variant, e.g.
|
|
||||||
// dexpreopt, will work the same way from source and prebuilt.
|
|
||||||
//
|
|
||||||
// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto
|
|
||||||
// itself so that they can retrieve the file paths to those files.
|
|
||||||
//
|
|
||||||
// It also creates a child module `selector` that is responsible for selecting the appropriate
|
|
||||||
// input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons:
|
|
||||||
//
|
|
||||||
// 1. To dedup the selection logic so it only runs in one module.
|
|
||||||
//
|
|
||||||
// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an
|
|
||||||
// `apex_set`.
|
|
||||||
//
|
|
||||||
// prebuilt_apex
|
|
||||||
// / | \
|
|
||||||
// / | \
|
|
||||||
// V V V
|
|
||||||
// selector <--- deapexer <--- exported java lib
|
|
||||||
func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
|
|
||||||
apexSelectorModuleName := apexSelectorModuleName(p.Name())
|
|
||||||
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
|
|
||||||
|
|
||||||
apexFileSource := ":" + apexSelectorModuleName
|
|
||||||
p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(p.Name()), apexFileSource)
|
|
||||||
|
|
||||||
// Add a source reference to retrieve the selected apex from the selector module.
|
|
||||||
p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
|
func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
p.prebuiltApexContentsDeps(ctx)
|
p.prebuiltApexContentsDeps(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|
||||||
if p.hasExportedDeps() {
|
|
||||||
// Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module
|
|
||||||
// The deapexer will return a provider which will be used to determine the exported artfifacts from this prebuilt.
|
|
||||||
ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.Name()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ ApexInfoMutator = (*Prebuilt)(nil)
|
var _ ApexInfoMutator = (*Prebuilt)(nil)
|
||||||
|
|
||||||
func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
|
func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
|
||||||
p.apexInfoMutator(mctx)
|
p.apexInfoMutator(mctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creates the build rules to deapex the prebuilt, and returns a deapexerInfo
|
||||||
|
func (p *prebuiltCommon) getDeapexerInfo(ctx android.ModuleContext, apexFile android.Path) *android.DeapexerInfo {
|
||||||
|
if !p.hasExportedDeps() {
|
||||||
|
// nothing to do
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
deapexerProps := p.getDeapexerPropertiesIfNeeded(ctx)
|
||||||
|
return deapex(ctx, apexFile, deapexerProps)
|
||||||
|
}
|
||||||
|
|
||||||
// Set a provider containing information about the jars and .prof provided by the apex
|
// Set a provider containing information about the jars and .prof provided by the apex
|
||||||
// Apexes built from prebuilts retrieve this information by visiting its internal deapexer module
|
// Apexes built from prebuilts retrieve this information by visiting its internal deapexer module
|
||||||
// Used by dex_bootjars to generate the boot image
|
// Used by dex_bootjars to generate the boot image
|
||||||
func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) {
|
func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext, di *android.DeapexerInfo) {
|
||||||
if !p.hasExportedDeps() {
|
if di == nil {
|
||||||
// nothing to do
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if di, err := android.FindDeapexerProviderForModule(ctx); err == nil {
|
javaModuleToDexPath := map[string]android.Path{}
|
||||||
javaModuleToDexPath := map[string]android.Path{}
|
for _, commonModule := range di.GetExportedModuleNames() {
|
||||||
for _, commonModule := range di.GetExportedModuleNames() {
|
if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil {
|
||||||
if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil {
|
javaModuleToDexPath[commonModule] = dex
|
||||||
javaModuleToDexPath[commonModule] = dex
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exports := android.ApexExportsInfo{
|
|
||||||
ApexName: p.ApexVariationName(),
|
|
||||||
ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex),
|
|
||||||
LibraryNameToDexJarPathOnHost: javaModuleToDexPath,
|
|
||||||
}
|
|
||||||
android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
|
|
||||||
} else {
|
|
||||||
ctx.ModuleErrorf(err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports := android.ApexExportsInfo{
|
||||||
|
ApexName: p.ApexVariationName(),
|
||||||
|
ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex),
|
||||||
|
LibraryNameToDexJarPathOnHost: javaModuleToDexPath,
|
||||||
|
}
|
||||||
|
android.SetProvider(ctx, android.ApexExportsInfoProvider, exports)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
|
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
|
||||||
@@ -780,7 +651,7 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
p.apexKeysPath = writeApexKeys(ctx, p)
|
p.apexKeysPath = writeApexKeys(ctx, p)
|
||||||
// TODO(jungjw): Check the key validity.
|
// TODO(jungjw): Check the key validity.
|
||||||
p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path()
|
p.inputApex = android.PathForModuleSrc(ctx, p.properties.prebuiltApexSelector(ctx, ctx.Module()))
|
||||||
p.installDir = android.PathForModuleInstall(ctx, "apex")
|
p.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
p.installFilename = p.InstallFilename()
|
p.installFilename = p.InstallFilename()
|
||||||
if !strings.HasSuffix(p.installFilename, imageApexSuffix) {
|
if !strings.HasSuffix(p.installFilename, imageApexSuffix) {
|
||||||
@@ -798,11 +669,13 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deapexerInfo := p.getDeapexerInfo(ctx, p.inputApex)
|
||||||
|
|
||||||
// dexpreopt any system server jars if present
|
// dexpreopt any system server jars if present
|
||||||
p.dexpreoptSystemServerJars(ctx)
|
p.dexpreoptSystemServerJars(ctx, deapexerInfo)
|
||||||
|
|
||||||
// provide info used for generating the boot image
|
// provide info used for generating the boot image
|
||||||
p.provideApexExportsInfo(ctx)
|
p.provideApexExportsInfo(ctx, deapexerInfo)
|
||||||
|
|
||||||
p.providePrebuiltInfo(ctx)
|
p.providePrebuiltInfo(ctx)
|
||||||
|
|
||||||
@@ -838,26 +711,11 @@ type prebuiltApexExtractorModule struct {
|
|||||||
extractedApex android.WritablePath
|
extractedApex android.WritablePath
|
||||||
}
|
}
|
||||||
|
|
||||||
func privateApexExtractorModuleFactory() android.Module {
|
// extract registers the build actions to extract an apex from .apks file
|
||||||
module := &prebuiltApexExtractorModule{}
|
// returns the path of the extracted apex
|
||||||
module.AddProperties(
|
func extract(ctx android.ModuleContext, apexSet android.Path, prerelease *bool) android.Path {
|
||||||
&module.properties,
|
|
||||||
)
|
|
||||||
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
|
||||||
return module
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *prebuiltApexExtractorModule) Srcs() android.Paths {
|
|
||||||
return android.Paths{p.extractedApex}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|
||||||
srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string {
|
|
||||||
return p.properties.prebuiltSrcs(ctx)
|
|
||||||
}
|
|
||||||
defaultAllowPrerelease := ctx.Config().IsEnvTrue("SOONG_ALLOW_PRERELEASE_APEXES")
|
defaultAllowPrerelease := ctx.Config().IsEnvTrue("SOONG_ALLOW_PRERELEASE_APEXES")
|
||||||
apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
|
extractedApex := android.PathForModuleOut(ctx, "extracted", apexSet.Base())
|
||||||
p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
|
|
||||||
// Filter out NativeBridge archs (b/260115309)
|
// Filter out NativeBridge archs (b/260115309)
|
||||||
abis := java.SupportedAbis(ctx, true)
|
abis := java.SupportedAbis(ctx, true)
|
||||||
ctx.Build(pctx,
|
ctx.Build(pctx,
|
||||||
@@ -865,14 +723,16 @@ func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.Mo
|
|||||||
Rule: extractMatchingApex,
|
Rule: extractMatchingApex,
|
||||||
Description: "Extract an apex from an apex set",
|
Description: "Extract an apex from an apex set",
|
||||||
Inputs: android.Paths{apexSet},
|
Inputs: android.Paths{apexSet},
|
||||||
Output: p.extractedApex,
|
Output: extractedApex,
|
||||||
Args: map[string]string{
|
Args: map[string]string{
|
||||||
"abis": strings.Join(abis, ","),
|
"abis": strings.Join(abis, ","),
|
||||||
"allow-prereleased": strconv.FormatBool(proptools.BoolDefault(p.properties.Prerelease, defaultAllowPrerelease)),
|
"allow-prereleased": strconv.FormatBool(proptools.BoolDefault(prerelease, defaultAllowPrerelease)),
|
||||||
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
|
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
|
||||||
"skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")),
|
"skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")),
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
return extractedApex
|
||||||
}
|
}
|
||||||
|
|
||||||
type ApexSet struct {
|
type ApexSet struct {
|
||||||
@@ -941,48 +801,18 @@ func (a *ApexSet) hasSanitizedSource(sanitizer string) bool {
|
|||||||
func apexSetFactory() android.Module {
|
func apexSetFactory() android.Module {
|
||||||
module := &ApexSet{}
|
module := &ApexSet{}
|
||||||
module.AddProperties(&module.properties)
|
module.AddProperties(&module.properties)
|
||||||
module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties)
|
module.prebuiltCommon.prebuiltCommonProperties = &module.properties.PrebuiltCommonProperties
|
||||||
|
|
||||||
|
// init the module as a prebuilt
|
||||||
|
// even though this module type has srcs, use `InitPrebuiltModuleWithoutSrcs`, since the existing
|
||||||
|
// InitPrebuiltModule* are not friendly with Sources of Configurable type.
|
||||||
|
// The actual src will be evaluated in GenerateAndroidBuildActions.
|
||||||
|
android.InitPrebuiltModuleWithoutSrcs(module)
|
||||||
|
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
func createApexExtractorModule(ctx android.BottomUpMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) {
|
|
||||||
props := struct {
|
|
||||||
Name *string
|
|
||||||
}{
|
|
||||||
Name: proptools.StringPtr(name),
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.CreateModule(privateApexExtractorModuleFactory,
|
|
||||||
&props,
|
|
||||||
apexExtractorProperties,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func apexExtractorModuleName(baseModuleName string) string {
|
|
||||||
return baseModuleName + ".apex.extractor"
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ prebuiltApexModuleCreator = (*ApexSet)(nil)
|
|
||||||
|
|
||||||
// createPrebuiltApexModules creates modules necessary to export files from the apex set to other
|
|
||||||
// modules.
|
|
||||||
//
|
|
||||||
// This effectively does for apex_set what Prebuilt.createPrebuiltApexModules does for a
|
|
||||||
// prebuilt_apex except that instead of creating a selector module which selects one .apex file
|
|
||||||
// from those provided this creates an extractor module which extracts the appropriate .apex file
|
|
||||||
// from the zip file containing them.
|
|
||||||
func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) {
|
|
||||||
apexExtractorModuleName := apexExtractorModuleName(a.Name())
|
|
||||||
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
|
|
||||||
|
|
||||||
apexFileSource := ":" + apexExtractorModuleName
|
|
||||||
a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(a.Name()), apexFileSource)
|
|
||||||
|
|
||||||
// After passing the arch specific src properties to the creating the apex selector module
|
|
||||||
a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
|
func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
a.prebuiltApexContentsDeps(ctx)
|
a.prebuiltApexContentsDeps(ctx)
|
||||||
}
|
}
|
||||||
@@ -1005,7 +835,15 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix)
|
ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix)
|
||||||
}
|
}
|
||||||
|
|
||||||
inputApex := android.OptionalPathForModuleSrc(ctx, a.prebuiltCommonProperties.Selected_apex).Path()
|
var apexSet android.Path
|
||||||
|
if srcs := a.properties.prebuiltSrcs(ctx); len(srcs) == 1 {
|
||||||
|
apexSet = android.PathForModuleSrc(ctx, srcs[0])
|
||||||
|
} else {
|
||||||
|
ctx.ModuleErrorf("Expected exactly one source apex_set file, found %v\n", srcs)
|
||||||
|
}
|
||||||
|
|
||||||
|
extractedApex := extract(ctx, apexSet, a.properties.Prerelease)
|
||||||
|
|
||||||
a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
|
a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
|
||||||
|
|
||||||
// Build the output APEX. If compression is not enabled, make sure the output is not compressed even if the input is compressed
|
// Build the output APEX. If compression is not enabled, make sure the output is not compressed even if the input is compressed
|
||||||
@@ -1015,7 +853,7 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
ctx.Build(pctx, android.BuildParams{
|
ctx.Build(pctx, android.BuildParams{
|
||||||
Rule: buildRule,
|
Rule: buildRule,
|
||||||
Input: inputApex,
|
Input: extractedApex,
|
||||||
Output: a.outputApex,
|
Output: a.outputApex,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1024,11 +862,13 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deapexerInfo := a.getDeapexerInfo(ctx, extractedApex)
|
||||||
|
|
||||||
// dexpreopt any system server jars if present
|
// dexpreopt any system server jars if present
|
||||||
a.dexpreoptSystemServerJars(ctx)
|
a.dexpreoptSystemServerJars(ctx, deapexerInfo)
|
||||||
|
|
||||||
// provide info used for generating the boot image
|
// provide info used for generating the boot image
|
||||||
a.provideApexExportsInfo(ctx)
|
a.provideApexExportsInfo(ctx, deapexerInfo)
|
||||||
|
|
||||||
a.providePrebuiltInfo(ctx)
|
a.providePrebuiltInfo(ctx)
|
||||||
|
|
||||||
|
@@ -277,8 +277,6 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
|
|||||||
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
|
java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{
|
||||||
`all_apex_contributions`,
|
`all_apex_contributions`,
|
||||||
`dex2oatd`,
|
`dex2oatd`,
|
||||||
`prebuilt_myapex.apex.selector`,
|
|
||||||
`prebuilt_myapex.deapexer`,
|
|
||||||
`prebuilt_mysystemserverclasspathfragment`,
|
`prebuilt_mysystemserverclasspathfragment`,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -286,10 +284,9 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
|
|||||||
`all_apex_contributions`,
|
`all_apex_contributions`,
|
||||||
`prebuilt_bar`,
|
`prebuilt_bar`,
|
||||||
`prebuilt_foo`,
|
`prebuilt_foo`,
|
||||||
`prebuilt_myapex.deapexer`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{
|
ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{
|
||||||
"javalib/foo.jar",
|
"javalib/foo.jar",
|
||||||
"javalib/bar.jar",
|
"javalib/bar.jar",
|
||||||
"javalib/bar.jar.prof",
|
"javalib/bar.jar.prof",
|
||||||
@@ -439,10 +436,9 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) {
|
|||||||
`all_apex_contributions`,
|
`all_apex_contributions`,
|
||||||
`prebuilt_bar`,
|
`prebuilt_bar`,
|
||||||
`prebuilt_foo`,
|
`prebuilt_foo`,
|
||||||
`prebuilt_myapex.deapexer`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{
|
ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{
|
||||||
"javalib/foo.jar",
|
"javalib/foo.jar",
|
||||||
"javalib/bar.jar",
|
"javalib/bar.jar",
|
||||||
"javalib/bar.jar.prof",
|
"javalib/bar.jar.prof",
|
||||||
|
@@ -414,6 +414,12 @@ func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleCont
|
|||||||
// Cross-cutting metadata dependencies are metadata.
|
// Cross-cutting metadata dependencies are metadata.
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// Dependency to the bootclasspath fragment of another apex
|
||||||
|
// e.g. concsrypt-bootclasspath-fragment --> art-bootclasspath-fragment
|
||||||
|
if tag == bootclasspathFragmentDepTag {
|
||||||
|
return false
|
||||||
|
|
||||||
|
}
|
||||||
panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
|
panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1099,22 +1105,10 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an
|
|||||||
return &output
|
return &output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED: this information is now generated in the context of the top level prebuilt apex.
|
||||||
// produceBootImageProfile extracts the boot image profile from the APEX if available.
|
// produceBootImageProfile extracts the boot image profile from the APEX if available.
|
||||||
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath {
|
func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath {
|
||||||
// This module does not provide a boot image profile.
|
return android.PathForModuleInstall(ctx, "intentionally_no_longer_supported")
|
||||||
if module.getProfileProviderApex(ctx) == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
di, err := android.FindDeapexerProviderForModule(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// An error was found, possibly due to multiple apexes in the tree that export this library
|
|
||||||
// Defer the error till a client tries to call getProfilePath
|
|
||||||
module.profilePathErr = err
|
|
||||||
return nil // An error has been reported by FindDeapexerProviderForModule.
|
|
||||||
}
|
|
||||||
|
|
||||||
return di.PrebuiltExportPath(ProfileInstallPathInApex)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
|
func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path {
|
||||||
|
39
java/java.go
39
java/java.go
@@ -2818,41 +2818,14 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
// If this is a variant created for a prebuilt_apex then use the dex implementation jar
|
// Shared libraries deapexed from prebuilt apexes are no longer supported.
|
||||||
// obtained from the associated deapexer module.
|
// Set the dexJarBuildPath to a fake path.
|
||||||
|
// This allows soong analysis pass, but will be an error during ninja execution if there are
|
||||||
|
// any rdeps.
|
||||||
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
||||||
if ai.ForPrebuiltApex {
|
if ai.ForPrebuiltApex {
|
||||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
j.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported"))
|
||||||
di, err := android.FindDeapexerProviderForModule(ctx)
|
j.initHiddenAPI(ctx, j.dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
|
||||||
if err != nil {
|
|
||||||
// An error was found, possibly due to multiple apexes in the tree that export this library
|
|
||||||
// Defer the error till a client tries to call DexJarBuildPath
|
|
||||||
j.dexJarFileErr = err
|
|
||||||
j.initHiddenAPIError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(j.BaseModuleName())
|
|
||||||
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
|
|
||||||
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
|
||||||
j.dexJarFile = dexJarFile
|
|
||||||
installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName()))
|
|
||||||
j.dexJarInstallFile = installPath
|
|
||||||
|
|
||||||
j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath)
|
|
||||||
setUncompressDex(ctx, &j.dexpreopter, &j.dexer)
|
|
||||||
j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex
|
|
||||||
|
|
||||||
if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
|
|
||||||
j.dexpreopter.inputProfilePathOnHost = profilePath
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the hiddenapi structure.
|
|
||||||
j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex)
|
|
||||||
} else {
|
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
|
||||||
// prebuilt_apex has been configured to export the java library dex file.
|
|
||||||
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName())
|
|
||||||
}
|
|
||||||
} else if Bool(j.dexProperties.Compile_dex) {
|
} else if Bool(j.dexProperties.Compile_dex) {
|
||||||
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
|
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
|
||||||
if sdkDep.invalidVersion {
|
if sdkDep.invalidVersion {
|
||||||
|
@@ -2768,40 +2768,14 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
// If this is a variant created for a prebuilt_apex then use the dex implementation jar
|
// Shared libraries deapexed from prebuilt apexes are no longer supported.
|
||||||
// obtained from the associated deapexer module.
|
// Set the dexJarBuildPath to a fake path.
|
||||||
|
// This allows soong analysis pass, but will be an error during ninja execution if there are
|
||||||
|
// any rdeps.
|
||||||
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
|
||||||
if ai.ForPrebuiltApex {
|
if ai.ForPrebuiltApex {
|
||||||
// Get the path of the dex implementation jar from the `deapexer` module.
|
module.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported"))
|
||||||
di, err := android.FindDeapexerProviderForModule(ctx)
|
module.initHiddenAPI(ctx, module.dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
||||||
if err != nil {
|
|
||||||
// An error was found, possibly due to multiple apexes in the tree that export this library
|
|
||||||
// Defer the error till a client tries to call DexJarBuildPath
|
|
||||||
module.dexJarFileErr = err
|
|
||||||
module.initHiddenAPIError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(module.BaseModuleName())
|
|
||||||
if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil {
|
|
||||||
dexJarFile := makeDexJarPathFromPath(dexOutputPath)
|
|
||||||
module.dexJarFile = dexJarFile
|
|
||||||
installPath := android.PathForModuleInPartitionInstall(
|
|
||||||
ctx, "apex", ai.ApexVariationName, dexJarFileApexRootRelative)
|
|
||||||
module.installFile = installPath
|
|
||||||
module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil)
|
|
||||||
|
|
||||||
module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath)
|
|
||||||
module.dexpreopter.isSDKLibrary = true
|
|
||||||
module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &module.dexpreopter)
|
|
||||||
|
|
||||||
if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil {
|
|
||||||
module.dexpreopter.inputProfilePathOnHost = profilePath
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This should never happen as a variant for a prebuilt_apex is only created if the
|
|
||||||
// prebuilt_apex has been configured to export the java library dex file.
|
|
||||||
ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -204,7 +204,19 @@ java_import {
|
|||||||
.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar
|
.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar
|
||||||
.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar
|
.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar
|
||||||
`),
|
`),
|
||||||
snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot),
|
snapshotTestPreparer(checkSnapshotWithoutSource, android.GroupFixturePreparers(
|
||||||
|
preparerForSnapshot,
|
||||||
|
// Flag ART prebuilts
|
||||||
|
android.FixtureMergeMockFs(android.MockFS{
|
||||||
|
"apex_contributions/Android.bp": []byte(`
|
||||||
|
apex_contributions {
|
||||||
|
name: "prebuilt_art_contributions",
|
||||||
|
contents: ["prebuilt_com.android.art"],
|
||||||
|
api_domain: "com.android.art",
|
||||||
|
}
|
||||||
|
`)}),
|
||||||
|
android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"),
|
||||||
|
)),
|
||||||
|
|
||||||
// Check the behavior of the snapshot without the source.
|
// Check the behavior of the snapshot without the source.
|
||||||
snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) {
|
snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) {
|
||||||
@@ -212,8 +224,8 @@ java_import {
|
|||||||
checkBootJarsPackageCheckRule(t, result,
|
checkBootJarsPackageCheckRule(t, result,
|
||||||
append(
|
append(
|
||||||
[]string{
|
[]string{
|
||||||
"out/soong/.intermediates/prebuilts/apex/prebuilt_com.android.art.deapexer/android_common/deapexer/javalib/core1.jar",
|
"out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core1.jar",
|
||||||
"out/soong/.intermediates/prebuilts/apex/prebuilt_com.android.art.deapexer/android_common/deapexer/javalib/core2.jar",
|
"out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core2.jar",
|
||||||
"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
|
"out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar",
|
||||||
},
|
},
|
||||||
java.ApexBootJarDexJarPaths...,
|
java.ApexBootJarDexJarPaths...,
|
||||||
|
Reference in New Issue
Block a user