xref: /aosp_15_r20/build/soong/android/apex_contributions.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2023 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage android
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint"
19*333d2b36SAndroid Build Coastguard Worker	"github.com/google/blueprint/proptools"
20*333d2b36SAndroid Build Coastguard Worker)
21*333d2b36SAndroid Build Coastguard Worker
22*333d2b36SAndroid Build Coastguard Workerfunc init() {
23*333d2b36SAndroid Build Coastguard Worker	RegisterApexContributionsBuildComponents(InitRegistrationContext)
24*333d2b36SAndroid Build Coastguard Worker}
25*333d2b36SAndroid Build Coastguard Worker
26*333d2b36SAndroid Build Coastguard Workerfunc RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
27*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
28*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
29*333d2b36SAndroid Build Coastguard Worker	ctx.RegisterModuleType("all_apex_contributions", allApexContributionsFactory)
30*333d2b36SAndroid Build Coastguard Worker}
31*333d2b36SAndroid Build Coastguard Worker
32*333d2b36SAndroid Build Coastguard Workertype apexContributions struct {
33*333d2b36SAndroid Build Coastguard Worker	ModuleBase
34*333d2b36SAndroid Build Coastguard Worker	DefaultableModuleBase
35*333d2b36SAndroid Build Coastguard Worker	properties contributionProps
36*333d2b36SAndroid Build Coastguard Worker}
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workertype contributionProps struct {
39*333d2b36SAndroid Build Coastguard Worker	// Name of the mainline module
40*333d2b36SAndroid Build Coastguard Worker	Api_domain *string
41*333d2b36SAndroid Build Coastguard Worker	// A list of module names that should be used when this contribution
42*333d2b36SAndroid Build Coastguard Worker	// is selected via product_config
43*333d2b36SAndroid Build Coastguard Worker	// The name should be explicit (foo or prebuilt_foo)
44*333d2b36SAndroid Build Coastguard Worker	Contents []string
45*333d2b36SAndroid Build Coastguard Worker}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Workerfunc (m *apexContributions) ApiDomain() string {
48*333d2b36SAndroid Build Coastguard Worker	return proptools.String(m.properties.Api_domain)
49*333d2b36SAndroid Build Coastguard Worker}
50*333d2b36SAndroid Build Coastguard Worker
51*333d2b36SAndroid Build Coastguard Workerfunc (m *apexContributions) Contents() []string {
52*333d2b36SAndroid Build Coastguard Worker	return m.properties.Contents
53*333d2b36SAndroid Build Coastguard Worker}
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard Worker// apex_contributions contains a list of module names (source or
56*333d2b36SAndroid Build Coastguard Worker// prebuilt) belonging to the mainline module
57*333d2b36SAndroid Build Coastguard Worker// An apex can have multiple apex_contributions modules
58*333d2b36SAndroid Build Coastguard Worker// with different combinations of source or prebuilts, but only one can be
59*333d2b36SAndroid Build Coastguard Worker// selected via product_config.
60*333d2b36SAndroid Build Coastguard Workerfunc apexContributionsFactory() Module {
61*333d2b36SAndroid Build Coastguard Worker	module := &apexContributions{}
62*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&module.properties)
63*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
64*333d2b36SAndroid Build Coastguard Worker	InitDefaultableModule(module)
65*333d2b36SAndroid Build Coastguard Worker	return module
66*333d2b36SAndroid Build Coastguard Worker}
67*333d2b36SAndroid Build Coastguard Worker
68*333d2b36SAndroid Build Coastguard Worker// This module type does not have any build actions.
69*333d2b36SAndroid Build Coastguard Worker// It provides metadata that is used in post-deps mutator phase for source vs
70*333d2b36SAndroid Build Coastguard Worker// prebuilts selection.
71*333d2b36SAndroid Build Coastguard Workerfunc (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
72*333d2b36SAndroid Build Coastguard Worker}
73*333d2b36SAndroid Build Coastguard Worker
74*333d2b36SAndroid Build Coastguard Workertype apexContributionsDefaults struct {
75*333d2b36SAndroid Build Coastguard Worker	ModuleBase
76*333d2b36SAndroid Build Coastguard Worker	DefaultsModuleBase
77*333d2b36SAndroid Build Coastguard Worker}
78*333d2b36SAndroid Build Coastguard Worker
79*333d2b36SAndroid Build Coastguard Workerfunc apexContributionsDefaultsFactory() Module {
80*333d2b36SAndroid Build Coastguard Worker	module := &apexContributionsDefaults{}
81*333d2b36SAndroid Build Coastguard Worker	module.AddProperties(&contributionProps{})
82*333d2b36SAndroid Build Coastguard Worker	InitDefaultsModule(module)
83*333d2b36SAndroid Build Coastguard Worker	return module
84*333d2b36SAndroid Build Coastguard Worker}
85*333d2b36SAndroid Build Coastguard Worker
86*333d2b36SAndroid Build Coastguard Worker// A container for apex_contributions.
87*333d2b36SAndroid Build Coastguard Worker// Based on product_config, it will create a dependency on the selected
88*333d2b36SAndroid Build Coastguard Worker// apex_contributions per mainline module
89*333d2b36SAndroid Build Coastguard Workertype allApexContributions struct {
90*333d2b36SAndroid Build Coastguard Worker	ModuleBase
91*333d2b36SAndroid Build Coastguard Worker}
92*333d2b36SAndroid Build Coastguard Worker
93*333d2b36SAndroid Build Coastguard Workerfunc allApexContributionsFactory() Module {
94*333d2b36SAndroid Build Coastguard Worker	module := &allApexContributions{}
95*333d2b36SAndroid Build Coastguard Worker	InitAndroidModule(module)
96*333d2b36SAndroid Build Coastguard Worker	return module
97*333d2b36SAndroid Build Coastguard Worker}
98*333d2b36SAndroid Build Coastguard Worker
99*333d2b36SAndroid Build Coastguard Workertype apexContributionsDepTag struct {
100*333d2b36SAndroid Build Coastguard Worker	blueprint.BaseDependencyTag
101*333d2b36SAndroid Build Coastguard Worker}
102*333d2b36SAndroid Build Coastguard Worker
103*333d2b36SAndroid Build Coastguard Workervar (
104*333d2b36SAndroid Build Coastguard Worker	AcDepTag = apexContributionsDepTag{}
105*333d2b36SAndroid Build Coastguard Worker)
106*333d2b36SAndroid Build Coastguard Worker
107*333d2b36SAndroid Build Coastguard Worker// Creates a dep to each selected apex_contributions
108*333d2b36SAndroid Build Coastguard Workerfunc (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
109*333d2b36SAndroid Build Coastguard Worker	// Skip apex_contributions if BuildApexContributionContents is true
110*333d2b36SAndroid Build Coastguard Worker	// This product config var allows some products in the same family to use mainline modules from source
111*333d2b36SAndroid Build Coastguard Worker	// (e.g. shiba and shiba_fullmte)
112*333d2b36SAndroid Build Coastguard Worker	// Eventually these product variants will have their own release config maps.
113*333d2b36SAndroid Build Coastguard Worker	if !proptools.Bool(ctx.Config().BuildIgnoreApexContributionContents()) {
114*333d2b36SAndroid Build Coastguard Worker		ctx.AddDependency(ctx.Module(), AcDepTag, ctx.Config().AllApexContributions()...)
115*333d2b36SAndroid Build Coastguard Worker	}
116*333d2b36SAndroid Build Coastguard Worker}
117*333d2b36SAndroid Build Coastguard Worker
118*333d2b36SAndroid Build Coastguard Worker// Set PrebuiltSelectionInfoProvider in post deps phase
119*333d2b36SAndroid Build Coastguard Workerfunc (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
120*333d2b36SAndroid Build Coastguard Worker	addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
121*333d2b36SAndroid Build Coastguard Worker		for _, content := range m.Contents() {
122*333d2b36SAndroid Build Coastguard Worker			// Verify that the module listed in contents exists in the tree
123*333d2b36SAndroid Build Coastguard Worker			// Remove the prebuilt_ prefix to account for partner worksapces where the source module does not
124*333d2b36SAndroid Build Coastguard Worker			// exist, and PrebuiltRenameMutator renames `prebuilt_foo` to `foo`
125*333d2b36SAndroid Build Coastguard Worker			if !ctx.OtherModuleExists(content) && !ctx.OtherModuleExists(RemoveOptionalPrebuiltPrefix(content)) && !ctx.Config().AllowMissingDependencies() {
126*333d2b36SAndroid Build Coastguard Worker				ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
127*333d2b36SAndroid Build Coastguard Worker			}
128*333d2b36SAndroid Build Coastguard Worker			pi := &PrebuiltSelectionInfo{
129*333d2b36SAndroid Build Coastguard Worker				selectedModuleName: content,
130*333d2b36SAndroid Build Coastguard Worker				metadataModuleName: m.Name(),
131*333d2b36SAndroid Build Coastguard Worker				apiDomain:          m.ApiDomain(),
132*333d2b36SAndroid Build Coastguard Worker			}
133*333d2b36SAndroid Build Coastguard Worker			p.Add(ctx, pi)
134*333d2b36SAndroid Build Coastguard Worker		}
135*333d2b36SAndroid Build Coastguard Worker	}
136*333d2b36SAndroid Build Coastguard Worker
137*333d2b36SAndroid Build Coastguard Worker	p := PrebuiltSelectionInfoMap{}
138*333d2b36SAndroid Build Coastguard Worker	ctx.VisitDirectDepsWithTag(AcDepTag, func(child Module) {
139*333d2b36SAndroid Build Coastguard Worker		if m, ok := child.(*apexContributions); ok {
140*333d2b36SAndroid Build Coastguard Worker			addContentsToProvider(&p, m)
141*333d2b36SAndroid Build Coastguard Worker		} else {
142*333d2b36SAndroid Build Coastguard Worker			ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
143*333d2b36SAndroid Build Coastguard Worker		}
144*333d2b36SAndroid Build Coastguard Worker	})
145*333d2b36SAndroid Build Coastguard Worker	SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
146*333d2b36SAndroid Build Coastguard Worker}
147*333d2b36SAndroid Build Coastguard Worker
148*333d2b36SAndroid Build Coastguard Worker// A provider containing metadata about whether source or prebuilt should be used
149*333d2b36SAndroid Build Coastguard Worker// This provider will be used in prebuilt_select mutator to redirect deps
150*333d2b36SAndroid Build Coastguard Workervar PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
151*333d2b36SAndroid Build Coastguard Worker
152*333d2b36SAndroid Build Coastguard Worker// Map of selected module names to a metadata object
153*333d2b36SAndroid Build Coastguard Worker// The metadata contains information about the api_domain of the selected module
154*333d2b36SAndroid Build Coastguard Workertype PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
155*333d2b36SAndroid Build Coastguard Worker
156*333d2b36SAndroid Build Coastguard Worker// Add a new entry to the map with some validations
157*333d2b36SAndroid Build Coastguard Workerfunc (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
158*333d2b36SAndroid Build Coastguard Worker	if p == nil {
159*333d2b36SAndroid Build Coastguard Worker		return
160*333d2b36SAndroid Build Coastguard Worker	}
161*333d2b36SAndroid Build Coastguard Worker	(*pm)[p.selectedModuleName] = *p
162*333d2b36SAndroid Build Coastguard Worker}
163*333d2b36SAndroid Build Coastguard Worker
164*333d2b36SAndroid Build Coastguard Workertype PrebuiltSelectionInfo struct {
165*333d2b36SAndroid Build Coastguard Worker	// e.g. (libc|prebuilt_libc)
166*333d2b36SAndroid Build Coastguard Worker	selectedModuleName string
167*333d2b36SAndroid Build Coastguard Worker	// Name of the apex_contributions module
168*333d2b36SAndroid Build Coastguard Worker	metadataModuleName string
169*333d2b36SAndroid Build Coastguard Worker	// e.g. com.android.runtime
170*333d2b36SAndroid Build Coastguard Worker	apiDomain string
171*333d2b36SAndroid Build Coastguard Worker}
172*333d2b36SAndroid Build Coastguard Worker
173*333d2b36SAndroid Build Coastguard Worker// Returns true if `name` is explicitly requested using one of the selected
174*333d2b36SAndroid Build Coastguard Worker// apex_contributions metadata modules.
175*333d2b36SAndroid Build Coastguard Workerfunc (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
176*333d2b36SAndroid Build Coastguard Worker	_, exists := (*p)[name]
177*333d2b36SAndroid Build Coastguard Worker	return exists
178*333d2b36SAndroid Build Coastguard Worker}
179*333d2b36SAndroid Build Coastguard Worker
180*333d2b36SAndroid Build Coastguard Worker// Return the list of soong modules selected for this api domain
181*333d2b36SAndroid Build Coastguard Worker// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
182*333d2b36SAndroid Build Coastguard Workerfunc (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
183*333d2b36SAndroid Build Coastguard Worker	selected := []string{}
184*333d2b36SAndroid Build Coastguard Worker	for _, entry := range *p {
185*333d2b36SAndroid Build Coastguard Worker		if entry.apiDomain == apiDomain {
186*333d2b36SAndroid Build Coastguard Worker			selected = append(selected, entry.selectedModuleName)
187*333d2b36SAndroid Build Coastguard Worker		}
188*333d2b36SAndroid Build Coastguard Worker	}
189*333d2b36SAndroid Build Coastguard Worker	return selected
190*333d2b36SAndroid Build Coastguard Worker}
191*333d2b36SAndroid Build Coastguard Worker
192*333d2b36SAndroid Build Coastguard Worker// This module type does not have any build actions.
193*333d2b36SAndroid Build Coastguard Workerfunc (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
194*333d2b36SAndroid Build Coastguard Worker	if ctx.ModuleName() != "all_apex_contributions" {
195*333d2b36SAndroid Build Coastguard Worker		ctx.ModuleErrorf("There can only be 1 all_apex_contributions module in build/soong")
196*333d2b36SAndroid Build Coastguard Worker	}
197*333d2b36SAndroid Build Coastguard Worker}
198