2023-10-24 20:55:12 +02:00
|
|
|
// Copyright 2023 Google Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package android
|
|
|
|
|
|
|
|
import (
|
2024-02-26 10:39:37 +01:00
|
|
|
"strings"
|
|
|
|
|
2023-10-26 22:48:02 +02:00
|
|
|
"github.com/google/blueprint"
|
2023-10-24 20:55:12 +02:00
|
|
|
"github.com/google/blueprint/proptools"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
RegisterApexContributionsBuildComponents(InitRegistrationContext)
|
|
|
|
}
|
|
|
|
|
|
|
|
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
|
|
|
|
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
|
2024-03-06 15:47:08 +01:00
|
|
|
ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
|
2023-10-26 22:48:02 +02:00
|
|
|
ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
|
2023-10-24 20:55:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type apexContributions struct {
|
|
|
|
ModuleBase
|
2024-03-06 15:47:08 +01:00
|
|
|
DefaultableModuleBase
|
2023-10-24 20:55:12 +02:00
|
|
|
properties contributionProps
|
|
|
|
}
|
|
|
|
|
|
|
|
type contributionProps struct {
|
|
|
|
// Name of the mainline module
|
|
|
|
Api_domain *string
|
|
|
|
// A list of module names that should be used when this contribution
|
|
|
|
// is selected via product_config
|
|
|
|
// The name should be explicit (foo or prebuilt_foo)
|
|
|
|
Contents []string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *apexContributions) ApiDomain() string {
|
|
|
|
return proptools.String(m.properties.Api_domain)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *apexContributions) Contents() []string {
|
|
|
|
return m.properties.Contents
|
|
|
|
}
|
|
|
|
|
|
|
|
// apex_contributions contains a list of module names (source or
|
|
|
|
// prebuilt) belonging to the mainline module
|
|
|
|
// An apex can have multiple apex_contributions modules
|
|
|
|
// with different combinations of source or prebuilts, but only one can be
|
|
|
|
// selected via product_config.
|
|
|
|
func apexContributionsFactory() Module {
|
|
|
|
module := &apexContributions{}
|
|
|
|
module.AddProperties(&module.properties)
|
|
|
|
InitAndroidModule(module)
|
2024-03-06 15:47:08 +01:00
|
|
|
InitDefaultableModule(module)
|
2023-10-24 20:55:12 +02:00
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
|
|
|
// This module type does not have any build actions.
|
|
|
|
// It provides metadata that is used in post-deps mutator phase for source vs
|
|
|
|
// prebuilts selection.
|
|
|
|
func (m *apexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
|
|
}
|
2023-10-26 22:48:02 +02:00
|
|
|
|
2024-03-06 15:47:08 +01:00
|
|
|
type apexContributionsDefaults struct {
|
|
|
|
ModuleBase
|
|
|
|
DefaultsModuleBase
|
|
|
|
}
|
|
|
|
|
|
|
|
func apexContributionsDefaultsFactory() Module {
|
|
|
|
module := &apexContributionsDefaults{}
|
|
|
|
module.AddProperties(&contributionProps{})
|
|
|
|
InitDefaultsModule(module)
|
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
2023-10-26 22:48:02 +02:00
|
|
|
// A container for apex_contributions.
|
|
|
|
// Based on product_config, it will create a dependency on the selected
|
|
|
|
// apex_contributions per mainline module
|
|
|
|
type allApexContributions struct {
|
|
|
|
SingletonModuleBase
|
|
|
|
}
|
|
|
|
|
|
|
|
func allApexContributionsFactory() SingletonModule {
|
|
|
|
module := &allApexContributions{}
|
|
|
|
InitAndroidModule(module)
|
|
|
|
return module
|
|
|
|
}
|
|
|
|
|
|
|
|
type apexContributionsDepTag struct {
|
|
|
|
blueprint.BaseDependencyTag
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
acDepTag = apexContributionsDepTag{}
|
|
|
|
)
|
|
|
|
|
|
|
|
// Creates a dep to each selected apex_contributions
|
|
|
|
func (a *allApexContributions) DepsMutator(ctx BottomUpMutatorContext) {
|
|
|
|
ctx.AddDependency(ctx.Module(), acDepTag, ctx.Config().AllApexContributions()...)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set PrebuiltSelectionInfoProvider in post deps phase
|
|
|
|
func (a *allApexContributions) SetPrebuiltSelectionInfoProvider(ctx BaseModuleContext) {
|
|
|
|
addContentsToProvider := func(p *PrebuiltSelectionInfoMap, m *apexContributions) {
|
|
|
|
for _, content := range m.Contents() {
|
2024-03-22 07:15:51 +01:00
|
|
|
// Skip any apexes that have been added to the product specific ignore list
|
|
|
|
if InList(content, ctx.Config().BuildIgnoreApexContributionContents()) {
|
|
|
|
continue
|
|
|
|
}
|
2024-02-26 10:39:37 +01:00
|
|
|
// Coverage builds for TARGET_RELEASE=foo should always build from source,
|
|
|
|
// even if TARGET_RELEASE=foo uses prebuilt mainline modules.
|
|
|
|
// This is necessary because the checked-in prebuilts were generated with
|
|
|
|
// instrumentation turned off.
|
|
|
|
//
|
|
|
|
// Skip any prebuilt contents in coverage builds
|
|
|
|
if strings.HasPrefix(content, "prebuilt_") && (ctx.Config().JavaCoverageEnabled() || ctx.DeviceConfig().NativeCoverageEnabled()) {
|
|
|
|
continue
|
|
|
|
}
|
2023-11-17 19:58:48 +01:00
|
|
|
if !ctx.OtherModuleExists(content) && !ctx.Config().AllowMissingDependencies() {
|
2023-10-26 22:48:02 +02:00
|
|
|
ctx.ModuleErrorf("%s listed in apex_contributions %s does not exist\n", content, m.Name())
|
|
|
|
}
|
|
|
|
pi := &PrebuiltSelectionInfo{
|
|
|
|
selectedModuleName: content,
|
|
|
|
metadataModuleName: m.Name(),
|
|
|
|
apiDomain: m.ApiDomain(),
|
|
|
|
}
|
|
|
|
p.Add(ctx, pi)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p := PrebuiltSelectionInfoMap{}
|
2024-03-22 07:15:51 +01:00
|
|
|
ctx.VisitDirectDepsWithTag(acDepTag, func(child Module) {
|
|
|
|
if m, ok := child.(*apexContributions); ok {
|
|
|
|
addContentsToProvider(&p, m)
|
|
|
|
} else {
|
|
|
|
ctx.ModuleErrorf("%s is not an apex_contributions module\n", child.Name())
|
|
|
|
}
|
|
|
|
})
|
2023-12-14 00:19:49 +01:00
|
|
|
SetProvider(ctx, PrebuiltSelectionInfoProvider, p)
|
2023-10-26 22:48:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// A provider containing metadata about whether source or prebuilt should be used
|
|
|
|
// This provider will be used in prebuilt_select mutator to redirect deps
|
2023-12-13 01:39:03 +01:00
|
|
|
var PrebuiltSelectionInfoProvider = blueprint.NewMutatorProvider[PrebuiltSelectionInfoMap]("prebuilt_select")
|
2023-10-26 22:48:02 +02:00
|
|
|
|
2024-01-03 19:57:03 +01:00
|
|
|
// Map of selected module names to a metadata object
|
|
|
|
// The metadata contains information about the api_domain of the selected module
|
2023-10-26 22:48:02 +02:00
|
|
|
type PrebuiltSelectionInfoMap map[string]PrebuiltSelectionInfo
|
|
|
|
|
|
|
|
// Add a new entry to the map with some validations
|
|
|
|
func (pm *PrebuiltSelectionInfoMap) Add(ctx BaseModuleContext, p *PrebuiltSelectionInfo) {
|
|
|
|
if p == nil {
|
|
|
|
return
|
|
|
|
}
|
2024-01-03 19:57:03 +01:00
|
|
|
(*pm)[p.selectedModuleName] = *p
|
2023-10-26 22:48:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type PrebuiltSelectionInfo struct {
|
|
|
|
// e.g. (libc|prebuilt_libc)
|
|
|
|
selectedModuleName string
|
|
|
|
// Name of the apex_contributions module
|
|
|
|
metadataModuleName string
|
|
|
|
// e.g. com.android.runtime
|
|
|
|
apiDomain string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Returns true if `name` is explicitly requested using one of the selected
|
|
|
|
// apex_contributions metadata modules.
|
2024-01-03 19:57:03 +01:00
|
|
|
func (p *PrebuiltSelectionInfoMap) IsSelected(name string) bool {
|
|
|
|
_, exists := (*p)[name]
|
|
|
|
return exists
|
2023-10-26 22:48:02 +02:00
|
|
|
}
|
|
|
|
|
2023-12-13 01:06:32 +01:00
|
|
|
// Return the list of soong modules selected for this api domain
|
|
|
|
// In the case of apexes, it is the canonical name of the apex on device (/apex/<apex_name>)
|
|
|
|
func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain string) []string {
|
|
|
|
selected := []string{}
|
|
|
|
for _, entry := range *p {
|
|
|
|
if entry.apiDomain == apiDomain {
|
|
|
|
selected = append(selected, entry.selectedModuleName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return selected
|
|
|
|
}
|
|
|
|
|
2023-10-26 22:48:02 +02:00
|
|
|
// This module type does not have any build actions.
|
|
|
|
func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
|
|
|
|
}
|