blob: 6ca0f7533ff998e869242e26bf1e82aaccb833f4 [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 (
18 "fmt"
19
20 "android/soong/android"
21 "github.com/google/blueprint"
22 "github.com/google/blueprint/proptools"
23)
24
25// Contains code that is common to both platform_bootclasspath and bootclasspath_fragment.
26
Paul Duffin4994d262021-04-22 12:08:59 +010027func init() {
28 registerBootclasspathBuildComponents(android.InitRegistrationContext)
29}
30
31func registerBootclasspathBuildComponents(ctx android.RegistrationContext) {
32 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
33 ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator)
34 })
35}
36
37// BootclasspathDepsMutator is the interface that a module must implement if it wants to add
38// dependencies onto APEX specific variants of bootclasspath fragments or bootclasspath contents.
39type BootclasspathDepsMutator interface {
40 // BootclasspathDepsMutator implementations should add dependencies using
41 // addDependencyOntoApexModulePair and addDependencyOntoApexVariants.
42 BootclasspathDepsMutator(ctx android.BottomUpMutatorContext)
43}
44
45// bootclasspathDepsMutator is called during the final deps phase after all APEX variants have
46// been created so can add dependencies onto specific APEX variants of modules.
47func bootclasspathDepsMutator(ctx android.BottomUpMutatorContext) {
48 m := ctx.Module()
49 if p, ok := m.(BootclasspathDepsMutator); ok {
50 p.BootclasspathDepsMutator(ctx)
51 }
52}
53
Paul Duffinb67d8782021-04-22 11:49:41 +010054// addDependencyOntoApexVariants adds dependencies onto the appropriate apex specific variants of
55// the module as specified in the ApexVariantReference list.
56func addDependencyOntoApexVariants(ctx android.BottomUpMutatorContext, propertyName string, refs []ApexVariantReference, tag blueprint.DependencyTag) {
57 for i, ref := range refs {
58 apex := proptools.StringDefault(ref.Apex, "platform")
59
60 if ref.Module == nil {
61 ctx.PropertyErrorf(propertyName, "missing module name at position %d", i)
62 continue
63 }
64 name := proptools.String(ref.Module)
65
66 addDependencyOntoApexModulePair(ctx, apex, name, tag)
67 }
68}
69
70// addDependencyOntoApexModulePair adds a dependency onto the specified APEX specific variant or the
71// specified module.
72//
73// If apex="platform" then this adds a dependency onto the platform variant of the module. This adds
74// dependencies onto the prebuilt and source modules with the specified name, depending on which
75// ones are available. Visiting must use isActiveModule to select the preferred module when both
76// source and prebuilt modules are available.
77func addDependencyOntoApexModulePair(ctx android.BottomUpMutatorContext, apex string, name string, tag blueprint.DependencyTag) {
78 var variations []blueprint.Variation
79 if apex != "platform" {
80 // Pick the correct apex variant.
81 variations = []blueprint.Variation{
82 {Mutator: "apex", Variation: apex},
83 }
84 }
85
86 addedDep := false
87 if ctx.OtherModuleDependencyVariantExists(variations, name) {
88 ctx.AddFarVariationDependencies(variations, tag, name)
89 addedDep = true
90 }
91
92 // Add a dependency on the prebuilt module if it exists.
93 prebuiltName := android.PrebuiltNameFromSource(name)
94 if ctx.OtherModuleDependencyVariantExists(variations, prebuiltName) {
95 ctx.AddVariationDependencies(variations, tag, prebuiltName)
96 addedDep = true
97 }
98
99 // If no appropriate variant existing for this, so no dependency could be added, then it is an
100 // error, unless missing dependencies are allowed. The simplest way to handle that is to add a
101 // dependency that will not be satisfied and the default behavior will handle it.
102 if !addedDep {
103 // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
104 // not exist. The resulting error message will contain useful information about the available
105 // variants.
106 reportMissingVariationDependency(ctx, variations, name)
107
108 // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
109 // so that information about its available variants will be reported too.
110 if ctx.OtherModuleExists(prebuiltName) {
111 reportMissingVariationDependency(ctx, variations, prebuiltName)
112 }
113 }
114}
115
116// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
117// to generate an appropriate error message with information about the available variations.
118func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
119 modules := ctx.AddFarVariationDependencies(variations, nil, name)
120 if len(modules) != 1 {
121 panic(fmt.Errorf("Internal Error: expected one module, found %d", len(modules)))
122 return
123 }
124 if modules[0] != nil {
125 panic(fmt.Errorf("Internal Error: expected module to be missing but was found: %q", modules[0]))
126 return
127 }
128}
129
130// ApexVariantReference specifies a particular apex variant of a module.
131type ApexVariantReference struct {
132 // The name of the module apex variant, i.e. the apex containing the module variant.
133 //
134 // If this is not specified then it defaults to "platform" which will cause a dependency to be
135 // added to the module's platform variant.
136 Apex *string
137
138 // The name of the module.
139 Module *string
140}
141
142// BootclasspathFragmentsDepsProperties contains properties related to dependencies onto fragments.
143type BootclasspathFragmentsDepsProperties struct {
144 // The names of the bootclasspath_fragment modules that form part of this module.
145 Fragments []ApexVariantReference
146}
147
148// addDependenciesOntoFragments adds dependencies to the fragments specified in this properties
149// structure.
150func (p *BootclasspathFragmentsDepsProperties) addDependenciesOntoFragments(ctx android.BottomUpMutatorContext) {
151 addDependencyOntoApexVariants(ctx, "fragments", p.Fragments, bootclasspathFragmentDepTag)
152}
153
154// bootclasspathDependencyTag defines dependencies from/to bootclasspath_fragment,
155// prebuilt_bootclasspath_fragment and platform_bootclasspath onto either source or prebuilt
156// modules.
157type bootclasspathDependencyTag struct {
158 blueprint.BaseDependencyTag
159
160 name string
161}
162
163func (t bootclasspathDependencyTag) ExcludeFromVisibilityEnforcement() {
164}
165
166// Dependencies that use the bootclasspathDependencyTag instances are only added after all the
167// visibility checking has been done so this has no functional effect. However, it does make it
168// clear that visibility is not being enforced on these tags.
169var _ android.ExcludeFromVisibilityEnforcementTag = bootclasspathDependencyTag{}
170
171// The tag used for dependencies onto bootclasspath_fragments.
172var bootclasspathFragmentDepTag = bootclasspathDependencyTag{name: "fragment"}