blob: c388afff9af7e5c0bfa83245d4a4474d6b15da3c [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 Dase3fcb412023-10-26 20:48:02 +000030 ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
Spandan Das0d53dd22023-10-24 18:55:12 +000031}
32
33type apexContributions struct {
34 ModuleBase
35 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)
64 return module
65}
66
67// This module type does not have any build actions.
68// It provides metadata that is used in post-deps mutator phase for source vs
69// prebuilts selection.
70func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
71}
Spandan Dase3fcb412023-10-26 20:48:02 +000072
73// A container for apex_contributions.
74// Based on product_config, it will create a dependency on the selected
75// apex_contributions per mainline module
76type allApexContributions struct {
77 SingletonModuleBase
78}
79
80func allApexContributionsFactory() SingletonModule {
81 module := &allApexContributions{}
82 InitAndroidModule(module)
83 return module
84}
85
86type apexContributionsDepTag struct {
87 blueprint.BaseDependencyTag
88}
89
90var (
91 acDepTag = apexContributionsDepTag{}
92)
93
94// Creates a dep to each selected apex_contributions
95func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
96 ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
97}
98
99// Set PrebuiltSelectionInfoProvider in post deps phase
100func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
101 addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
102 for _, content := range m.Contents() {
Spandan Das8ab28dd2024-02-17 03:31:45 +0000103 // Skip any apexes that have been added to the product specific ignore list
104 if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
105 continue
106 }
Spandan Dasbffd7fb2024-02-26 09:39:37 +0000107 // Coverage builds for TARGET_RELEASE=foo should always build from source,
108 // even if TARGET_RELEASE=foo uses prebuilt mainline modules.
109 // This is necessary because the checked-in prebuilts were generated with
110 // instrumentation turned off.
111 //
112 // Skip any prebuilt contents in coverage builds
113 if strings.HasPrefix(content, "prebuilt_") && (ctx.Config().JavaCoverageEnabled() || ctx.DeviceConfig().NativeCoverageEnabled()) {
114 continue
115 }
Spandan Das2daded42023-11-17 18:58:48 +0000116 if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
Spandan Dase3fcb412023-10-26 20:48:02 +0000117 ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
118 }
119 pi := &PrebuiltSelectionInfo{
Spandan Dase3fcb412023-10-26 20:48:02 +0000120 selectedModuleName: content,
121 metadataModuleName: m.Name(),
122 apiDomain: m.ApiDomain(),
123 }
124 p.Add(ctx, pi)
125 }
126 }
127
Spandan Dase3fcb412023-10-26 20:48:02 +0000128 p := PrebuiltSelectionInfoMap{}
129 ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
130 if m, ok := child.(*apexContributions); ok {
131 addContentsToProvider(&p, m)
132 } else {
133 ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
134 }
135 })
Colin Cross40213022023-12-13 15:19:49 -0800136 SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
Spandan Dase3fcb412023-10-26 20:48:02 +0000137}
138
139// A provider containing metadata about whether source or prebuilt should be used
140// This provider will be used in prebuilt_select mutator to redirect deps
Colin Crossbc7d76c2023-12-12 16:39:03 -0800141var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
Spandan Dase3fcb412023-10-26 20:48:02 +0000142
Spandan Das3576e762024-01-03 18:57:03 +0000143// Map of selected module names to a metadata object
144// The metadata contains information about the api_domain of the selected module
Spandan Dase3fcb412023-10-26 20:48:02 +0000145type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
146
147// Add a new entry to the map with some validations
148func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
149 if p == nil {
150 return
151 }
Spandan Das3576e762024-01-03 18:57:03 +0000152 (*pm)[p.selectedModuleName] = *p
Spandan Dase3fcb412023-10-26 20:48:02 +0000153}
154
155type PrebuiltSelectionInfo struct {
Spandan Dase3fcb412023-10-26 20:48:02 +0000156 // e.g. (libc|prebuilt_libc)
157 selectedModuleName string
158 // Name of the apex_contributions module
159 metadataModuleName string
160 // e.g. com.android.runtime
161 apiDomain string
162}
163
164// Returns true if `name` is explicitly requested using one of the selected
165// apex_contributions metadata modules.
Spandan Das3576e762024-01-03 18:57:03 +0000166func (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
167 _, exists := (*p)[name]
168 return exists
Spandan Dase3fcb412023-10-26 20:48:02 +0000169}
170
Spandan Dasda739a32023-12-13 00:06:32 +0000171// Return the list of soong modules selected for this api domain
172// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
173func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
174 selected := []string{}
175 for _, entry := range *p {
176 if entry.apiDomain == apiDomain {
177 selected = append(selected, entry.selectedModuleName)
178 }
179 }
180 return selected
181}
182
Spandan Dase3fcb412023-10-26 20:48:02 +0000183// This module type does not have any build actions.
184func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
185}
186
187func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
188}