blob: c76d9c23534a6bf00c4a5b0db171fed5e555ec2f [file] [log] [blame]
Spandan Das0d53dd22023-10-24 18:55:12 +00001// Copyright 2023 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 android
16
17import (
Spandan Dasbffd7fb2024-02-26 09:39:37 +000018 "strings"
19
Spandan Dase3fcb412023-10-26 20:48:02 +000020 "github.com/google/blueprint"
Spandan Das0d53dd22023-10-24 18:55:12 +000021 "github.com/google/blueprint/proptools"
22)
23
24func init() {
25 RegisterApexContributionsBuildComponents(InitRegistrationContext)
26}
27
28func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
29 ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
Spandan Das471d0682024-03-06 14:47:08 +000030 ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
Spandan Dase3fcb412023-10-26 20:48:02 +000031 ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
Spandan Das0d53dd22023-10-24 18:55:12 +000032}
33
34type apexContributions struct {
35 ModuleBase
Spandan Das471d0682024-03-06 14:47:08 +000036 DefaultableModuleBase
Spandan Das0d53dd22023-10-24 18:55:12 +000037 properties contributionProps
38}
39
40type contributionProps struct {
41 // Name of the mainline module
42 Api_domain *string
43 // A list of module names that should be used when this contribution
44 // is selected via product_config
45 // The name should be explicit (foo or prebuilt_foo)
46 Contents []string
47}
48
49func (m *apexContributions) ApiDomain() string {
50 return proptools.String(m.properties.Api_domain)
51}
52
53func (m *apexContributions) Contents() []string {
54 return m.properties.Contents
55}
56
57// apex_contributions contains a list of module names (source or
58// prebuilt) belonging to the mainline module
59// An apex can have multiple apex_contributions modules
60// with different combinations of source or prebuilts, but only one can be
61// selected via product_config.
62func apexContributionsFactory() Module {
63 module := &apexContributions{}
64 module.AddProperties(&module.properties)
65 InitAndroidModule(module)
Spandan Das471d0682024-03-06 14:47:08 +000066 InitDefaultableModule(module)
Spandan Das0d53dd22023-10-24 18:55:12 +000067 return module
68}
69
70// This module type does not have any build actions.
71// It provides metadata that is used in post-deps mutator phase for source vs
72// prebuilts selection.
73func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
74}
Spandan Dase3fcb412023-10-26 20:48:02 +000075
Spandan Das471d0682024-03-06 14:47:08 +000076type apexContributionsDefaults struct {
77 ModuleBase
78 DefaultsModuleBase
79}
80
81func apexContributionsDefaultsFactory() Module {
82 module := &apexContributionsDefaults{}
83 module.AddProperties(&contributionProps{})
84 InitDefaultsModule(module)
85 return module
86}
87
Spandan Dase3fcb412023-10-26 20:48:02 +000088// A container for apex_contributions.
89// Based on product_config, it will create a dependency on the selected
90// apex_contributions per mainline module
91type allApexContributions struct {
92 SingletonModuleBase
93}
94
95func allApexContributionsFactory() SingletonModule {
96 module := &allApexContributions{}
97 InitAndroidModule(module)
98 return module
99}
100
101type apexContributionsDepTag struct {
102 blueprint.BaseDependencyTag
103}
104
105var (
106 acDepTag = apexContributionsDepTag{}
107)
108
109// Creates a dep to each selected apex_contributions
110func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
111 ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
112}
113
114// Set PrebuiltSelectionInfoProvider in post deps phase
115func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
116 addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
117 for _, content := range m.Contents() {
Android Culprit Assistantd4afe202024-03-22 06:15:51 +0000118 // Skip any apexes that have been added to the product specific ignore list
119 if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
120 continue
121 }
Spandan Dasbffd7fb2024-02-26 09:39:37 +0000122 // Coverage builds for TARGET_RELEASE=foo should always build from source,
123 // even if TARGET_RELEASE=foo uses prebuilt mainline modules.
124 // This is necessary because the checked-in prebuilts were generated with
125 // instrumentation turned off.
126 //
127 // Skip any prebuilt contents in coverage builds
128 if strings.HasPrefix(content, "prebuilt_") && (ctx.Config().JavaCoverageEnabled() || ctx.DeviceConfig().NativeCoverageEnabled()) {
129 continue
130 }
Spandan Das2daded42023-11-17 18:58:48 +0000131 if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
Spandan Dase3fcb412023-10-26 20:48:02 +0000132 ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
133 }
134 pi := &PrebuiltSelectionInfo{
Spandan Dase3fcb412023-10-26 20:48:02 +0000135 selectedModuleName: content,
136 metadataModuleName: m.Name(),
137 apiDomain: m.ApiDomain(),
138 }
139 p.Add(ctx, pi)
140 }
141 }
142
Spandan Dase3fcb412023-10-26 20:48:02 +0000143 p := PrebuiltSelectionInfoMap{}
Android Culprit Assistantd4afe202024-03-22 06:15:51 +0000144 ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
145 if m, ok := child.(*apexContributions); ok {
146 addContentsToProvider(&p, m)
147 } else {
148 ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
149 }
150 })
Colin Cross40213022023-12-13 15:19:49 -0800151 SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
Spandan Dase3fcb412023-10-26 20:48:02 +0000152}
153
154// A provider containing metadata about whether source or prebuilt should be used
155// This provider will be used in prebuilt_select mutator to redirect deps
Colin Crossbc7d76c2023-12-12 16:39:03 -0800156var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
Spandan Dase3fcb412023-10-26 20:48:02 +0000157
Spandan Das3576e762024-01-03 18:57:03 +0000158// Map of selected module names to a metadata object
159// The metadata contains information about the api_domain of the selected module
Spandan Dase3fcb412023-10-26 20:48:02 +0000160type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
161
162// Add a new entry to the map with some validations
163func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
164 if p == nil {
165 return
166 }
Spandan Das3576e762024-01-03 18:57:03 +0000167 (*pm)[p.selectedModuleName] = *p
Spandan Dase3fcb412023-10-26 20:48:02 +0000168}
169
170type PrebuiltSelectionInfo struct {
Spandan Dase3fcb412023-10-26 20:48:02 +0000171 // e.g. (libc|prebuilt_libc)
172 selectedModuleName string
173 // Name of the apex_contributions module
174 metadataModuleName string
175 // e.g. com.android.runtime
176 apiDomain string
177}
178
179// Returns true if `name` is explicitly requested using one of the selected
180// apex_contributions metadata modules.
Spandan Das3576e762024-01-03 18:57:03 +0000181func (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
182 _, exists := (*p)[name]
183 return exists
Spandan Dase3fcb412023-10-26 20:48:02 +0000184}
185
Spandan Dasda739a32023-12-13 00:06:32 +0000186// Return the list of soong modules selected for this api domain
187// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
188func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
189 selected := []string{}
190 for _, entry := range *p {
191 if entry.apiDomain == apiDomain {
192 selected = append(selected, entry.selectedModuleName)
193 }
194 }
195 return selected
196}
197
Spandan Dase3fcb412023-10-26 20:48:02 +0000198// This module type does not have any build actions.
199func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
200}
201
202func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
203}