| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 1 | // 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 |  | 
|  | 15 | package java | 
|  | 16 |  | 
|  | 17 | import ( | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 18 | "android/soong/android" | 
| Paul Duffin | 81667c8 | 2021-04-26 13:55:36 +0100 | [diff] [blame] | 19 |  | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 20 | "github.com/google/blueprint" | 
|  | 21 | "github.com/google/blueprint/proptools" | 
|  | 22 | ) | 
|  | 23 |  | 
|  | 24 | // Contains code that is common to both platform_bootclasspath and bootclasspath_fragment. | 
|  | 25 |  | 
| Paul Duffin | 4994d26 | 2021-04-22 12:08:59 +0100 | [diff] [blame] | 26 | func init() { | 
|  | 27 | registerBootclasspathBuildComponents(android.InitRegistrationContext) | 
|  | 28 | } | 
|  | 29 |  | 
|  | 30 | func registerBootclasspathBuildComponents(ctx android.RegistrationContext) { | 
|  | 31 | ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { | 
| Paul Duffin | 7487a7a | 2021-05-19 09:36:09 +0100 | [diff] [blame] | 32 | ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator).Parallel() | 
| Paul Duffin | 4994d26 | 2021-04-22 12:08:59 +0100 | [diff] [blame] | 33 | }) | 
|  | 34 | } | 
|  | 35 |  | 
|  | 36 | // BootclasspathDepsMutator is the interface that a module must implement if it wants to add | 
|  | 37 | // dependencies onto APEX specific variants of bootclasspath fragments or bootclasspath contents. | 
|  | 38 | type BootclasspathDepsMutator interface { | 
|  | 39 | // BootclasspathDepsMutator implementations should add dependencies using | 
|  | 40 | // addDependencyOntoApexModulePair and addDependencyOntoApexVariants. | 
|  | 41 | BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) | 
|  | 42 | } | 
|  | 43 |  | 
|  | 44 | // bootclasspathDepsMutator is called during the final deps phase after all APEX variants have | 
|  | 45 | // been created so can add dependencies onto specific APEX variants of modules. | 
|  | 46 | func bootclasspathDepsMutator(ctx android.BottomUpMutatorContext) { | 
|  | 47 | m := ctx.Module() | 
|  | 48 | if p, ok := m.(BootclasspathDepsMutator); ok { | 
|  | 49 | p.BootclasspathDepsMutator(ctx) | 
|  | 50 | } | 
|  | 51 | } | 
|  | 52 |  | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 53 | // addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of | 
|  | 54 | // the module as specified in the ApexVariantReference list. | 
|  | 55 | func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) { | 
|  | 56 | for i, ref := range refs { | 
|  | 57 | apex := proptools.StringDefault(ref.Apex, "platform") | 
|  | 58 |  | 
|  | 59 | if ref.Module == nil { | 
|  | 60 | ctx.PropertyErrorf(propertyName, "missing module name at position %d", i) | 
|  | 61 | continue | 
|  | 62 | } | 
|  | 63 | name := proptools.String(ref.Module) | 
|  | 64 |  | 
|  | 65 | addDependencyOntoApexModulePair(ctx, apex, name, tag) | 
|  | 66 | } | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | // addDependencyOntoApexModulePair adds a dependency onto the specified APEX specific variant or the | 
|  | 70 | // specified module. | 
|  | 71 | // | 
| Paul Duffin | 110b0ad | 2021-04-27 14:36:08 +0100 | [diff] [blame] | 72 | // If apex="platform" or "system_ext" then this adds a dependency onto the platform variant of the | 
|  | 73 | // module. This adds dependencies onto the prebuilt and source modules with the specified name, | 
|  | 74 | // depending on which ones are available. Visiting must use isActiveModule to select the preferred | 
|  | 75 | // module when both source and prebuilt modules are available. | 
| Paul Duffin | 9bacf56 | 2021-04-28 21:16:02 +0100 | [diff] [blame] | 76 | // | 
|  | 77 | // Use gatherApexModulePairDepsWithTag to retrieve the dependencies. | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 78 | func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) { | 
|  | 79 | var variations []blueprint.Variation | 
| Jiakai Zhang | b1639db | 2023-07-11 15:03:13 +0100 | [diff] [blame] | 80 | if !android.IsConfiguredJarForPlatform(apex) { | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 81 | // Pick the correct apex variant. | 
|  | 82 | variations = []blueprint.Variation{ | 
|  | 83 | {Mutator: "apex", Variation: apex}, | 
|  | 84 | } | 
|  | 85 | } | 
|  | 86 |  | 
| Paul Duffin | b2c2173 | 2022-05-11 14:29:53 +0000 | [diff] [blame] | 87 | target := ctx.Module().Target() | 
|  | 88 | variations = append(variations, target.Variations()...) | 
|  | 89 |  | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 90 | addedDep := false | 
|  | 91 | if ctx.OtherModuleDependencyVariantExists(variations, name) { | 
|  | 92 | ctx.AddFarVariationDependencies(variations, tag, name) | 
|  | 93 | addedDep = true | 
|  | 94 | } | 
|  | 95 |  | 
|  | 96 | // Add a dependency on the prebuilt module if it exists. | 
|  | 97 | prebuiltName := android.PrebuiltNameFromSource(name) | 
|  | 98 | if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) { | 
|  | 99 | ctx.AddVariationDependencies(variations, tag, prebuiltName) | 
|  | 100 | addedDep = true | 
|  | 101 | } | 
|  | 102 |  | 
|  | 103 | // If no appropriate variant existing for this, so no dependency could be added, then it is an | 
|  | 104 | // error, unless missing dependencies are allowed. The simplest way to handle that is to add a | 
|  | 105 | // dependency that will not be satisfied and the default behavior will handle it. | 
|  | 106 | if !addedDep { | 
|  | 107 | // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does | 
|  | 108 | // not exist. The resulting error message will contain useful information about the available | 
|  | 109 | // variants. | 
|  | 110 | reportMissingVariationDependency(ctx, variations, name) | 
|  | 111 |  | 
|  | 112 | // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists | 
|  | 113 | // so that information about its available variants will be reported too. | 
|  | 114 | if ctx.OtherModuleExists(prebuiltName) { | 
|  | 115 | reportMissingVariationDependency(ctx, variations, prebuiltName) | 
|  | 116 | } | 
|  | 117 | } | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | // reportMissingVariationDependency intentionally adds a dependency on a missing variation in order | 
|  | 121 | // to generate an appropriate error message with information about the available variations. | 
|  | 122 | func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) { | 
| Paul Duffin | 81667c8 | 2021-04-26 13:55:36 +0100 | [diff] [blame] | 123 | ctx.AddFarVariationDependencies(variations, nil, name) | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 124 | } | 
|  | 125 |  | 
| Paul Duffin | 9bacf56 | 2021-04-28 21:16:02 +0100 | [diff] [blame] | 126 | // gatherApexModulePairDepsWithTag returns the list of dependencies with the supplied tag that was | 
|  | 127 | // added by addDependencyOntoApexModulePair. | 
|  | 128 | func gatherApexModulePairDepsWithTag(ctx android.BaseModuleContext, tag blueprint.DependencyTag) []android.Module { | 
|  | 129 | var modules []android.Module | 
| Cole Faust | a963b94 | 2024-04-11 17:43:00 -0700 | [diff] [blame] | 130 | isActiveModulePred := func(module android.Module) bool { | 
|  | 131 | return isActiveModule(ctx, module) | 
|  | 132 | } | 
|  | 133 | ctx.VisitDirectDepsIf(isActiveModulePred, func(module android.Module) { | 
| Paul Duffin | 9bacf56 | 2021-04-28 21:16:02 +0100 | [diff] [blame] | 134 | t := ctx.OtherModuleDependencyTag(module) | 
|  | 135 | if t == tag { | 
|  | 136 | modules = append(modules, module) | 
|  | 137 | } | 
|  | 138 | }) | 
|  | 139 | return modules | 
|  | 140 | } | 
|  | 141 |  | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 142 | // ApexVariantReference specifies a particular apex variant of a module. | 
|  | 143 | type ApexVariantReference struct { | 
| Paul Duffin | 51227d8 | 2021-05-18 12:54:27 +0100 | [diff] [blame] | 144 | android.BpPrintableBase | 
|  | 145 |  | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 146 | // The name of the module apex variant, i.e. the apex containing the module variant. | 
|  | 147 | // | 
|  | 148 | // If this is not specified then it defaults to "platform" which will cause a dependency to be | 
|  | 149 | // added to the module's platform variant. | 
| Paul Duffin | 110b0ad | 2021-04-27 14:36:08 +0100 | [diff] [blame] | 150 | // | 
|  | 151 | // A value of system_ext should be used for any module that will be part of the system_ext | 
|  | 152 | // partition. | 
| Paul Duffin | b67d878 | 2021-04-22 11:49:41 +0100 | [diff] [blame] | 153 | Apex *string | 
|  | 154 |  | 
|  | 155 | // The name of the module. | 
|  | 156 | Module *string | 
|  | 157 | } | 
|  | 158 |  | 
|  | 159 | // BootclasspathFragmentsDepsProperties contains properties related to dependencies onto fragments. | 
|  | 160 | type BootclasspathFragmentsDepsProperties struct { | 
|  | 161 | // The names of the bootclasspath_fragment modules that form part of this module. | 
|  | 162 | Fragments []ApexVariantReference | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | // addDependenciesOntoFragments adds dependencies to the fragments specified in this properties | 
|  | 166 | // structure. | 
|  | 167 | func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) { | 
|  | 168 | addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, bootclasspathFragmentDepTag) | 
|  | 169 | } | 
|  | 170 |  | 
|  | 171 | // bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment, | 
|  | 172 | // prebuilt_bootclasspath_fragment and platform_bootclasspath onto either source or prebuilt | 
|  | 173 | // modules. | 
|  | 174 | type bootclasspathDependencyTag struct { | 
|  | 175 | blueprint.BaseDependencyTag | 
|  | 176 |  | 
|  | 177 | name string | 
|  | 178 | } | 
|  | 179 |  | 
|  | 180 | func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() { | 
|  | 181 | } | 
|  | 182 |  | 
|  | 183 | // Dependencies that use the bootclasspathDependencyTag instances are only added after all the | 
|  | 184 | // visibility checking has been done so this has no functional effect. However, it does make it | 
|  | 185 | // clear that visibility is not being enforced on these tags. | 
|  | 186 | var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{} | 
|  | 187 |  | 
|  | 188 | // The tag used for dependencies onto bootclasspath_fragments. | 
|  | 189 | var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"} | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 190 |  | 
| Jiakai Zhang | cb13b5d | 2023-07-13 11:03:38 +0100 | [diff] [blame] | 191 | // The tag used for dependencies onto platform_bootclasspath. | 
|  | 192 | var platformBootclasspathDepTag = bootclasspathDependencyTag{name: "platform"} | 
|  | 193 |  | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 194 | // BootclasspathNestedAPIProperties defines properties related to the API provided by parts of the | 
|  | 195 | // bootclasspath that are nested within the main BootclasspathAPIProperties. | 
|  | 196 | type BootclasspathNestedAPIProperties struct { | 
|  | 197 | // java_library or preferably, java_sdk_library modules providing stub classes that define the | 
|  | 198 | // APIs provided by this bootclasspath_fragment. | 
| Cole Faust | aaff782 | 2024-07-30 12:59:44 -0700 | [diff] [blame] | 199 | Stub_libs proptools.Configurable[[]string] | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 200 | } | 
|  | 201 |  | 
|  | 202 | // BootclasspathAPIProperties defines properties for defining the API provided by parts of the | 
|  | 203 | // bootclasspath. | 
|  | 204 | type BootclasspathAPIProperties struct { | 
|  | 205 | // Api properties provide information about the APIs provided by the bootclasspath_fragment. | 
|  | 206 | // Properties in this section apply to public, system and test api scopes. They DO NOT apply to | 
|  | 207 | // core_platform as that is a special, ART specific scope, that does not follow the pattern and so | 
|  | 208 | // has its own section. It is in the process of being deprecated and replaced by the system scope | 
|  | 209 | // but this will remain for the foreseeable future to maintain backwards compatibility. | 
|  | 210 | // | 
|  | 211 | // Every bootclasspath_fragment must specify at least one stubs_lib in this section and must | 
|  | 212 | // specify stubs for all the APIs provided by its contents. Failure to do so will lead to those | 
|  | 213 | // methods being inaccessible to other parts of Android, including but not limited to | 
|  | 214 | // applications. | 
|  | 215 | Api BootclasspathNestedAPIProperties | 
|  | 216 |  | 
|  | 217 | // Properties related to the core platform API surface. | 
|  | 218 | // | 
|  | 219 | // This must only be used by the following modules: | 
|  | 220 | // * ART | 
|  | 221 | // * Conscrypt | 
|  | 222 | // * I18N | 
|  | 223 | // | 
|  | 224 | // The bootclasspath_fragments for each of the above modules must specify at least one stubs_lib | 
|  | 225 | // and must specify stubs for all the APIs provided by its contents. Failure to do so will lead to | 
|  | 226 | // those methods being inaccessible to the other modules in the list. | 
|  | 227 | Core_platform_api BootclasspathNestedAPIProperties | 
|  | 228 | } | 
|  | 229 |  | 
| Paul Duffin | 31fad80 | 2021-06-18 18:14:25 +0100 | [diff] [blame] | 230 | // apiScopeToStubLibs calculates the stub library modules for each relevant *HiddenAPIScope from the | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 231 | // Stub_libs properties. | 
| Cole Faust | aaff782 | 2024-07-30 12:59:44 -0700 | [diff] [blame] | 232 | func (p BootclasspathAPIProperties) apiScopeToStubLibs(ctx android.BaseModuleContext) map[*HiddenAPIScope][]string { | 
| Paul Duffin | 31fad80 | 2021-06-18 18:14:25 +0100 | [diff] [blame] | 233 | m := map[*HiddenAPIScope][]string{} | 
|  | 234 | for _, apiScope := range hiddenAPISdkLibrarySupportedScopes { | 
| Cole Faust | aaff782 | 2024-07-30 12:59:44 -0700 | [diff] [blame] | 235 | m[apiScope] = p.Api.Stub_libs.GetOrDefault(ctx, nil) | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 236 | } | 
| Cole Faust | aaff782 | 2024-07-30 12:59:44 -0700 | [diff] [blame] | 237 | m[CorePlatformHiddenAPIScope] = p.Core_platform_api.Stub_libs.GetOrDefault(ctx, nil) | 
| Paul Duffin | 1093158 | 2021-04-25 10:13:54 +0100 | [diff] [blame] | 238 | return m | 
|  | 239 | } |