blob: 6c82d330cbdb44f182997fff04be0cbdad5c1512 [file] [log] [blame]
Paul Duffinb67d8782021-04-22 11:49:41 +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 (
Colin Crossd6495802025-01-14 15:50:48 -080018 "fmt"
19
Paul Duffinb67d8782021-04-22 11:49:41 +010020 "android/soong/android"
Paul Duffin81667c82021-04-26 13:55:36 +010021
Paul Duffinb67d8782021-04-22 11:49:41 +010022 "github.com/google/blueprint"
23 "github.com/google/blueprint/proptools"
24)
25
26// Contains code that is common to both platform_bootclasspath and bootclasspath_fragment.
27
Paul Duffinb67d8782021-04-22 11:49:41 +010028// addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of
29// the module as specified in the ApexVariantReference list.
Colin Crossd8d8b852024-12-20 16:32:37 -080030func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tagType bootclasspathDependencyTagType) {
Paul Duffinb67d8782021-04-22 11:49:41 +010031 for i, ref := range refs {
32 apex := proptools.StringDefault(ref.Apex, "platform")
33
34 if ref.Module == nil {
35 ctx.PropertyErrorf(propertyName, "missing module name at position %d", i)
36 continue
37 }
38 name := proptools.String(ref.Module)
39
Colin Crossd8d8b852024-12-20 16:32:37 -080040 addDependencyOntoApexModulePair(ctx, apex, name, tagType)
Paul Duffinb67d8782021-04-22 11:49:41 +010041 }
42}
43
44// addDependencyOntoApexModulePair adds a dependency onto the specified APEX specific variant or the
45// specified module.
46//
Paul Duffin110b0ad2021-04-27 14:36:08 +010047// If apex="platform" or "system_ext" then this adds a dependency onto the platform variant of the
48// module. This adds dependencies onto the prebuilt and source modules with the specified name,
49// depending on which ones are available. Visiting must use isActiveModule to select the preferred
50// module when both source and prebuilt modules are available.
Paul Duffin9bacf562021-04-28 21:16:02 +010051//
52// Use gatherApexModulePairDepsWithTag to retrieve the dependencies.
Colin Crossd8d8b852024-12-20 16:32:37 -080053func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tagType bootclasspathDependencyTagType) {
54 tag := bootclasspathDependencyTag{
55 typ: tagType,
56 }
Colin Crossd6495802025-01-14 15:50:48 -080057 target := ctx.Module().Target()
58 if android.IsConfiguredJarForPlatform(apex) {
59 // Platform variant, add a direct dependency.
60 ctx.AddFarVariationDependencies(target.Variations(), tag, name)
61 } else {
62 // A module in an apex. Dependencies can't be added directly onto an apex variation, as that would
63 // require constructing a full ApexInfo configuration, which can't be predicted here. Add a dependency
64 // on the apex instead, and annotate the dependency tag with the desired module in the apex.
65 tag.moduleInApex = name
66 ctx.AddFarVariationDependencies(target.Variations(), tag, apex)
Paul Duffinb67d8782021-04-22 11:49:41 +010067 }
68
Paul Duffinb67d8782021-04-22 11:49:41 +010069}
70
Colin Cross92b0eb12025-02-06 11:49:52 -080071// gatherFragments collects fragments that are direct dependencies of this module, as well as
72// any fragments in apexes via the dependency on the apex. It returns a list of the fragment
73// modules and map from apex name to the fragment in that apex.
Colin Cross38803c62025-04-16 14:14:55 -070074func gatherFragments(ctx android.BaseModuleContext) ([]android.ModuleProxy, map[string]android.ModuleProxy) {
75 var fragments []android.ModuleProxy
Colin Cross92b0eb12025-02-06 11:49:52 -080076
77 type fragmentInApex struct {
78 module string
79 apex string
80 }
81
82 var fragmentsInApexes []fragmentInApex
83
84 // Find any direct dependencies, as well as a list of the modules in apexes.
Colin Cross38803c62025-04-16 14:14:55 -070085 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Colin Cross92b0eb12025-02-06 11:49:52 -080086 t := ctx.OtherModuleDependencyTag(module)
87 if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment {
88 if bcpTag.moduleInApex != "" {
89 fragmentsInApexes = append(fragmentsInApexes, fragmentInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
90 } else {
91 fragments = append(fragments, module)
92 }
93 }
94 })
95
Colin Cross38803c62025-04-16 14:14:55 -070096 fragmentsMap := make(map[string]android.ModuleProxy)
Colin Cross92b0eb12025-02-06 11:49:52 -080097 for _, fragmentInApex := range fragmentsInApexes {
Colin Cross38803c62025-04-16 14:14:55 -070098 var found android.ModuleProxy
Colin Cross92b0eb12025-02-06 11:49:52 -080099 // Find a desired module in an apex.
Colin Cross38803c62025-04-16 14:14:55 -0700100 ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
Colin Cross92b0eb12025-02-06 11:49:52 -0800101 t := ctx.OtherModuleDependencyTag(child)
Colin Cross38803c62025-04-16 14:14:55 -0700102 if android.EqualModules(parent, ctx.Module()) {
Colin Cross92b0eb12025-02-06 11:49:52 -0800103 if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == fragment && ctx.OtherModuleName(child) == fragmentInApex.apex {
104 // This is the dependency from this module to the apex, recurse into it.
105 return true
106 }
107 } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
108 return false
109 } else if t == android.PrebuiltDepTag {
110 return false
111 } else if IsBootclasspathFragmentContentDepTag(t) {
112 return false
113 } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == fragmentInApex.module {
114 // This is the desired module inside the apex.
Colin Cross38803c62025-04-16 14:14:55 -0700115 if !found.IsNil() && child != found {
Colin Cross92b0eb12025-02-06 11:49:52 -0800116 panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
117 fragmentInApex.module, fragmentInApex.apex, found, child))
118 }
119 found = child
120 }
121 return false
122 })
Colin Cross38803c62025-04-16 14:14:55 -0700123 if !found.IsNil() {
Colin Cross92b0eb12025-02-06 11:49:52 -0800124 if existing, exists := fragmentsMap[fragmentInApex.apex]; exists {
125 ctx.ModuleErrorf("apex %s has multiple fragments, %s and %s", fragmentInApex.apex, fragmentInApex.module, existing)
126 } else {
127 fragmentsMap[fragmentInApex.apex] = found
128 fragments = append(fragments, found)
129 }
130 } else if !ctx.Config().AllowMissingDependencies() {
131 ctx.ModuleErrorf("failed to find fragment %q in apex %q\n",
132 fragmentInApex.module, fragmentInApex.apex)
133 }
134 }
135 return fragments, fragmentsMap
136}
137
Paul Duffin9bacf562021-04-28 21:16:02 +0100138// gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was
139// added by addDependencyOntoApexModulePair.
Colin Cross38803c62025-04-16 14:14:55 -0700140func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext,
141 tagType bootclasspathDependencyTagType) ([]android.ModuleProxy, map[android.ModuleProxy]string) {
142 var modules []android.ModuleProxy
143 modulesToApex := make(map[android.ModuleProxy]string)
Colin Crossd6495802025-01-14 15:50:48 -0800144
145 type moduleInApex struct {
146 module string
147 apex string
148 }
149
150 var modulesInApexes []moduleInApex
151
Colin Cross38803c62025-04-16 14:14:55 -0700152 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) {
Paul Duffin9bacf562021-04-28 21:16:02 +0100153 t := ctx.OtherModuleDependencyTag(module)
Colin Crossd8d8b852024-12-20 16:32:37 -0800154 if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType {
Colin Crossd6495802025-01-14 15:50:48 -0800155 if bcpTag.moduleInApex != "" {
156 modulesInApexes = append(modulesInApexes, moduleInApex{bcpTag.moduleInApex, ctx.OtherModuleName(module)})
157 } else {
158 modules = append(modules, module)
159 }
Paul Duffin9bacf562021-04-28 21:16:02 +0100160 }
161 })
Colin Crossd6495802025-01-14 15:50:48 -0800162
163 for _, moduleInApex := range modulesInApexes {
Colin Cross38803c62025-04-16 14:14:55 -0700164 var found android.ModuleProxy
165 ctx.WalkDepsProxy(func(child, parent android.ModuleProxy) bool {
Colin Crossd6495802025-01-14 15:50:48 -0800166 t := ctx.OtherModuleDependencyTag(child)
Colin Cross38803c62025-04-16 14:14:55 -0700167 if android.EqualModules(parent, ctx.Module()) {
Colin Crossd6495802025-01-14 15:50:48 -0800168 if bcpTag, ok := t.(bootclasspathDependencyTag); ok && bcpTag.typ == tagType && ctx.OtherModuleName(child) == moduleInApex.apex {
169 // recurse into the apex
170 return true
171 }
172 } else if tagType != fragment && android.IsFragmentInApexTag(t) {
173 return true
174 } else if android.IsDontReplaceSourceWithPrebuiltTag(t) {
175 return false
176 } else if t == android.PrebuiltDepTag {
177 return false
178 } else if IsBootclasspathFragmentContentDepTag(t) {
179 return false
180 } else if android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(child)) == moduleInApex.module {
Colin Cross38803c62025-04-16 14:14:55 -0700181 if !found.IsNil() && child != found {
Colin Crossd6495802025-01-14 15:50:48 -0800182 panic(fmt.Errorf("found two conflicting modules %q in apex %q: %s and %s",
183 moduleInApex.module, moduleInApex.apex, found, child))
184 }
185 found = child
186 }
187 return false
188 })
Colin Cross38803c62025-04-16 14:14:55 -0700189 if !found.IsNil() {
Colin Crossd6495802025-01-14 15:50:48 -0800190 modules = append(modules, found)
Colin Cross92b0eb12025-02-06 11:49:52 -0800191 if existing, exists := modulesToApex[found]; exists && existing != moduleInApex.apex {
192 ctx.ModuleErrorf("module %s is in two apexes, %s and %s", moduleInApex.module, existing, moduleInApex.apex)
193 } else {
194 modulesToApex[found] = moduleInApex.apex
195 }
Colin Crossd6495802025-01-14 15:50:48 -0800196 } else if !ctx.Config().AllowMissingDependencies() {
197 ctx.ModuleErrorf("failed to find module %q in apex %q\n",
198 moduleInApex.module, moduleInApex.apex)
199 }
200 }
Colin Cross92b0eb12025-02-06 11:49:52 -0800201 return modules, modulesToApex
Paul Duffin9bacf562021-04-28 21:16:02 +0100202}
203
Paul Duffinb67d8782021-04-22 11:49:41 +0100204// ApexVariantReference specifies a particular apex variant of a module.
205type ApexVariantReference struct {
Paul Duffin51227d82021-05-18 12:54:27 +0100206 android.BpPrintableBase
207
Paul Duffinb67d8782021-04-22 11:49:41 +0100208 // The name of the module apex variant, i.e. the apex containing the module variant.
209 //
210 // If this is not specified then it defaults to "platform" which will cause a dependency to be
211 // added to the module's platform variant.
Paul Duffin110b0ad2021-04-27 14:36:08 +0100212 //
213 // A value of system_ext should be used for any module that will be part of the system_ext
214 // partition.
Paul Duffinb67d8782021-04-22 11:49:41 +0100215 Apex *string
216
217 // The name of the module.
218 Module *string
219}
220
221// BootclasspathFragmentsDepsProperties contains properties related to dependencies onto fragments.
222type BootclasspathFragmentsDepsProperties struct {
223 // The names of the bootclasspath_fragment modules that form part of this module.
224 Fragments []ApexVariantReference
225}
226
227// addDependenciesOntoFragments adds dependencies to the fragments specified in this properties
228// structure.
229func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) {
Colin Crossd8d8b852024-12-20 16:32:37 -0800230 addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, fragment)
Paul Duffinb67d8782021-04-22 11:49:41 +0100231}
232
233// bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment,
234// prebuilt_bootclasspath_fragment and platform_bootclasspath onto either source or prebuilt
235// modules.
236type bootclasspathDependencyTag struct {
237 blueprint.BaseDependencyTag
238
Colin Crossd8d8b852024-12-20 16:32:37 -0800239 typ bootclasspathDependencyTagType
240
Colin Crossd6495802025-01-14 15:50:48 -0800241 // moduleInApex is set to the name of the desired module when this dependency points
242 // to the apex that the modules is contained in.
243 moduleInApex string
Paul Duffinb67d8782021-04-22 11:49:41 +0100244}
245
Colin Crossd8d8b852024-12-20 16:32:37 -0800246type bootclasspathDependencyTagType int
247
248const (
249 // The tag used for dependencies onto bootclasspath_fragments.
250 fragment bootclasspathDependencyTagType = iota
251 // The tag used for dependencies onto platform_bootclasspath.
252 platform
253 dexpreoptBootJar
254 artBootJar
255 platformBootJar
256 apexBootJar
257)
258
Paul Duffinb67d8782021-04-22 11:49:41 +0100259func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
260}
261
Colin Crossd6495802025-01-14 15:50:48 -0800262func (t bootclasspathDependencyTag) LicenseAnnotations() []android.LicenseAnnotation {
263 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency}
Colin Crossd8d8b852024-12-20 16:32:37 -0800264}
265
Paul Duffinb67d8782021-04-22 11:49:41 +0100266// Dependencies that use the bootclasspathDependencyTag instances are only added after all the
267// visibility checking has been done so this has no functional effect. However, it does make it
268// clear that visibility is not being enforced on these tags.
269var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
270
Paul Duffin10931582021-04-25 10:13:54 +0100271// BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the
272// bootclasspath that are nested within the main BootclasspathAPIProperties.
273type BootclasspathNestedAPIProperties struct {
274 // java_library or preferably, java_sdk_library modules providing stub classes that define the
275 // APIs provided by this bootclasspath_fragment.
Cole Faustaaff7822024-07-30 12:59:44 -0700276 Stub_libs proptools.Configurable[[]string]
Paul Duffin10931582021-04-25 10:13:54 +0100277}
278
279// BootclasspathAPIProperties defines properties for defining the API provided by parts of the
280// bootclasspath.
281type BootclasspathAPIProperties struct {
282 // Api properties provide information about the APIs provided by the bootclasspath_fragment.
283 // Properties in this section apply to public, system and test api scopes. They DO NOT apply to
284 // core_platform as that is a special, ART specific scope, that does not follow the pattern and so
285 // has its own section. It is in the process of being deprecated and replaced by the system scope
286 // but this will remain for the foreseeable future to maintain backwards compatibility.
287 //
288 // Every bootclasspath_fragment must specify at least one stubs_lib in this section and must
289 // specify stubs for all the APIs provided by its contents. Failure to do so will lead to those
290 // methods being inaccessible to other parts of Android, including but not limited to
291 // applications.
292 Api BootclasspathNestedAPIProperties
293
294 // Properties related to the core platform API surface.
295 //
296 // This must only be used by the following modules:
297 // * ART
298 // * Conscrypt
299 // * I18N
300 //
301 // The bootclasspath_fragments for each of the above modules must specify at least one stubs_lib
302 // and must specify stubs for all the APIs provided by its contents. Failure to do so will lead to
303 // those methods being inaccessible to the other modules in the list.
304 Core_platform_api BootclasspathNestedAPIProperties
305}
306
Paul Duffin31fad802021-06-18 18:14:25 +0100307// apiScopeToStubLibs calculates the stub library modules for each relevant *HiddenAPIScope from the
Paul Duffin10931582021-04-25 10:13:54 +0100308// Stub_libs properties.
Cole Faustaaff7822024-07-30 12:59:44 -0700309func (p BootclasspathAPIProperties) apiScopeToStubLibs(ctx android.BaseModuleContext) map[*HiddenAPIScope][]string {
Paul Duffin31fad802021-06-18 18:14:25 +0100310 m := map[*HiddenAPIScope][]string{}
311 for _, apiScope := range hiddenAPISdkLibrarySupportedScopes {
Cole Faustaaff7822024-07-30 12:59:44 -0700312 m[apiScope] = p.Api.Stub_libs.GetOrDefault(ctx, nil)
Paul Duffin10931582021-04-25 10:13:54 +0100313 }
Cole Faustaaff7822024-07-30 12:59:44 -0700314 m[CorePlatformHiddenAPIScope] = p.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil)
Paul Duffin10931582021-04-25 10:13:54 +0100315 return m
316}