Merge "Combine hidden API encoding with flag generation"
This commit is contained in:
@@ -6564,6 +6564,7 @@ func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer androi
|
|||||||
"com.android.art.debug",
|
"com.android.art.debug",
|
||||||
],
|
],
|
||||||
hostdex: true,
|
hostdex: true,
|
||||||
|
compile_dex: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
apex {
|
apex {
|
||||||
|
@@ -82,6 +82,7 @@ func TestBootclasspathFragments(t *testing.T) {
|
|||||||
"com.android.art",
|
"com.android.art",
|
||||||
],
|
],
|
||||||
srcs: ["b.java"],
|
srcs: ["b.java"],
|
||||||
|
compile_dex: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
java_library {
|
java_library {
|
||||||
@@ -90,6 +91,7 @@ func TestBootclasspathFragments(t *testing.T) {
|
|||||||
"com.android.art",
|
"com.android.art",
|
||||||
],
|
],
|
||||||
srcs: ["b.java"],
|
srcs: ["b.java"],
|
||||||
|
compile_dex: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
bootclasspath_fragment {
|
bootclasspath_fragment {
|
||||||
@@ -318,6 +320,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
|||||||
apex_available: [
|
apex_available: [
|
||||||
"com.android.art",
|
"com.android.art",
|
||||||
],
|
],
|
||||||
|
compile_dex: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_import {
|
||||||
@@ -326,6 +329,7 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) {
|
|||||||
apex_available: [
|
apex_available: [
|
||||||
"com.android.art",
|
"com.android.art",
|
||||||
],
|
],
|
||||||
|
compile_dex: true,
|
||||||
}
|
}
|
||||||
`),
|
`),
|
||||||
)
|
)
|
||||||
@@ -489,7 +493,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
src: "com.android.art-arm.apex",
|
src: "com.android.art-arm.apex",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
exported_java_libs: ["foo", "bar"],
|
exported_bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
}
|
}
|
||||||
|
|
||||||
java_import {
|
java_import {
|
||||||
@@ -521,8 +525,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) {
|
|||||||
|
|
||||||
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
|
java.CheckModuleDependencies(t, result.TestContext, "com.android.art", "android_common_com.android.art", []string{
|
||||||
`com.android.art.apex.selector`,
|
`com.android.art.apex.selector`,
|
||||||
`prebuilt_bar`,
|
`prebuilt_mybootclasspathfragment`,
|
||||||
`prebuilt_foo`,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common", []string{
|
java.CheckModuleDependencies(t, result.TestContext, "mybootclasspathfragment", "android_common", []string{
|
||||||
|
@@ -137,10 +137,13 @@ type BootclasspathFragmentModule struct {
|
|||||||
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
|
// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
|
||||||
// bootclasspath fragment modules.
|
// bootclasspath fragment modules.
|
||||||
type commonBootclasspathFragment interface {
|
type commonBootclasspathFragment interface {
|
||||||
// produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
|
// produceHiddenAPIOutput produces the all-flags.csv and intermediate files and encodes the flags
|
||||||
|
// into dex files.
|
||||||
//
|
//
|
||||||
// Updates the supplied hiddenAPIInfo with the paths to the generated files set.
|
// Returns a *HiddenAPIOutput containing the paths for the generated files. Returns nil if the
|
||||||
produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput
|
// module cannot contribute to hidden API processing, e.g. because it is a prebuilt module in a
|
||||||
|
// versioned sdk.
|
||||||
|
produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
|
var _ commonBootclasspathFragment = (*BootclasspathFragmentModule)(nil)
|
||||||
@@ -292,9 +295,9 @@ type BootclasspathFragmentApexContentInfo struct {
|
|||||||
// Map from arch type to the boot image files.
|
// Map from arch type to the boot image files.
|
||||||
bootImageFilesByArch map[android.ArchType]android.OutputPaths
|
bootImageFilesByArch map[android.ArchType]android.OutputPaths
|
||||||
|
|
||||||
// Map from the name of the context module (as returned by Name()) to the hidden API encoded dex
|
// Map from the base module name (without prebuilt_ prefix) of a fragment's contents module to the
|
||||||
// jar path.
|
// hidden API encoded dex jar path.
|
||||||
contentModuleDexJarPaths map[string]android.Path
|
contentModuleDexJarPaths bootDexJarByModule
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
|
func (i BootclasspathFragmentApexContentInfo) Modules() android.ConfiguredJarList {
|
||||||
@@ -312,6 +315,8 @@ func (i BootclasspathFragmentApexContentInfo) AndroidBootImageFilesByArchType()
|
|||||||
//
|
//
|
||||||
// The dex boot jar is one which has had hidden API encoding performed on it.
|
// The dex boot jar is one which has had hidden API encoding performed on it.
|
||||||
func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) {
|
func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(module android.Module) (android.Path, error) {
|
||||||
|
// A bootclasspath_fragment cannot use a prebuilt library so Name() will return the base name
|
||||||
|
// without a prebuilt_ prefix so is safe to use as the key for the contentModuleDexJarPaths.
|
||||||
name := module.Name()
|
name := module.Name()
|
||||||
if dexJar, ok := i.contentModuleDexJarPaths[name]; ok {
|
if dexJar, ok := i.contentModuleDexJarPaths[name]; ok {
|
||||||
return dexJar, nil
|
return dexJar, nil
|
||||||
@@ -400,28 +405,34 @@ func (b *BootclasspathFragmentModule) GenerateAndroidBuildActions(ctx android.Mo
|
|||||||
|
|
||||||
fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
|
fragments := gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
|
||||||
|
|
||||||
// Perform hidden API processing.
|
|
||||||
hiddenAPIFlagOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
|
|
||||||
|
|
||||||
// Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
|
// Verify that the image_name specified on a bootclasspath_fragment is valid even if this is a
|
||||||
// prebuilt which will not use the image config.
|
// prebuilt which will not use the image config.
|
||||||
imageConfig := b.getImageConfig(ctx)
|
imageConfig := b.getImageConfig(ctx)
|
||||||
|
|
||||||
// A prebuilt fragment cannot contribute to the apex.
|
// A versioned prebuilt_bootclasspath_fragment cannot and does not need to perform hidden API
|
||||||
if !android.IsModulePrebuilt(ctx.Module()) {
|
// processing. It cannot do it because it is not part of a prebuilt_apex and so has no access to
|
||||||
// Provide the apex content info.
|
// the correct dex implementation jar. It does not need to because the platform-bootclasspath
|
||||||
b.provideApexContentInfo(ctx, imageConfig, contents, hiddenAPIFlagOutput)
|
// always references the latest bootclasspath_fragments.
|
||||||
|
if !android.IsModuleInVersionedSdk(ctx.Module()) {
|
||||||
|
// Perform hidden API processing.
|
||||||
|
hiddenAPIOutput := b.generateHiddenAPIBuildActions(ctx, contents, fragments)
|
||||||
|
|
||||||
|
// A prebuilt fragment cannot contribute to an apex.
|
||||||
|
if !android.IsModulePrebuilt(ctx.Module()) {
|
||||||
|
// Provide the apex content info.
|
||||||
|
b.provideApexContentInfo(ctx, imageConfig, contents, hiddenAPIOutput)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
|
// provideApexContentInfo creates, initializes and stores the apex content info for use by other
|
||||||
// modules.
|
// modules.
|
||||||
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
|
func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleContext, imageConfig *bootImageConfig, contents []android.Module, hiddenAPIOutput *HiddenAPIOutput) {
|
||||||
// Construct the apex content info from the config.
|
// Construct the apex content info from the config.
|
||||||
info := BootclasspathFragmentApexContentInfo{}
|
info := BootclasspathFragmentApexContentInfo{
|
||||||
|
// Populate the apex content info with paths to the dex jars.
|
||||||
// Populate the apex content info with paths to the dex jars.
|
contentModuleDexJarPaths: hiddenAPIOutput.EncodedBootDexFilesByModule,
|
||||||
b.populateApexContentInfoDexJars(ctx, &info, contents, hiddenAPIFlagOutput)
|
}
|
||||||
|
|
||||||
if imageConfig != nil {
|
if imageConfig != nil {
|
||||||
info.modules = imageConfig.modules
|
info.modules = imageConfig.modules
|
||||||
@@ -451,38 +462,6 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC
|
|||||||
ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
|
ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
// populateApexContentInfoDexJars adds paths to the dex jars provided by this fragment to the
|
|
||||||
// apex content info.
|
|
||||||
func (b *BootclasspathFragmentModule) populateApexContentInfoDexJars(ctx android.ModuleContext, info *BootclasspathFragmentApexContentInfo, contents []android.Module, hiddenAPIFlagOutput *HiddenAPIFlagOutput) {
|
|
||||||
|
|
||||||
info.contentModuleDexJarPaths = map[string]android.Path{}
|
|
||||||
if hiddenAPIFlagOutput != nil {
|
|
||||||
// Hidden API encoding has been performed.
|
|
||||||
flags := hiddenAPIFlagOutput.AllFlagsPath
|
|
||||||
for _, m := range contents {
|
|
||||||
h := m.(hiddenAPIModule)
|
|
||||||
unencodedDex := h.bootDexJar()
|
|
||||||
if unencodedDex == nil {
|
|
||||||
// This is an error. Sometimes Soong will report the error directly, other times it will
|
|
||||||
// defer the error reporting to happen only when trying to use the missing file in ninja.
|
|
||||||
// Either way it is handled by extractBootDexJarsFromModules which must have been
|
|
||||||
// called before this as it generates the flags that are used to encode these files.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
|
|
||||||
encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, flags, *h.uncompressDex(), outputDir)
|
|
||||||
info.contentModuleDexJarPaths[m.Name()] = encodedDex
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, m := range contents {
|
|
||||||
j := m.(UsesLibraryDependency)
|
|
||||||
dexJar := j.DexJarBuildPath()
|
|
||||||
info.contentModuleDexJarPaths[m.Name()] = dexJar
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
|
// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
|
||||||
func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
|
func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
|
||||||
var classpathJars []classpathJar
|
var classpathJars []classpathJar
|
||||||
@@ -548,12 +527,12 @@ func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
|
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
|
||||||
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIFlagOutput {
|
func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) *HiddenAPIOutput {
|
||||||
|
|
||||||
// Create hidden API input structure.
|
// Create hidden API input structure.
|
||||||
input := b.createHiddenAPIFlagInput(ctx, contents, fragments)
|
input := b.createHiddenAPIFlagInput(ctx, contents, fragments)
|
||||||
|
|
||||||
var output *HiddenAPIFlagOutput
|
var output *HiddenAPIOutput
|
||||||
|
|
||||||
// Hidden API processing is conditional as a temporary workaround as not all
|
// Hidden API processing is conditional as a temporary workaround as not all
|
||||||
// bootclasspath_fragments provide the appropriate information needed for hidden API processing
|
// bootclasspath_fragments provide the appropriate information needed for hidden API processing
|
||||||
@@ -563,7 +542,14 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
|
|||||||
if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
|
if input.canPerformHiddenAPIProcessing(ctx, b.properties) {
|
||||||
// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
|
// Delegate the production of the hidden API all-flags.csv file to a module type specific method.
|
||||||
common := ctx.Module().(commonBootclasspathFragment)
|
common := ctx.Module().(commonBootclasspathFragment)
|
||||||
output = common.produceHiddenAPIAllFlagsFile(ctx, contents, input)
|
output = common.produceHiddenAPIOutput(ctx, contents, input)
|
||||||
|
} else {
|
||||||
|
// As hidden API processing cannot be performed fall back to trying to retrieve the legacy
|
||||||
|
// encoded boot dex files, i.e. those files encoded by the individual libraries and returned
|
||||||
|
// from the DexJarBuildPath() method.
|
||||||
|
output = &HiddenAPIOutput{
|
||||||
|
EncodedBootDexFilesByModule: retrieveLegacyEncodedBootDexFiles(ctx, contents),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a HiddenAPIInfo structure.
|
// Initialize a HiddenAPIInfo structure.
|
||||||
@@ -580,11 +566,9 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
|
|||||||
TransitiveStubDexJarsByKind: input.transitiveStubDexJarsByKind(),
|
TransitiveStubDexJarsByKind: input.transitiveStubDexJarsByKind(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if output != nil {
|
// The monolithic hidden API processing also needs access to all the output files produced by
|
||||||
// The monolithic hidden API processing also needs access to all the output files produced by
|
// hidden API processing of this fragment.
|
||||||
// hidden API processing of this fragment.
|
hiddenAPIInfo.HiddenAPIFlagOutput = (*output).HiddenAPIFlagOutput
|
||||||
hiddenAPIInfo.HiddenAPIFlagOutput = *output
|
|
||||||
}
|
|
||||||
|
|
||||||
// Provide it for use by other modules.
|
// Provide it for use by other modules.
|
||||||
ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)
|
ctx.SetProvider(HiddenAPIInfoProvider, hiddenAPIInfo)
|
||||||
@@ -592,6 +576,21 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.
|
|||||||
return output
|
return output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retrieveLegacyEncodedBootDexFiles attempts to retrieve the legacy encoded boot dex jar files.
|
||||||
|
func retrieveLegacyEncodedBootDexFiles(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
|
||||||
|
// If the current bootclasspath_fragment is the active module or a source module then retrieve the
|
||||||
|
// encoded dex files, otherwise return an empty map.
|
||||||
|
//
|
||||||
|
// An inactive (i.e. not preferred) bootclasspath_fragment needs to retrieve the encoded dex jars
|
||||||
|
// as they are still needed by an apex. An inactive prebuilt_bootclasspath_fragment does not need
|
||||||
|
// to do so and may not yet have access to dex boot jars from a prebuilt_apex/apex_set.
|
||||||
|
if isActiveModule(ctx.Module()) || !android.IsModulePrebuilt(ctx.Module()) {
|
||||||
|
return extractEncodedDexJarsFromModules(ctx, contents)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived
|
// createHiddenAPIFlagInput creates a HiddenAPIFlagInput struct and initializes it with information derived
|
||||||
// from the properties on this module and its dependencies.
|
// from the properties on this module and its dependencies.
|
||||||
func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) HiddenAPIFlagInput {
|
func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.ModuleContext, contents []android.Module, fragments []android.Module) HiddenAPIFlagInput {
|
||||||
@@ -615,12 +614,12 @@ func (b *BootclasspathFragmentModule) createHiddenAPIFlagInput(ctx android.Modul
|
|||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
|
// produceHiddenAPIOutput produces the hidden API all-flags.csv file (and supporting files)
|
||||||
// for the fragment.
|
// for the fragment as well as encoding the flags in the boot dex jars.
|
||||||
func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
|
func (b *BootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
|
||||||
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
|
// Generate the rules to create the hidden API flags and update the supplied hiddenAPIInfo with the
|
||||||
// paths to the created files.
|
// paths to the created files.
|
||||||
return hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, input)
|
return hiddenAPIRulesForBootclasspathFragment(ctx, contents, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
|
// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
|
||||||
@@ -836,9 +835,8 @@ func (module *prebuiltBootclasspathFragmentModule) Name() string {
|
|||||||
return module.prebuilt.Name(module.ModuleBase.Name())
|
return module.prebuilt.Name(module.ModuleBase.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
|
// produceHiddenAPIOutput returns a path to the prebuilt all-flags.csv or nil if none is specified.
|
||||||
// specified.
|
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
|
||||||
func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, _ HiddenAPIFlagInput) *HiddenAPIFlagOutput {
|
|
||||||
pathForOptionalSrc := func(src *string) android.Path {
|
pathForOptionalSrc := func(src *string) android.Path {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
|
// TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
|
||||||
@@ -847,12 +845,19 @@ func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(
|
|||||||
return android.PathForModuleSrc(ctx, *src)
|
return android.PathForModuleSrc(ctx, *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := HiddenAPIFlagOutput{
|
// Retrieve the dex files directly from the content modules. They in turn should retrieve the
|
||||||
StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags),
|
// encoded dex jars from the prebuilt .apex files.
|
||||||
AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags),
|
encodedBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, contents)
|
||||||
MetadataPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata),
|
|
||||||
IndexPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index),
|
output := HiddenAPIOutput{
|
||||||
AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags),
|
HiddenAPIFlagOutput: HiddenAPIFlagOutput{
|
||||||
|
StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags),
|
||||||
|
AnnotationFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags),
|
||||||
|
MetadataPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata),
|
||||||
|
IndexPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Index),
|
||||||
|
AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags),
|
||||||
|
},
|
||||||
|
EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &output
|
return &output
|
||||||
|
@@ -580,6 +580,23 @@ func (b bootDexJarByModule) addPath(module android.Module, path android.Path) {
|
|||||||
b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path
|
b[android.RemoveOptionalPrebuiltPrefix(module.Name())] = path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bootDexJars returns the boot dex jar paths sorted by their keys.
|
||||||
|
func (b bootDexJarByModule) bootDexJars() android.Paths {
|
||||||
|
paths := android.Paths{}
|
||||||
|
for _, k := range android.SortedStringKeys(b) {
|
||||||
|
paths = append(paths, b[k])
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiddenAPIOutput encapsulates the output from the hidden API processing.
|
||||||
|
type HiddenAPIOutput struct {
|
||||||
|
HiddenAPIFlagOutput
|
||||||
|
|
||||||
|
// The map from base module name to the path to the encoded boot dex file.
|
||||||
|
EncodedBootDexFilesByModule bootDexJarByModule
|
||||||
|
}
|
||||||
|
|
||||||
// pathForValidation creates a path of the same type as the supplied type but with a name of
|
// pathForValidation creates a path of the same type as the supplied type but with a name of
|
||||||
// <path>.valid.
|
// <path>.valid.
|
||||||
//
|
//
|
||||||
@@ -665,8 +682,8 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
|
|||||||
rule.Build(name, desc)
|
rule.Build(name, desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hiddenAPIGenerateAllFlagsForBootclasspathFragment will generate all the flags for a fragment
|
// hiddenAPIRulesForBootclasspathFragment will generate all the flags for a fragment of the
|
||||||
// of the bootclasspath.
|
// bootclasspath and then encode the flags into the boot dex files.
|
||||||
//
|
//
|
||||||
// It takes:
|
// It takes:
|
||||||
// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
|
// * Map from android.SdkKind to stub dex jar paths defining the API for that sdk kind.
|
||||||
@@ -679,15 +696,16 @@ func buildRuleToGenerateHiddenApiFlags(ctx android.BuilderContext, name, desc st
|
|||||||
// * metadata.csv
|
// * metadata.csv
|
||||||
// * index.csv
|
// * index.csv
|
||||||
// * all-flags.csv
|
// * all-flags.csv
|
||||||
func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIFlagOutput {
|
// * encoded boot dex files
|
||||||
|
func hiddenAPIRulesForBootclasspathFragment(ctx android.ModuleContext, contents []android.Module, input HiddenAPIFlagInput) *HiddenAPIOutput {
|
||||||
hiddenApiSubDir := "modular-hiddenapi"
|
hiddenApiSubDir := "modular-hiddenapi"
|
||||||
|
|
||||||
// Gather the dex files for the boot libraries provided by this fragment.
|
// Gather information about the boot dex files for the boot libraries provided by this fragment.
|
||||||
bootDexJars := extractBootDexJarsFromModules(ctx, contents)
|
bootDexInfoByModule := extractBootDexInfoFromModules(ctx, contents)
|
||||||
|
|
||||||
// Generate the stub-flags.csv.
|
// Generate the stub-flags.csv.
|
||||||
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
|
stubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "stub-flags.csv")
|
||||||
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexJars, input)
|
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlagsCSV, bootDexInfoByModule.bootDexJars(), input)
|
||||||
rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
|
rule.Build("modularHiddenAPIStubFlagsFile", "modular hiddenapi stub flags")
|
||||||
|
|
||||||
// Extract the classes jars from the contents.
|
// Extract the classes jars from the contents.
|
||||||
@@ -715,16 +733,29 @@ func hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx android.ModuleContext
|
|||||||
|
|
||||||
// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
|
// Generate the all-flags.csv which are the flags that will, in future, be encoded into the dex
|
||||||
// files.
|
// files.
|
||||||
outputPath := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
|
allFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "all-flags.csv")
|
||||||
buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", outputPath, stubFlagsCSV, annotationFlagsCSV, input.FlagFilesByCategory, nil, removedDexSignatures)
|
buildRuleToGenerateHiddenApiFlags(ctx, "modularHiddenApiAllFlags", "modular hiddenapi all flags", allFlagsCSV, stubFlagsCSV, annotationFlagsCSV, input.FlagFilesByCategory, nil, removedDexSignatures)
|
||||||
|
|
||||||
|
// Encode the flags into the boot dex files.
|
||||||
|
encodedBootDexJarsByModule := map[string]android.Path{}
|
||||||
|
outputDir := android.PathForModuleOut(ctx, "hiddenapi-modular/encoded").OutputPath
|
||||||
|
for _, name := range android.SortedStringKeys(bootDexInfoByModule) {
|
||||||
|
bootDexInfo := bootDexInfoByModule[name]
|
||||||
|
unencodedDex := bootDexInfo.path
|
||||||
|
encodedDex := hiddenAPIEncodeDex(ctx, unencodedDex, allFlagsCSV, bootDexInfo.uncompressDex, outputDir)
|
||||||
|
encodedBootDexJarsByModule[name] = encodedDex
|
||||||
|
}
|
||||||
|
|
||||||
// Store the paths in the info for use by other modules and sdk snapshot generation.
|
// Store the paths in the info for use by other modules and sdk snapshot generation.
|
||||||
output := HiddenAPIFlagOutput{
|
output := HiddenAPIOutput{
|
||||||
StubFlagsPath: stubFlagsCSV,
|
HiddenAPIFlagOutput: HiddenAPIFlagOutput{
|
||||||
AnnotationFlagsPath: annotationFlagsCSV,
|
StubFlagsPath: stubFlagsCSV,
|
||||||
MetadataPath: metadataCSV,
|
AnnotationFlagsPath: annotationFlagsCSV,
|
||||||
IndexPath: indexCSV,
|
MetadataPath: metadataCSV,
|
||||||
AllFlagsPath: outputPath,
|
IndexPath: indexCSV,
|
||||||
|
AllFlagsPath: allFlagsCSV,
|
||||||
|
},
|
||||||
|
EncodedBootDexFilesByModule: encodedBootDexJarsByModule,
|
||||||
}
|
}
|
||||||
return &output
|
return &output
|
||||||
}
|
}
|
||||||
@@ -747,37 +778,15 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, removedT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
|
// extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules.
|
||||||
func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) android.Paths {
|
func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
|
||||||
bootDexJars := android.Paths{}
|
bootDexJars := bootDexJarByModule{}
|
||||||
for _, module := range contents {
|
for _, module := range contents {
|
||||||
hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
|
hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module)
|
||||||
if hiddenAPIModule == nil {
|
if hiddenAPIModule == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
bootDexJar := hiddenAPIModule.bootDexJar()
|
bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
|
||||||
if bootDexJar == nil {
|
bootDexJars.addPath(module, bootDexJar)
|
||||||
if ctx.Config().AlwaysUsePrebuiltSdks() {
|
|
||||||
// TODO(b/179354495): Remove this workaround when it is unnecessary.
|
|
||||||
// Prebuilt modules like framework-wifi do not yet provide dex implementation jars. So,
|
|
||||||
// create a fake one that will cause a build error only if it is used.
|
|
||||||
fake := android.PathForModuleOut(ctx, "fake/boot-dex/%s.jar", module.Name())
|
|
||||||
|
|
||||||
// Create an error rule that pretends to create the output file but will actually fail if it
|
|
||||||
// is run.
|
|
||||||
ctx.Build(pctx, android.BuildParams{
|
|
||||||
Rule: android.ErrorRule,
|
|
||||||
Output: fake,
|
|
||||||
Args: map[string]string{
|
|
||||||
"error": fmt.Sprintf("missing dependencies: boot dex jar for %s", module),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
bootDexJars = append(bootDexJars, fake)
|
|
||||||
} else {
|
|
||||||
ctx.ModuleErrorf("module %s does not provide a dex jar", module)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bootDexJars = append(bootDexJars, bootDexJar)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return bootDexJars
|
return bootDexJars
|
||||||
}
|
}
|
||||||
@@ -794,6 +803,60 @@ func hiddenAPIModuleFromModule(ctx android.BaseModuleContext, module android.Mod
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bootDexInfo encapsulates both the path and uncompressDex status retrieved from a hiddenAPIModule.
|
||||||
|
type bootDexInfo struct {
|
||||||
|
// The path to the dex jar that has not had hidden API flags encoded into it.
|
||||||
|
path android.Path
|
||||||
|
|
||||||
|
// Indicates whether the dex jar needs uncompressing before encoding.
|
||||||
|
uncompressDex bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// bootDexInfoByModule is a map from module name (as returned by module.Name()) to the boot dex
|
||||||
|
// path (as returned by hiddenAPIModule.bootDexJar()) and the uncompressDex flag.
|
||||||
|
type bootDexInfoByModule map[string]bootDexInfo
|
||||||
|
|
||||||
|
// bootDexJars returns the boot dex jar paths sorted by their keys.
|
||||||
|
func (b bootDexInfoByModule) bootDexJars() android.Paths {
|
||||||
|
paths := android.Paths{}
|
||||||
|
for _, m := range android.SortedStringKeys(b) {
|
||||||
|
paths = append(paths, b[m].path)
|
||||||
|
}
|
||||||
|
return paths
|
||||||
|
}
|
||||||
|
|
||||||
|
// extractBootDexInfoFromModules extracts the boot dex jar and uncompress dex state from
|
||||||
|
// each of the supplied modules which must implement hiddenAPIModule.
|
||||||
|
func extractBootDexInfoFromModules(ctx android.ModuleContext, contents []android.Module) bootDexInfoByModule {
|
||||||
|
bootDexJarsByModule := bootDexInfoByModule{}
|
||||||
|
for _, module := range contents {
|
||||||
|
hiddenAPIModule := module.(hiddenAPIModule)
|
||||||
|
bootDexJar := retrieveBootDexJarFromHiddenAPIModule(ctx, hiddenAPIModule)
|
||||||
|
bootDexJarsByModule[module.Name()] = bootDexInfo{
|
||||||
|
path: bootDexJar,
|
||||||
|
uncompressDex: *hiddenAPIModule.uncompressDex(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bootDexJarsByModule
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieveBootDexJarFromHiddenAPIModule retrieves the boot dex jar from the hiddenAPIModule.
|
||||||
|
//
|
||||||
|
// If the module does not provide a boot dex jar, i.e. the returned boot dex jar is nil, then that
|
||||||
|
// create a fake path and either report an error immediately or defer reporting of the error until
|
||||||
|
// the path is actually used.
|
||||||
|
func retrieveBootDexJarFromHiddenAPIModule(ctx android.ModuleContext, module hiddenAPIModule) android.Path {
|
||||||
|
bootDexJar := module.bootDexJar()
|
||||||
|
if bootDexJar == nil {
|
||||||
|
fake := android.PathForModuleOut(ctx, fmt.Sprintf("fake/boot-dex/%s.jar", module.Name()))
|
||||||
|
bootDexJar = fake
|
||||||
|
|
||||||
|
handleMissingDexBootFile(ctx, module, fake)
|
||||||
|
}
|
||||||
|
return bootDexJar
|
||||||
|
}
|
||||||
|
|
||||||
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
|
// extractClassesJarsFromModules extracts the class jars from the supplied modules.
|
||||||
func extractClassesJarsFromModules(contents []android.Module) android.Paths {
|
func extractClassesJarsFromModules(contents []android.Module) android.Paths {
|
||||||
classesJars := android.Paths{}
|
classesJars := android.Paths{}
|
||||||
@@ -822,6 +885,11 @@ func deferReportingMissingBootDexJar(ctx android.ModuleContext, module android.M
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any missing dependency should be allowed.
|
||||||
|
if ctx.Config().AllowMissingDependencies() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// This is called for both platform_bootclasspath and bootclasspath_fragment modules.
|
// This is called for both platform_bootclasspath and bootclasspath_fragment modules.
|
||||||
//
|
//
|
||||||
// A bootclasspath_fragment module should only use the APEX variant of source or prebuilt modules.
|
// A bootclasspath_fragment module should only use the APEX variant of source or prebuilt modules.
|
||||||
|
@@ -291,9 +291,9 @@ func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.
|
|||||||
input.FlagFilesByCategory = monolithicInfo.FlagsFilesByCategory
|
input.FlagFilesByCategory = monolithicInfo.FlagsFilesByCategory
|
||||||
|
|
||||||
// Generate the monolithic stub-flags.csv file.
|
// Generate the monolithic stub-flags.csv file.
|
||||||
bootDexJars := extractBootDexJarsFromModules(ctx, modules)
|
bootDexJarByModule := extractBootDexJarsFromModules(ctx, modules)
|
||||||
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
|
stubFlags := hiddenAPISingletonPaths(ctx).stubFlags
|
||||||
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJars, input)
|
rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, stubFlags, bootDexJarByModule.bootDexJars(), input)
|
||||||
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
|
rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
|
||||||
|
|
||||||
// Extract the classes jars from the contents.
|
// Extract the classes jars from the contents.
|
||||||
|
Reference in New Issue
Block a user