blob: fe7a8352e0e7a7530e1a98f6b15418b90de3ee00 [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 Das471d0682024-03-06 14:47:08 +000028 ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
Cole Faust28cc1c72024-10-30 10:08:58 -070029 ctx.RegisterModuleType("all_apex_contributions", allApexContributionsFactory)
Spandan Das0d53dd22023-10-24 18:55:12 +000030}
31
32type apexContributions struct {
33 ModuleBase
Spandan Das471d0682024-03-06 14:47:08 +000034 DefaultableModuleBase
Spandan Das0d53dd22023-10-24 18:55:12 +000035 properties contributionProps
36}
37
38type contributionProps struct {
39 // Name of the mainline module
40 Api_domain *string
41 // A list of module names that should be used when this contribution
42 // is selected via product_config
43 // The name should be explicit (foo or prebuilt_foo)
44 Contents []string
45}
46
47func (m *apexContributions) ApiDomain() string {
48 return proptools.String(m.properties.Api_domain)
49}
50
51func (m *apexContributions) Contents() []string {
52 return m.properties.Contents
53}
54
55// apex_contributions contains a list of module names (source or
56// prebuilt) belonging to the mainline module
57// An apex can have multiple apex_contributions modules
58// with different combinations of source or prebuilts, but only one can be
59// selected via product_config.
60func apexContributionsFactory() Module {
61 module := &apexContributions{}
62 module.AddProperties(&module.properties)
63 InitAndroidModule(module)
Spandan Das471d0682024-03-06 14:47:08 +000064 InitDefaultableModule(module)
Spandan Das0d53dd22023-10-24 18:55:12 +000065 return module
66}
67
68// This module type does not have any build actions.
69// It provides metadata that is used in post-deps mutator phase for source vs
70// prebuilts selection.
71func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
72}
Spandan Dase3fcb412023-10-26 20:48:02 +000073
Spandan Das471d0682024-03-06 14:47:08 +000074type apexContributionsDefaults struct {
75 ModuleBase
76 DefaultsModuleBase
77}
78
79func apexContributionsDefaultsFactory() Module {
80 module := &apexContributionsDefaults{}
81 module.AddProperties(&contributionProps{})
82 InitDefaultsModule(module)
83 return module
84}
85
Spandan Dase3fcb412023-10-26 20:48:02 +000086// A container for apex_contributions.
87// Based on product_config, it will create a dependency on the selected
88// apex_contributions per mainline module
89type allApexContributions struct {
Cole Faust28cc1c72024-10-30 10:08:58 -070090 ModuleBase
Spandan Dase3fcb412023-10-26 20:48:02 +000091}
92
Cole Faust28cc1c72024-10-30 10:08:58 -070093func allApexContributionsFactory() Module {
Spandan Dase3fcb412023-10-26 20:48:02 +000094 module := &allApexContributions{}
95 InitAndroidModule(module)
96 return module
97}
98
99type apexContributionsDepTag struct {
100 blueprint.BaseDependencyTag
101}
102
103var (
Jihoon Kanga3a05462024-04-05 00:36:44 +0000104 AcDepTag = apexContributionsDepTag{}
Spandan Dase3fcb412023-10-26 20:48:02 +0000105)
106
Spandan Dase3fcb412023-10-26 20:48:02 +0000107// Set PrebuiltSelectionInfoProvider in post deps phase
Colin Crossd8d8b852024-12-20 16:32:37 -0800108func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BottomUpMutatorContext) {
Spandan Dase3fcb412023-10-26 20:48:02 +0000109 addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
110 for _, content := range m.Contents() {
Spandan Das85bd4622024-08-01 00:51:20 +0000111 // Verify that the module listed in contents exists in the tree
112 // Remove the prebuilt_ prefix to account for partner worksapces where the source module does not
113 // exist, and PrebuiltRenameMutator renames `prebuilt_foo` to `foo`
114 if !ctx.OtherModuleExists(content) && !ctx.OtherModuleExists(RemoveOptionalPrebuiltPrefix(content)) && !ctx.Config().AllowMissingDependencies() {
Spandan Dase3fcb412023-10-26 20:48:02 +0000115 ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
116 }
117 pi := &PrebuiltSelectionInfo{
Spandan Dase3fcb412023-10-26 20:48:02 +0000118 selectedModuleName: content,
119 metadataModuleName: m.Name(),
120 apiDomain: m.ApiDomain(),
121 }
122 p.Add(ctx, pi)
123 }
124 }
125
Spandan Dase3fcb412023-10-26 20:48:02 +0000126 p := PrebuiltSelectionInfoMap{}
Colin Crossd8d8b852024-12-20 16:32:37 -0800127 // Skip apex_contributions if BuildApexContributionContents is true
128 // This product config var allows some products in the same family to use mainline modules from source
129 // (e.g. shiba and shiba_fullmte)
130 // Eventually these product variants will have their own release config maps.
131 if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
132 deps := ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
133 for _, child := range deps {
134 if child == nil {
135 continue
136 }
137 if m, ok := child.(*apexContributions); ok {
138 addContentsToProvider(&p, m)
139 } else {
140 ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
141 }
Spandan Dasa8667132024-05-30 16:46:44 +0000142 }
Colin Crossd8d8b852024-12-20 16:32:37 -0800143 }
Colin Cross40213022023-12-13 15:19:49 -0800144 SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
Spandan Dase3fcb412023-10-26 20:48:02 +0000145}
146
147// A provider containing metadata about whether source or prebuilt should be used
148// This provider will be used in prebuilt_select mutator to redirect deps
Colin Crossbc7d76c2023-12-12 16:39:03 -0800149var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
Spandan Dase3fcb412023-10-26 20:48:02 +0000150
Spandan Das3576e762024-01-03 18:57:03 +0000151// Map of selected module names to a metadata object
152// The metadata contains information about the api_domain of the selected module
Spandan Dase3fcb412023-10-26 20:48:02 +0000153type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
154
155// Add a new entry to the map with some validations
156func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
157 if p == nil {
158 return
159 }
Spandan Das3576e762024-01-03 18:57:03 +0000160 (*pm)[p.selectedModuleName] = *p
Spandan Dase3fcb412023-10-26 20:48:02 +0000161}
162
163type PrebuiltSelectionInfo struct {
Spandan Dase3fcb412023-10-26 20:48:02 +0000164 // e.g. (libc|prebuilt_libc)
165 selectedModuleName string
166 // Name of the apex_contributions module
167 metadataModuleName string
168 // e.g. com.android.runtime
169 apiDomain string
170}
171
172// Returns true if `name` is explicitly requested using one of the selected
173// apex_contributions metadata modules.
Spandan Das3576e762024-01-03 18:57:03 +0000174func (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
175 _, exists := (*p)[name]
176 return exists
Spandan Dase3fcb412023-10-26 20:48:02 +0000177}
178
Spandan Dasda739a32023-12-13 00:06:32 +0000179// Return the list of soong modules selected for this api domain
180// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
181func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
182 selected := []string{}
183 for _, entry := range *p {
184 if entry.apiDomain == apiDomain {
185 selected = append(selected, entry.selectedModuleName)
186 }
187 }
188 return selected
189}
190
Spandan Dase3fcb412023-10-26 20:48:02 +0000191// This module type does not have any build actions.
192func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
Cole Faust28cc1c72024-10-30 10:08:58 -0700193 if ctx.ModuleName() != "all_apex_contributions" {
194 ctx.ModuleErrorf("There can only be 1 all_apex_contributions module in build/soong")
195 }
Spandan Dase3fcb412023-10-26 20:48:02 +0000196}