blob: 38ce98525a135a0df3d3a4fac181ae5cd999c9b9 [file] [log] [blame]
Paul Duffinbb7f1ac2021-03-29 22:18:45 +01001// Copyright 2021 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
Paul Duffin6a766452021-04-12 14:15:22 +010018 "fmt"
19
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010020 "android/soong/android"
21 "android/soong/dexpreopt"
22)
23
24func init() {
25 registerPlatformBootclasspathBuildComponents(android.InitRegistrationContext)
26}
27
28func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
29 ctx.RegisterModuleType("platform_bootclasspath", platformBootclasspathFactory)
Paul Duffinb432df92021-03-22 22:09:42 +000030
31 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
32 ctx.BottomUp("platform_bootclasspath_deps", platformBootclasspathDepsMutator)
33 })
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010034}
35
Paul Duffinb432df92021-03-22 22:09:42 +000036// The tag used for the dependency between the platform bootclasspath and any configured boot jars.
Paul Duffinb67d8782021-04-22 11:49:41 +010037var platformBootclasspathModuleDepTag = bootclasspathDependencyTag{name: "module"}
Paul Duffinb432df92021-03-22 22:09:42 +000038
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010039type platformBootclasspathModule struct {
40 android.ModuleBase
Artur Satayev97259dc2021-04-07 15:17:14 +010041 ClasspathFragmentBase
Paul Duffinb432df92021-03-22 22:09:42 +000042
Paul Duffin62d8c3b2021-04-07 20:35:11 +010043 properties platformBootclasspathProperties
44
Paul Duffinb432df92021-03-22 22:09:42 +000045 // The apex:module pairs obtained from the configured modules.
46 //
47 // Currently only for testing.
48 configuredModules []android.Module
Paul Duffin62d8c3b2021-04-07 20:35:11 +010049
50 // The apex:module pairs obtained from the fragments.
51 //
52 // Currently only for testing.
53 fragments []android.Module
Paul Duffin6a766452021-04-12 14:15:22 +010054
55 // Path to the monolithic hiddenapi-flags.csv file.
Paul Duffin0b659862021-04-13 13:02:29 +010056 hiddenAPIFlagsCSV android.OutputPath
Paul Duffin6a766452021-04-12 14:15:22 +010057
58 // Path to the monolithic hiddenapi-index.csv file.
Paul Duffin0b659862021-04-13 13:02:29 +010059 hiddenAPIIndexCSV android.OutputPath
Paul Duffin6a766452021-04-12 14:15:22 +010060
61 // Path to the monolithic hiddenapi-unsupported.csv file.
Paul Duffin0b659862021-04-13 13:02:29 +010062 hiddenAPIMetadataCSV android.OutputPath
Paul Duffin62d8c3b2021-04-07 20:35:11 +010063}
64
Paul Duffin62d8c3b2021-04-07 20:35:11 +010065type platformBootclasspathProperties struct {
Paul Duffinb67d8782021-04-22 11:49:41 +010066 BootclasspathFragmentsDepsProperties
Paul Duffin702210b2021-04-08 20:12:41 +010067
Paul Duffin46169772021-04-14 15:01:56 +010068 Hidden_api HiddenAPIFlagFileProperties
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010069}
70
71func platformBootclasspathFactory() android.Module {
72 m := &platformBootclasspathModule{}
Paul Duffin62d8c3b2021-04-07 20:35:11 +010073 m.AddProperties(&m.properties)
Artur Satayev97259dc2021-04-07 15:17:14 +010074 // TODO(satayev): split systemserver and apex jars into separate configs.
75 initClasspathFragment(m)
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010076 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
77 return m
78}
79
Paul Duffin6a766452021-04-12 14:15:22 +010080var _ android.OutputFileProducer = (*platformBootclasspathModule)(nil)
81
Artur Satayev97259dc2021-04-07 15:17:14 +010082func (b *platformBootclasspathModule) AndroidMkEntries() (entries []android.AndroidMkEntries) {
83 entries = append(entries, android.AndroidMkEntries{
84 Class: "FAKE",
85 // Need at least one output file in order for this to take effect.
86 OutputFile: android.OptionalPathForPath(b.hiddenAPIFlagsCSV),
87 Include: "$(BUILD_PHONY_PACKAGE)",
88 })
89 entries = append(entries, b.classpathFragmentBase().getAndroidMkEntries()...)
90 return
Paul Duffin6a766452021-04-12 14:15:22 +010091}
92
93// Make the hidden API files available from the platform-bootclasspath module.
94func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, error) {
95 switch tag {
96 case "hiddenapi-flags.csv":
97 return android.Paths{b.hiddenAPIFlagsCSV}, nil
98 case "hiddenapi-index.csv":
99 return android.Paths{b.hiddenAPIIndexCSV}, nil
100 case "hiddenapi-metadata.csv":
101 return android.Paths{b.hiddenAPIMetadataCSV}, nil
102 }
103
104 return nil, fmt.Errorf("unknown tag %s", tag)
105}
106
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100107func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
Paul Duffin74431d52021-04-21 14:10:42 +0100108 b.hiddenAPIDepsMutator(ctx)
109
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100110 if SkipDexpreoptBootJars(ctx) {
111 return
112 }
113
114 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
115 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
116 dexpreopt.RegisterToolDeps(ctx)
117}
118
Paul Duffin74431d52021-04-21 14:10:42 +0100119func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpMutatorContext) {
120 if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
121 return
122 }
123
124 // Add dependencies onto the stub lib modules.
125 sdkKindToStubLibModules := hiddenAPIComputeMonolithicStubLibModules(ctx.Config())
126 hiddenAPIAddStubLibDependencies(ctx, sdkKindToStubLibModules)
127}
128
Paul Duffinb432df92021-03-22 22:09:42 +0000129func platformBootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
130 m := ctx.Module()
131 if p, ok := m.(*platformBootclasspathModule); ok {
132 // Add dependencies on all the modules configured in the "art" boot image.
133 artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
134 addDependenciesOntoBootImageModules(ctx, artImageConfig.modules)
135
136 // Add dependencies on all the modules configured in the "boot" boot image. That does not
137 // include modules configured in the "art" boot image.
138 bootImageConfig := p.getImageConfig(ctx)
139 addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules)
140
141 // Add dependencies on all the updatable modules.
142 updatableModules := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
143 addDependenciesOntoBootImageModules(ctx, updatableModules)
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100144
145 // Add dependencies on all the fragments.
Paul Duffinb67d8782021-04-22 11:49:41 +0100146 p.properties.BootclasspathFragmentsDepsProperties.addDependenciesOntoFragments(ctx)
Paul Duffinb432df92021-03-22 22:09:42 +0000147 }
148}
149
150func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList) {
151 for i := 0; i < modules.Len(); i++ {
152 apex := modules.Apex(i)
153 name := modules.Jar(i)
154
155 addDependencyOntoApexModulePair(ctx, apex, name, platformBootclasspathModuleDepTag)
156 }
157}
158
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100159func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Artur Satayev97259dc2021-04-07 15:17:14 +0100160 b.classpathFragmentBase().generateAndroidBuildActions(ctx)
161
Paul Duffinb432df92021-03-22 22:09:42 +0000162 ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
163 tag := ctx.OtherModuleDependencyTag(module)
164 if tag == platformBootclasspathModuleDepTag {
165 b.configuredModules = append(b.configuredModules, module)
Paul Duffinb67d8782021-04-22 11:49:41 +0100166 } else if tag == bootclasspathFragmentDepTag {
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100167 b.fragments = append(b.fragments, module)
Paul Duffinb432df92021-03-22 22:09:42 +0000168 }
169 })
170
Paul Duffin9b381ef2021-04-08 23:01:37 +0100171 b.generateHiddenAPIBuildActions(ctx, b.configuredModules, b.fragments)
Paul Duffin702210b2021-04-08 20:12:41 +0100172
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100173 // Nothing to do if skipping the dexpreopt of boot image jars.
174 if SkipDexpreoptBootJars(ctx) {
175 return
176 }
177
178 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
179 // GenerateSingletonBuildActions method as it cannot create it for itself.
180 dexpreopt.GetGlobalSoongConfig(ctx)
181
182 imageConfig := b.getImageConfig(ctx)
183 if imageConfig == nil {
184 return
185 }
186
187 // Construct the boot image info from the config.
188 info := BootImageInfo{imageConfig: imageConfig}
189
190 // Make it available for other modules.
191 ctx.SetProvider(BootImageInfoProvider, info)
192}
193
194func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
195 return defaultBootImageConfig(ctx)
196}
Paul Duffin702210b2021-04-08 20:12:41 +0100197
198// generateHiddenAPIBuildActions generates all the hidden API related build rules.
Paul Duffin9b381ef2021-04-08 23:01:37 +0100199func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module, fragments []android.Module) {
Paul Duffin702210b2021-04-08 20:12:41 +0100200
Paul Duffin90b8ad32021-04-13 12:25:01 +0100201 // Save the paths to the monolithic files for retrieval via OutputFiles().
202 b.hiddenAPIFlagsCSV = hiddenAPISingletonPaths(ctx).flags
203 b.hiddenAPIIndexCSV = hiddenAPISingletonPaths(ctx).index
204 b.hiddenAPIMetadataCSV = hiddenAPISingletonPaths(ctx).metadata
Paul Duffin6a766452021-04-12 14:15:22 +0100205
Paul Duffin0b659862021-04-13 13:02:29 +0100206 // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true. This is a performance
207 // optimization that can be used to reduce the incremental build time but as its name suggests it
208 // can be unsafe to use, e.g. when the changes affect anything that goes on the bootclasspath.
209 if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
210 paths := android.OutputPaths{b.hiddenAPIFlagsCSV, b.hiddenAPIIndexCSV, b.hiddenAPIMetadataCSV}
211 for _, path := range paths {
212 ctx.Build(pctx, android.BuildParams{
213 Rule: android.Touch,
214 Output: path,
215 })
216 }
217 return
218 }
219
Paul Duffin1ba24672021-04-12 23:26:14 +0100220 hiddenAPISupportingModules := []hiddenAPISupportingModule{}
Paul Duffin702210b2021-04-08 20:12:41 +0100221 for _, module := range modules {
Paul Duffin1ba24672021-04-12 23:26:14 +0100222 if h, ok := module.(hiddenAPISupportingModule); ok {
223 if h.bootDexJar() == nil {
224 ctx.ModuleErrorf("module %s does not provide a bootDexJar file", module)
Paul Duffin702210b2021-04-08 20:12:41 +0100225 }
Paul Duffin1ba24672021-04-12 23:26:14 +0100226 if h.flagsCSV() == nil {
227 ctx.ModuleErrorf("module %s does not provide a flagsCSV file", module)
228 }
229 if h.indexCSV() == nil {
230 ctx.ModuleErrorf("module %s does not provide an indexCSV file", module)
231 }
232 if h.metadataCSV() == nil {
233 ctx.ModuleErrorf("module %s does not provide a metadataCSV file", module)
234 }
235
236 if ctx.Failed() {
237 continue
238 }
239
240 hiddenAPISupportingModules = append(hiddenAPISupportingModules, h)
Paul Duffin702210b2021-04-08 20:12:41 +0100241 } else {
Paul Duffin1ba24672021-04-12 23:26:14 +0100242 ctx.ModuleErrorf("module %s of type %s does not support hidden API processing", module, ctx.OtherModuleType(module))
Paul Duffin702210b2021-04-08 20:12:41 +0100243 }
244 }
245
Paul Duffin1ba24672021-04-12 23:26:14 +0100246 moduleSpecificFlagsPaths := android.Paths{}
247 for _, module := range hiddenAPISupportingModules {
248 moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, module.flagsCSV())
249 }
250
Paul Duffin9b381ef2021-04-08 23:01:37 +0100251 flagFileInfo := b.properties.Hidden_api.hiddenAPIFlagFileInfo(ctx)
252 for _, fragment := range fragments {
253 if ctx.OtherModuleHasProvider(fragment, hiddenAPIFlagFileInfoProvider) {
254 info := ctx.OtherModuleProvider(fragment, hiddenAPIFlagFileInfoProvider).(hiddenAPIFlagFileInfo)
255 flagFileInfo.append(info)
256 }
257 }
258
259 // Store the information for testing.
260 ctx.SetProvider(hiddenAPIFlagFileInfoProvider, flagFileInfo)
Paul Duffin702210b2021-04-08 20:12:41 +0100261
262 outputPath := hiddenAPISingletonPaths(ctx).flags
263 baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
Paul Duffin9b381ef2021-04-08 23:01:37 +0100264 ruleToGenerateHiddenApiFlags(ctx, outputPath, baseFlagsPath, moduleSpecificFlagsPaths, flagFileInfo)
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100265
Paul Duffin74431d52021-04-21 14:10:42 +0100266 b.generateHiddenAPIStubFlagsRules(ctx, hiddenAPISupportingModules)
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100267 b.generateHiddenAPIIndexRules(ctx, hiddenAPISupportingModules)
Paul Duffin85dee5d2021-04-13 00:14:38 +0100268 b.generatedHiddenAPIMetadataRules(ctx, hiddenAPISupportingModules)
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100269}
270
Paul Duffin74431d52021-04-21 14:10:42 +0100271func (b *platformBootclasspathModule) generateHiddenAPIStubFlagsRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
272 bootDexJars := android.Paths{}
273 for _, module := range modules {
274 bootDexJars = append(bootDexJars, module.bootDexJar())
275 }
276
277 sdkKindToStubPaths := hiddenAPIGatherStubLibDexJarPaths(ctx)
278
279 outputPath := hiddenAPISingletonPaths(ctx).stubFlags
280 rule := ruleToGenerateHiddenAPIStubFlagsFile(ctx, outputPath, bootDexJars, sdkKindToStubPaths)
281 rule.Build("platform-bootclasspath-monolithic-hiddenapi-stub-flags", "monolithic hidden API stub flags")
282}
283
Paul Duffin00b2bfd2021-04-12 17:24:36 +0100284func (b *platformBootclasspathModule) generateHiddenAPIIndexRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
285 indexes := android.Paths{}
286 for _, module := range modules {
287 indexes = append(indexes, module.indexCSV())
288 }
289
290 rule := android.NewRuleBuilder(pctx, ctx)
291 rule.Command().
292 BuiltTool("merge_csv").
293 Flag("--key_field signature").
294 FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
295 FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
296 Inputs(indexes)
297 rule.Build("platform-bootclasspath-monolithic-hiddenapi-index", "monolithic hidden API index")
Paul Duffin702210b2021-04-08 20:12:41 +0100298}
Paul Duffin85dee5d2021-04-13 00:14:38 +0100299
300func (b *platformBootclasspathModule) generatedHiddenAPIMetadataRules(ctx android.ModuleContext, modules []hiddenAPISupportingModule) {
301 metadataCSVFiles := android.Paths{}
302 for _, module := range modules {
303 metadataCSVFiles = append(metadataCSVFiles, module.metadataCSV())
304 }
305
306 rule := android.NewRuleBuilder(pctx, ctx)
307
308 outputPath := hiddenAPISingletonPaths(ctx).metadata
309
310 rule.Command().
311 BuiltTool("merge_csv").
312 Flag("--key_field signature").
313 FlagWithOutput("--output=", outputPath).
314 Inputs(metadataCSVFiles)
315
316 rule.Build("platform-bootclasspath-monolithic-hiddenapi-metadata", "monolithic hidden API metadata")
317}