Generate hidden API flags for a bootclasspath_fragment
This change adds support for generating the hidden API flags for the
contents of a bootclasspath_fragment. Currently, it will only work for
the art-bootclasspath-fragment as it has no support for creating
dependencies between bootclasspath_fragment modules which will be
needed for handling any other bootclasspath_fragment.
The hidden API flag generation added by this change is completely
separate to the normal hidden API processing and is not as yet encoded
in dex jars so will have no effect on the runtime.
The generated files are provided for use by other modules and copied
into the sdk snapshot. That is needed to allow the build to verify that
the hidden API flags generated by the individual bootclasspath_fragment
modules are consistent with the flags generated for the whole
bootclasspath, whether building from source or prebuilts.
Bug: 179354495
Test: m art-module-sdk
m out/soong/.intermediates/art/build/boot/art-bootclasspath-fragment/android_common_apex10000/modular-hiddenapi/all-flags.csv
m out/soong/hiddenapi/hiddenapi-flags.csv
- test that the former file is a subset of the latter and that
where they overlap they are identical.
Change-Id: Ie27303e2960953db1b7abe95510e3bca4411b09a
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index d8c5453..ec61e70 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -120,6 +120,15 @@
properties bootclasspathFragmentProperties
}
+// commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt
+// bootclasspath fragment modules.
+type commonBootclasspathFragment interface {
+ // produceHiddenAPIAllFlagsFile produces the all-flags.csv and intermediate files.
+ //
+ // Updates the supplied flagFileInfo with the paths to the generated files set.
+ produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo)
+}
+
func bootclasspathFragmentFactory() android.Module {
m := &BootclasspathFragmentModule{}
m.AddProperties(&m.properties)
@@ -381,7 +390,7 @@
})
// Perform hidden API processing.
- b.generateHiddenAPIBuildActions(ctx)
+ b.generateHiddenAPIBuildActions(ctx, contents)
// Construct the boot image info from the config.
info := BootclasspathFragmentApexContentInfo{
@@ -441,12 +450,7 @@
}
// generateHiddenAPIBuildActions generates all the hidden API related build rules.
-func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext) {
- // Resolve the properties to paths.
- flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
-
- // Store the information for use by platform_bootclasspath.
- ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
+func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, contents []android.Module) {
// Convert the kind specific lists of modules into kind specific lists of jars.
stubJarsByKind := hiddenAPIGatherStubLibDexJarPaths(ctx)
@@ -454,6 +458,33 @@
// Store the information for use by other modules.
bootclasspathApiInfo := bootclasspathApiInfo{stubJarsByKind: stubJarsByKind}
ctx.SetProvider(bootclasspathApiInfoProvider, bootclasspathApiInfo)
+
+ // Resolve the properties to paths.
+ flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
+
+ // Delegate the production of the hidden API all flags file to a module type specific method.
+ common := ctx.Module().(commonBootclasspathFragment)
+ common.produceHiddenAPIAllFlagsFile(ctx, contents, stubJarsByKind, &flagFileInfo)
+
+ // Store the information for use by platform_bootclasspath.
+ ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
+}
+
+// produceHiddenAPIAllFlagsFile produces the hidden API all-flags.csv file (and supporting files)
+// for the fragment.
+func (b *BootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, contents []android.Module, stubJarsByKind map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
+ // If no stubs have been provided then don't perform hidden API processing. This is a temporary
+ // workaround to avoid existing bootclasspath_fragments that do not provide stubs breaking the
+ // build.
+ // TODO(b/179354495): Remove this workaround.
+ if len(stubJarsByKind) == 0 {
+ // Nothing to do.
+ return
+ }
+
+ // Generate the rules to create the hidden API flags and update the supplied flagFileInfo with the
+ // paths to the created files.
+ hiddenAPIGenerateAllFlagsForBootclasspathFragment(ctx, contents, stubJarsByKind, flagFileInfo)
}
// generateBootImageBuildActions generates ninja rules to create the boot image if required for this
@@ -534,6 +565,32 @@
// Flag files by *hiddenAPIFlagFileCategory
Flag_files_by_category map[*hiddenAPIFlagFileCategory]android.Paths
+
+ // The path to the generated stub-flags.csv file.
+ Stub_flags_path android.OptionalPath
+
+ // The path to the generated annotation-flags.csv file.
+ Annotation_flags_path android.OptionalPath
+
+ // The path to the generated metadata.csv file.
+ Metadata_path android.OptionalPath
+
+ // The path to the generated index.csv file.
+ Index_path android.OptionalPath
+
+ // The path to the generated all-flags.csv file.
+ All_flags_path android.OptionalPath
+}
+
+func pathsToOptionalPath(paths android.Paths) android.OptionalPath {
+ switch len(paths) {
+ case 0:
+ return android.OptionalPath{}
+ case 1:
+ return android.OptionalPathForPath(paths[0])
+ default:
+ panic(fmt.Errorf("expected 0 or 1 paths, found %q", paths))
+ }
}
func (b *bootclasspathFragmentSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -547,6 +604,13 @@
flagFileInfo := mctx.OtherModuleProvider(module, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
b.Flag_files_by_category = flagFileInfo.categoryToPaths
+ // Copy all the generated file paths.
+ b.Stub_flags_path = pathsToOptionalPath(flagFileInfo.StubFlagsPaths)
+ b.Annotation_flags_path = pathsToOptionalPath(flagFileInfo.AnnotationFlagsPaths)
+ b.Metadata_path = pathsToOptionalPath(flagFileInfo.MetadataPaths)
+ b.Index_path = pathsToOptionalPath(flagFileInfo.IndexPaths)
+ b.All_flags_path = pathsToOptionalPath(flagFileInfo.AllFlagsPaths)
+
// Copy stub_libs properties.
b.Stub_libs = module.properties.Api.Stub_libs
b.Core_platform_stub_libs = module.properties.Core_platform_api.Stub_libs
@@ -573,14 +637,17 @@
corePlatformApiPropertySet.AddPropertyWithTag("stub_libs", b.Core_platform_stub_libs, requiredMemberDependency)
}
+ hiddenAPISet := propertySet.AddPropertySet("hidden_api")
+ hiddenAPIDir := "hiddenapi"
+
+ // Copy manually curated flag files specified on the bootclasspath_fragment.
if b.Flag_files_by_category != nil {
- hiddenAPISet := propertySet.AddPropertySet("hidden_api")
for _, category := range hiddenAPIFlagFileCategories {
paths := b.Flag_files_by_category[category]
if len(paths) > 0 {
dests := []string{}
for _, p := range paths {
- dest := filepath.Join("hiddenapi", p.Base())
+ dest := filepath.Join(hiddenAPIDir, p.Base())
builder.CopyToSnapshot(p, dest)
dests = append(dests, dest)
}
@@ -588,10 +655,47 @@
}
}
}
+
+ copyOptionalPath := func(path android.OptionalPath, property string) {
+ if path.Valid() {
+ p := path.Path()
+ dest := filepath.Join(hiddenAPIDir, p.Base())
+ builder.CopyToSnapshot(p, dest)
+ hiddenAPISet.AddProperty(property, dest)
+ }
+ }
+
+ // Copy all the generated files, if available.
+ copyOptionalPath(b.Stub_flags_path, "stub_flags")
+ copyOptionalPath(b.Annotation_flags_path, "annotation_flags")
+ copyOptionalPath(b.Metadata_path, "metadata")
+ copyOptionalPath(b.Index_path, "index")
+ copyOptionalPath(b.All_flags_path, "all_flags")
}
var _ android.SdkMemberType = (*bootclasspathFragmentMemberType)(nil)
+// prebuiltBootclasspathFragmentProperties contains additional prebuilt_bootclasspath_fragment
+// specific properties.
+type prebuiltBootclasspathFragmentProperties struct {
+ Hidden_api struct {
+ // The path to the stub-flags.csv file created by the bootclasspath_fragment.
+ Stub_flags *string `android:"path"`
+
+ // The path to the annotation-flags.csv file created by the bootclasspath_fragment.
+ Annotation_flags *string `android:"path"`
+
+ // The path to the metadata.csv file created by the bootclasspath_fragment.
+ Metadata *string `android:"path"`
+
+ // The path to the index.csv file created by the bootclasspath_fragment.
+ Index *string `android:"path"`
+
+ // The path to the all-flags.csv file created by the bootclasspath_fragment.
+ All_flags *string `android:"path"`
+ }
+}
+
// A prebuilt version of the bootclasspath_fragment module.
//
// At the moment this is basically just a bootclasspath_fragment module that can be used as a
@@ -600,6 +704,9 @@
type prebuiltBootclasspathFragmentModule struct {
BootclasspathFragmentModule
prebuilt android.Prebuilt
+
+ // Additional prebuilt specific properties.
+ prebuiltProperties prebuiltBootclasspathFragmentProperties
}
func (module *prebuiltBootclasspathFragmentModule) Prebuilt() *android.Prebuilt {
@@ -610,9 +717,29 @@
return module.prebuilt.Name(module.ModuleBase.Name())
}
+// produceHiddenAPIAllFlagsFile returns a path to the prebuilt all-flags.csv or nil if none is
+// specified.
+func (module *prebuiltBootclasspathFragmentModule) produceHiddenAPIAllFlagsFile(ctx android.ModuleContext, _ []android.Module, _ map[android.SdkKind]android.Paths, flagFileInfo *hiddenAPIFlagFileInfo) {
+ pathsForOptionalSrc := func(src *string) android.Paths {
+ if src == nil {
+ // TODO(b/179354495): Fail if this is not provided once prebuilts have been updated.
+ return nil
+ }
+ return android.Paths{android.PathForModuleSrc(ctx, *src)}
+ }
+
+ flagFileInfo.StubFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags)
+ flagFileInfo.AnnotationFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Annotation_flags)
+ flagFileInfo.MetadataPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Metadata)
+ flagFileInfo.IndexPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.Index)
+ flagFileInfo.AllFlagsPaths = pathsForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags)
+}
+
+var _ commonBootclasspathFragment = (*prebuiltBootclasspathFragmentModule)(nil)
+
func prebuiltBootclasspathFragmentFactory() android.Module {
m := &prebuiltBootclasspathFragmentModule{}
- m.AddProperties(&m.properties)
+ m.AddProperties(&m.properties, &m.prebuiltProperties)
// This doesn't actually have any prebuilt files of its own so pass a placeholder for the srcs
// array.
android.InitPrebuiltModule(m, &[]string{"placeholder"})