blob: 89e27b97b92d80ab59838b03de80364bf9dcad86 [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 Dase3fcb412023-10-26 20:48:02 +000018 "github.com/google/blueprint"
Spandan Das0d53dd22023-10-24 18:55:12 +000019 "github.com/google/blueprint/proptools"
20)
21
22func init() {
23 RegisterApexContributionsBuildComponents(InitRegistrationContext)
24}
25
26func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
27 ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
Spandan Dase3fcb412023-10-26 20:48:02 +000028 ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
Spandan Das0d53dd22023-10-24 18:55:12 +000029}
30
31type apexContributions struct {
32 ModuleBase
33 properties contributionProps
34}
35
36type contributionProps struct {
37 // Name of the mainline module
38 Api_domain *string
39 // A list of module names that should be used when this contribution
40 // is selected via product_config
41 // The name should be explicit (foo or prebuilt_foo)
42 Contents []string
43}
44
45func (m *apexContributions) ApiDomain() string {
46 return proptools.String(m.properties.Api_domain)
47}
48
49func (m *apexContributions) Contents() []string {
50 return m.properties.Contents
51}
52
53// apex_contributions contains a list of module names (source or
54// prebuilt) belonging to the mainline module
55// An apex can have multiple apex_contributions modules
56// with different combinations of source or prebuilts, but only one can be
57// selected via product_config.
58func apexContributionsFactory() Module {
59 module := &apexContributions{}
60 module.AddProperties(&module.properties)
61 InitAndroidModule(module)
62 return module
63}
64
65// This module type does not have any build actions.
66// It provides metadata that is used in post-deps mutator phase for source vs
67// prebuilts selection.
68func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
69}
Spandan Dase3fcb412023-10-26 20:48:02 +000070
71// A container for apex_contributions.
72// Based on product_config, it will create a dependency on the selected
73// apex_contributions per mainline module
74type allApexContributions struct {
75 SingletonModuleBase
76}
77
78func allApexContributionsFactory() SingletonModule {
79 module := &allApexContributions{}
80 InitAndroidModule(module)
81 return module
82}
83
84type apexContributionsDepTag struct {
85 blueprint.BaseDependencyTag
86}
87
88var (
89 acDepTag = apexContributionsDepTag{}
90)
91
92// Creates a dep to each selected apex_contributions
93func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
94 ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
95}
96
97// Set PrebuiltSelectionInfoProvider in post deps phase
98func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
99 addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
100 for _, content := range m.Contents() {
Spandan Das8ab28dd2024-02-17 03:31:45 +0000101 // Skip any apexes that have been added to the product specific ignore list
102 if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
103 continue
104 }
Spandan Das2daded42023-11-17 18:58:48 +0000105 if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
Spandan Dase3fcb412023-10-26 20:48:02 +0000106 ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
107 }
108 pi := &PrebuiltSelectionInfo{
Spandan Dase3fcb412023-10-26 20:48:02 +0000109 selectedModuleName: content,
110 metadataModuleName: m.Name(),
111 apiDomain: m.ApiDomain(),
112 }
113 p.Add(ctx, pi)
114 }
115 }
116
Spandan Dase3fcb412023-10-26 20:48:02 +0000117 p := PrebuiltSelectionInfoMap{}
118 ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
119 if m, ok := child.(*apexContributions); ok {
120 addContentsToProvider(&p, m)
121 } else {
122 ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
123 }
124 })
Colin Cross40213022023-12-13 15:19:49 -0800125 SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
Spandan Dase3fcb412023-10-26 20:48:02 +0000126}
127
128// A provider containing metadata about whether source or prebuilt should be used
129// This provider will be used in prebuilt_select mutator to redirect deps
Colin Crossbc7d76c2023-12-12 16:39:03 -0800130var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
Spandan Dase3fcb412023-10-26 20:48:02 +0000131
Spandan Das3576e762024-01-03 18:57:03 +0000132// Map of selected module names to a metadata object
133// The metadata contains information about the api_domain of the selected module
Spandan Dase3fcb412023-10-26 20:48:02 +0000134type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
135
136// Add a new entry to the map with some validations
137func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
138 if p == nil {
139 return
140 }
Spandan Das3576e762024-01-03 18:57:03 +0000141 (*pm)[p.selectedModuleName] = *p
Spandan Dase3fcb412023-10-26 20:48:02 +0000142}
143
144type PrebuiltSelectionInfo struct {
Spandan Dase3fcb412023-10-26 20:48:02 +0000145 // e.g. (libc|prebuilt_libc)
146 selectedModuleName string
147 // Name of the apex_contributions module
148 metadataModuleName string
149 // e.g. com.android.runtime
150 apiDomain string
151}
152
153// Returns true if `name` is explicitly requested using one of the selected
154// apex_contributions metadata modules.
Spandan Das3576e762024-01-03 18:57:03 +0000155func (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
156 _, exists := (*p)[name]
157 return exists
Spandan Dase3fcb412023-10-26 20:48:02 +0000158}
159
Spandan Dasda739a32023-12-13 00:06:32 +0000160// Return the list of soong modules selected for this api domain
161// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
162func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
163 selected := []string{}
164 for _, entry := range *p {
165 if entry.apiDomain == apiDomain {
166 selected = append(selected, entry.selectedModuleName)
167 }
168 }
169 return selected
170}
171
Spandan Dase3fcb412023-10-26 20:48:02 +0000172// This module type does not have any build actions.
173func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
174}
175
176func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
177}