Merge changes I0edb681b,I0ea2327f into main am: e2860d9db6

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/3273493

Change-Id: I1616399c194df10dd2da09eab4e76cc8ebf75438
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Spandan Das
2024-09-23 20:55:45 +00:00
committed by Automerger Merge Worker
11 changed files with 151 additions and 510 deletions

View File

@@ -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")

View File

@@ -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`)
@@ -7973,189 +7954,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 {
@@ -8267,12 +8065,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)
}) })
} }
@@ -10959,12 +10761,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",
}, },
} }

View File

@@ -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) {
@@ -562,26 +578,18 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
`dex2oatd`, `dex2oatd`,
`prebuilt_art-bootclasspath-fragment`, `prebuilt_art-bootclasspath-fragment`,
`prebuilt_com.android.art.apex.selector`, `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

View File

@@ -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
} }

View File

@@ -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 {

View File

@@ -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)
@@ -545,17 +541,7 @@ func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, a
) )
} }
// createDeapexerModuleIfNeeded will create a deapexer module if it is needed. func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext) DeapexerProperties {
//
// 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 +575,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,18 +584,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 { func apexSelectorModuleName(baseModuleName string) string {
@@ -661,6 +636,7 @@ var (
var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) var _ prebuiltApexModuleCreator = (*Prebuilt)(nil)
// DEPRECATED: This dependency graph is being removed.
// createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the // createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the
// build. // build.
// //
@@ -696,7 +672,6 @@ func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext)
createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties) createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties)
apexFileSource := ":" + apexSelectorModuleName apexFileSource := ":" + apexSelectorModuleName
p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(p.Name()), apexFileSource)
// Add a source reference to retrieve the selected apex from the selector module. // Add a source reference to retrieve the selected apex from the selector module.
p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -706,45 +681,43 @@ 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) *android.DeapexerInfo {
if !p.hasExportedDeps() {
// nothing to do
return nil
}
apexFile := android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path()
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
@@ -798,11 +771,13 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return return
} }
deapexerInfo := p.getDeapexerInfo(ctx)
// 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)
@@ -977,7 +952,6 @@ func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext)
createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties) createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties)
apexFileSource := ":" + apexExtractorModuleName apexFileSource := ":" + apexExtractorModuleName
a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(a.Name()), apexFileSource)
// After passing the arch specific src properties to the creating the apex selector module // After passing the arch specific src properties to the creating the apex selector module
a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource)
@@ -1024,11 +998,13 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
return return
} }
deapexerInfo := a.getDeapexerInfo(ctx)
// 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)

View File

@@ -278,7 +278,6 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) {
`all_apex_contributions`, `all_apex_contributions`,
`dex2oatd`, `dex2oatd`,
`prebuilt_myapex.apex.selector`, `prebuilt_myapex.apex.selector`,
`prebuilt_myapex.deapexer`,
`prebuilt_mysystemserverclasspathfragment`, `prebuilt_mysystemserverclasspathfragment`,
}) })
@@ -286,10 +285,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 +437,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",

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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())
}
} }
} }

View File

@@ -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...,