blob: e292d8057ec3ad103a815ff0757c758a29fd5a52 [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 (
18 "android/soong/android"
19 "android/soong/dexpreopt"
Paul Duffinb432df92021-03-22 22:09:42 +000020 "github.com/google/blueprint"
Paul Duffin62d8c3b2021-04-07 20:35:11 +010021 "github.com/google/blueprint/proptools"
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010022)
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 +000036type platformBootclasspathDependencyTag struct {
37 blueprint.BaseDependencyTag
38
39 name string
40}
41
42// Avoid having to make platform bootclasspath content visible to the platform bootclasspath.
43//
44// This is a temporary workaround to make it easier to migrate to platform bootclasspath with proper
45// dependencies.
46// TODO(b/177892522): Remove this and add needed visibility.
47func (t platformBootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
48}
49
50// The tag used for the dependency between the platform bootclasspath and any configured boot jars.
51var platformBootclasspathModuleDepTag = platformBootclasspathDependencyTag{name: "module"}
52
Paul Duffin62d8c3b2021-04-07 20:35:11 +010053// The tag used for the dependency between the platform bootclasspath and bootclasspath_fragments.
54var platformBootclasspathFragmentDepTag = platformBootclasspathDependencyTag{name: "fragment"}
55
Paul Duffinb432df92021-03-22 22:09:42 +000056var _ android.ExcludeFromVisibilityEnforcementTag = platformBootclasspathDependencyTag{}
57
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010058type platformBootclasspathModule struct {
59 android.ModuleBase
Paul Duffinb432df92021-03-22 22:09:42 +000060
Paul Duffin62d8c3b2021-04-07 20:35:11 +010061 properties platformBootclasspathProperties
62
Paul Duffinb432df92021-03-22 22:09:42 +000063 // The apex:module pairs obtained from the configured modules.
64 //
65 // Currently only for testing.
66 configuredModules []android.Module
Paul Duffin62d8c3b2021-04-07 20:35:11 +010067
68 // The apex:module pairs obtained from the fragments.
69 //
70 // Currently only for testing.
71 fragments []android.Module
72}
73
74// ApexVariantReference specifies a particular apex variant of a module.
75type ApexVariantReference struct {
76 // The name of the module apex variant, i.e. the apex containing the module variant.
77 //
78 // If this is not specified then it defaults to "platform" which will cause a dependency to be
79 // added to the module's platform variant.
80 Apex *string
81
82 // The name of the module.
83 Module *string
84}
85
86type platformBootclasspathProperties struct {
Paul Duffin62d8c3b2021-04-07 20:35:11 +010087 // The names of the bootclasspath_fragment modules that form part of this
88 // platform_bootclasspath.
89 Fragments []ApexVariantReference
Paul Duffin702210b2021-04-08 20:12:41 +010090
91 Hidden_api HiddenAPIAugmentationProperties
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010092}
93
94func platformBootclasspathFactory() android.Module {
95 m := &platformBootclasspathModule{}
Paul Duffin62d8c3b2021-04-07 20:35:11 +010096 m.AddProperties(&m.properties)
Paul Duffinbb7f1ac2021-03-29 22:18:45 +010097 android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
98 return m
99}
100
101func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
102 if SkipDexpreoptBootJars(ctx) {
103 return
104 }
105
106 // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
107 // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
108 dexpreopt.RegisterToolDeps(ctx)
109}
110
Paul Duffinb432df92021-03-22 22:09:42 +0000111func platformBootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
112 m := ctx.Module()
113 if p, ok := m.(*platformBootclasspathModule); ok {
114 // Add dependencies on all the modules configured in the "art" boot image.
115 artImageConfig := genBootImageConfigs(ctx)[artBootImageName]
116 addDependenciesOntoBootImageModules(ctx, artImageConfig.modules)
117
118 // Add dependencies on all the modules configured in the "boot" boot image. That does not
119 // include modules configured in the "art" boot image.
120 bootImageConfig := p.getImageConfig(ctx)
121 addDependenciesOntoBootImageModules(ctx, bootImageConfig.modules)
122
123 // Add dependencies on all the updatable modules.
124 updatableModules := dexpreopt.GetGlobalConfig(ctx).UpdatableBootJars
125 addDependenciesOntoBootImageModules(ctx, updatableModules)
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100126
127 // Add dependencies on all the fragments.
128 addDependencyOntoApexVariants(ctx, "fragments", p.properties.Fragments, platformBootclasspathFragmentDepTag)
129 }
130}
131
132func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
133 for i, ref := range refs {
134 apex := proptools.StringDefault(ref.Apex, "platform")
135
136 if ref.Module == nil {
137 ctx.PropertyErrorf(propertyName, "missing module name at position %d", i)
138 continue
139 }
140 name := proptools.String(ref.Module)
141
142 addDependencyOntoApexModulePair(ctx, apex, name, tag)
Paul Duffinb432df92021-03-22 22:09:42 +0000143 }
144}
145
146func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
147 var variations []blueprint.Variation
148 if apex != "platform" {
149 // Pick the correct apex variant.
150 variations = []blueprint.Variation{
151 {Mutator: "apex", Variation: apex},
152 }
153 }
154
155 addedDep := false
156 if ctx.OtherModuleDependencyVariantExists(variations, name) {
157 ctx.AddFarVariationDependencies(variations, tag, name)
158 addedDep = true
159 }
160
161 // Add a dependency on the prebuilt module if it exists.
162 prebuiltName := android.PrebuiltNameFromSource(name)
163 if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
164 ctx.AddVariationDependencies(variations, tag, prebuiltName)
165 addedDep = true
166 }
167
168 // If no appropriate variant existing for this, so no dependency could be added, then it is an
169 // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
170 // dependency that will not be satisfied and the default behavior will handle it.
171 if !addedDep {
172 ctx.AddFarVariationDependencies(variations, tag, name)
173 }
174}
175
176func addDependenciesOntoBootImageModules(ctx android.BottomUpMutatorContext, modules android.ConfiguredJarList) {
177 for i := 0; i < modules.Len(); i++ {
178 apex := modules.Apex(i)
179 name := modules.Jar(i)
180
181 addDependencyOntoApexModulePair(ctx, apex, name, platformBootclasspathModuleDepTag)
182 }
183}
184
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100185func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Paul Duffinb432df92021-03-22 22:09:42 +0000186 ctx.VisitDirectDepsIf(isActiveModule, func(module android.Module) {
187 tag := ctx.OtherModuleDependencyTag(module)
188 if tag == platformBootclasspathModuleDepTag {
189 b.configuredModules = append(b.configuredModules, module)
Paul Duffin62d8c3b2021-04-07 20:35:11 +0100190 } else if tag == platformBootclasspathFragmentDepTag {
191 b.fragments = append(b.fragments, module)
Paul Duffinb432df92021-03-22 22:09:42 +0000192 }
193 })
194
Paul Duffin702210b2021-04-08 20:12:41 +0100195 b.generateHiddenAPIBuildActions(ctx, b.configuredModules)
196
Paul Duffinbb7f1ac2021-03-29 22:18:45 +0100197 // Nothing to do if skipping the dexpreopt of boot image jars.
198 if SkipDexpreoptBootJars(ctx) {
199 return
200 }
201
202 // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
203 // GenerateSingletonBuildActions method as it cannot create it for itself.
204 dexpreopt.GetGlobalSoongConfig(ctx)
205
206 imageConfig := b.getImageConfig(ctx)
207 if imageConfig == nil {
208 return
209 }
210
211 // Construct the boot image info from the config.
212 info := BootImageInfo{imageConfig: imageConfig}
213
214 // Make it available for other modules.
215 ctx.SetProvider(BootImageInfoProvider, info)
216}
217
218func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
219 return defaultBootImageConfig(ctx)
220}
Paul Duffin702210b2021-04-08 20:12:41 +0100221
222// generateHiddenAPIBuildActions generates all the hidden API related build rules.
223func (b *platformBootclasspathModule) generateHiddenAPIBuildActions(ctx android.ModuleContext, modules []android.Module) {
224
225 moduleSpecificFlagsPaths := android.Paths{}
226 for _, module := range modules {
227 if h, ok := module.(hiddenAPIIntf); ok {
228 if csv := h.flagsCSV(); csv != nil {
229 moduleSpecificFlagsPaths = append(moduleSpecificFlagsPaths, csv)
230 }
231 } else {
232 ctx.ModuleErrorf("module %s of type %s does not implement hiddenAPIIntf", module, ctx.OtherModuleType(module))
233 }
234 }
235
236 augmentationInfo := b.properties.Hidden_api.hiddenAPIAugmentationInfo(ctx)
237
238 outputPath := hiddenAPISingletonPaths(ctx).flags
239 baseFlagsPath := hiddenAPISingletonPaths(ctx).stubFlags
240 ruleToGenerateHiddenApiFlags(ctx, outputPath, baseFlagsPath, moduleSpecificFlagsPaths, augmentationInfo)
241}