Merge "Add support for specifying api provided by bootclasspath_fragment" am: 0948060f50 am: 126a48b0c5 am: e30368dc81

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

Change-Id: I4216d71d26a2e6256220359c60de0927119f5731
This commit is contained in:
Paul Duffin 2021-04-29 10:02:29 +00:00 committed by Automerger Merge Worker
commit a7c96bb1e5
4 changed files with 147 additions and 9 deletions

View File

@ -161,3 +161,59 @@ var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
// The tag used for dependencies onto bootclasspath_fragments.
var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}
// BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the
// bootclasspath that are nested within the main BootclasspathAPIProperties.
type BootclasspathNestedAPIProperties struct {
// java_library or preferably, java_sdk_library modules providing stub classes that define the
// APIs provided by this bootclasspath_fragment.
Stub_libs []string
}
// BootclasspathAPIProperties defines properties for defining the API provided by parts of the
// bootclasspath.
type BootclasspathAPIProperties struct {
// Api properties provide information about the APIs provided by the bootclasspath_fragment.
// Properties in this section apply to public, system and test api scopes. They DO NOT apply to
// core_platform as that is a special, ART specific scope, that does not follow the pattern and so
// has its own section. It is in the process of being deprecated and replaced by the system scope
// but this will remain for the foreseeable future to maintain backwards compatibility.
//
// Every bootclasspath_fragment must specify at least one stubs_lib in this section and must
// specify stubs for all the APIs provided by its contents. Failure to do so will lead to those
// methods being inaccessible to other parts of Android, including but not limited to
// applications.
Api BootclasspathNestedAPIProperties
// Properties related to the core platform API surface.
//
// This must only be used by the following modules:
// * ART
// * Conscrypt
// * I18N
//
// The bootclasspath_fragments for each of the above modules must specify at least one stubs_lib
// and must specify stubs for all the APIs provided by its contents. Failure to do so will lead to
// those methods being inaccessible to the other modules in the list.
Core_platform_api BootclasspathNestedAPIProperties
}
// sdkKindToStubLibs calculates the stub library modules for each relevant android.SdkKind from the
// Stub_libs properties.
func (p BootclasspathAPIProperties) sdkKindToStubLibs() map[android.SdkKind][]string {
m := map[android.SdkKind][]string{}
for _, kind := range []android.SdkKind{android.SdkPublic, android.SdkSystem, android.SdkTest} {
m[kind] = p.Api.Stub_libs
}
m[android.SdkCorePlatform] = p.Core_platform_api.Stub_libs
return m
}
// bootclasspathApiInfo contains paths resolved from BootclasspathAPIProperties
type bootclasspathApiInfo struct {
// stubJarsByKind maps from the android.SdkKind to the paths containing dex stub jars for each
// kind.
stubJarsByKind map[android.SdkKind]android.Paths
}
var bootclasspathApiInfoProvider = blueprint.NewProvider(bootclasspathApiInfo{})

View File

@ -88,6 +88,9 @@ type BootclasspathFragmentCoverageAffectedProperties struct {
//
// The order of this list matters as it is the order that is used in the bootclasspath.
Contents []string
// The properties for specifying the API stubs provided by this fragment.
BootclasspathAPIProperties
}
type bootclasspathFragmentProperties struct {
@ -316,6 +319,9 @@ func (b *BootclasspathFragmentModule) ComponentDepsMutator(ctx android.BottomUpM
}
func (b *BootclasspathFragmentModule) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies onto all the modules that provide the API stubs for classes on this
// bootclasspath fragment.
hiddenAPIAddStubLibDependencies(ctx, b.properties.sdkKindToStubLibs())
if SkipDexpreoptBootJars(ctx) {
return
@ -384,6 +390,13 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
// Store the information for use by platform_bootclasspath.
ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
// Convert the kind specific lists of modules into kind specific lists of jars.
stubJarsByKind := hiddenAPIGatherStubLibDexJarPaths(ctx)
// Store the information for use by other modules.
bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: stubJarsByKind}
ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
}
type bootclasspathFragmentMemberType struct {

View File

@ -171,3 +171,68 @@ func TestBootclasspathFragment_Coverage(t *testing.T) {
checkContents(t, result, "mybootlib", "coveragelib")
})
}
func TestBootclasspathFragment_StubLibs(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForTestWithBootclasspathFragment,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("mysdklibrary", "mycoreplatform"),
).RunTestWithBp(t, `
bootclasspath_fragment {
name: "myfragment",
contents: ["mysdklibrary"],
api: {
stub_libs: [
"mystublib",
"mysdklibrary",
],
},
core_platform_api: {
stub_libs: ["mycoreplatform"],
},
}
java_library {
name: "mystublib",
srcs: ["Test.java"],
system_modules: "none",
sdk_version: "none",
compile_dex: true,
}
java_sdk_library {
name: "mysdklibrary",
srcs: ["a.java"],
compile_dex: true,
public: {enabled: true},
system: {enabled: true},
}
java_sdk_library {
name: "mycoreplatform",
srcs: ["a.java"],
compile_dex: true,
public: {enabled: true},
}
`)
fragment := result.Module("myfragment", "android_common")
info := result.ModuleProvider(fragment, bootclasspathApiInfoProvider).(bootclasspathApiInfo)
stubsJar := "out/soong/.intermediates/mystublib/android_common/dex/mystublib.jar"
// Check that SdkPublic uses public stubs.
publicStubsJar := "out/soong/.intermediates/mysdklibrary.stubs/android_common/dex/mysdklibrary.stubs.jar"
android.AssertPathsRelativeToTopEquals(t, "public dex stubs jar", []string{stubsJar, publicStubsJar}, info.stubJarsByKind[android.SdkPublic])
// Check that SdkSystem uses system stubs.
systemStubsJar := "out/soong/.intermediates/mysdklibrary.stubs.system/android_common/dex/mysdklibrary.stubs.system.jar"
android.AssertPathsRelativeToTopEquals(t, "system dex stubs jar", []string{stubsJar, systemStubsJar}, info.stubJarsByKind[android.SdkSystem])
// Check that SdkTest also uses system stubs as the mysdklibrary does not provide test stubs.
android.AssertPathsRelativeToTopEquals(t, "test dex stubs jar", []string{stubsJar, systemStubsJar}, info.stubJarsByKind[android.SdkTest])
// Check that SdkCorePlatform uses public stubs from the mycoreplatform library.
corePlatformStubsJar := "out/soong/.intermediates/mycoreplatform.stubs/android_common/dex/mycoreplatform.stubs.jar"
android.AssertPathsRelativeToTopEquals(t, "core platform dex stubs jar", []string{corePlatformStubsJar}, info.stubJarsByKind[android.SdkCorePlatform])
}

View File

@ -127,7 +127,7 @@ func hiddenAPIGatherStubLibDexJarPaths(ctx android.ModuleContext) map[android.Sd
tag := ctx.OtherModuleDependencyTag(module)
if hiddenAPIStubsTag, ok := tag.(hiddenAPIStubsDependencyTag); ok {
kind := hiddenAPIStubsTag.sdkKind
dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module)
dexJar := hiddenAPIRetrieveDexJarBuildPath(ctx, module, kind)
if dexJar != nil {
m[kind] = append(m[kind], dexJar)
}
@ -138,17 +138,21 @@ func hiddenAPIGatherStubLibDexJarPaths(ctx android.ModuleContext) map[android.Sd
// hiddenAPIRetrieveDexJarBuildPath retrieves the DexJarBuildPath from the specified module, if
// available, or reports an error.
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module) android.Path {
if j, ok := module.(UsesLibraryDependency); ok {
dexJar := j.DexJarBuildPath()
if dexJar != nil {
return dexJar
}
ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
func hiddenAPIRetrieveDexJarBuildPath(ctx android.ModuleContext, module android.Module, kind android.SdkKind) android.Path {
var dexJar android.Path
if sdkLibrary, ok := module.(SdkLibraryDependency); ok {
dexJar = sdkLibrary.SdkApiStubDexJar(ctx, kind)
} else if j, ok := module.(UsesLibraryDependency); ok {
dexJar = j.DexJarBuildPath()
} else {
ctx.ModuleErrorf("dependency %s of module type %s does not support providing a dex jar", module, ctx.OtherModuleType(module))
return nil
}
return nil
if dexJar == nil {
ctx.ModuleErrorf("dependency %s does not provide a dex jar, consider setting compile_dex: true", module)
}
return dexJar
}
var sdkKindToHiddenapiListOption = map[android.SdkKind]string{