summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/Android.bp2
-rw-r--r--android/androidmk.go18
-rw-r--r--android/arch.go4
-rw-r--r--android/arch_test.go4
-rw-r--r--android/base_module_context.go2
-rw-r--r--android/config.go4
-rw-r--r--android/configurable_properties.go28
-rw-r--r--android/early_module_context.go2
-rw-r--r--android/gen_notice.go2
-rw-r--r--android/license_metadata.go6
-rw-r--r--android/logtags.go56
-rw-r--r--android/makevars.go3
-rw-r--r--android/module.go24
-rw-r--r--android/module_context.go21
-rw-r--r--android/mutator.go30
-rw-r--r--android/override_module.go108
-rw-r--r--android/packaging.go29
-rw-r--r--android/paths.go36
-rw-r--r--android/prebuilt.go6
-rw-r--r--android/prebuilt_test.go2
-rw-r--r--android/register.go3
-rw-r--r--android/sdk_version.go7
-rw-r--r--android/singleton.go2
-rw-r--r--android/testing.go18
-rw-r--r--android/variable.go10
25 files changed, 327 insertions, 100 deletions
diff --git a/android/Android.bp b/android/Android.bp
index f130d3aee..9ce8cdcd2 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -41,6 +41,7 @@ bootstrap_go_package {
"buildinfo_prop.go",
"config.go",
"test_config.go",
+ "configurable_properties.go",
"configured_jars.go",
"csuite_config.go",
"deapexer.go",
@@ -60,6 +61,7 @@ bootstrap_go_package {
"license_metadata.go",
"license_sdk_member.go",
"licenses.go",
+ "logtags.go",
"makevars.go",
"metrics.go",
"module.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index 07f7c58d0..66f42f97c 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -36,6 +36,7 @@ import (
"github.com/google/blueprint"
"github.com/google/blueprint/bootstrap"
"github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -541,6 +542,11 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint
a.SetPath("LOCAL_SOONG_INSTALLED_MODULE", base.katiInstalls[len(base.katiInstalls)-1].to)
a.SetString("LOCAL_SOONG_INSTALL_PAIRS", base.katiInstalls.BuiltInstalled())
a.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", base.katiSymlinks.InstallPaths().Paths())
+ } else {
+ // Soong may not have generated the install rule also when `no_full_install: true`.
+ // Mark this module as uninstallable in order to prevent Make from creating an
+ // install rule there.
+ a.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
}
if len(base.testData) > 0 {
@@ -849,7 +855,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *
mod blueprint.Module, provider AndroidMkDataProvider) error {
amod := mod.(Module).base()
- if shouldSkipAndroidMkProcessing(amod) {
+ if shouldSkipAndroidMkProcessing(ctx, amod) {
return nil
}
@@ -939,7 +945,7 @@ func WriteAndroidMkData(w io.Writer, data AndroidMkData) {
func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
mod blueprint.Module, provider AndroidMkEntriesProvider) error {
- if shouldSkipAndroidMkProcessing(mod.(Module).base()) {
+ if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
return nil
}
@@ -961,11 +967,11 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn
return nil
}
-func ShouldSkipAndroidMkProcessing(module Module) bool {
- return shouldSkipAndroidMkProcessing(module.base())
+func ShouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module Module) bool {
+ return shouldSkipAndroidMkProcessing(ctx, module.base())
}
-func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
+func shouldSkipAndroidMkProcessing(ctx ConfigAndErrorContext, module *ModuleBase) bool {
if !module.commonProperties.NamespaceExportedToMake {
// TODO(jeffrygaston) do we want to validate that there are no modules being
// exported to Kati that depend on this module?
@@ -984,7 +990,7 @@ func shouldSkipAndroidMkProcessing(module *ModuleBase) bool {
return true
}
- return !module.Enabled() ||
+ return !module.Enabled(ctx) ||
module.commonProperties.HideFromMake ||
// Make does not understand LinuxBionic
module.Os() == LinuxBionic ||
diff --git a/android/arch.go b/android/arch.go
index cd8882bbd..e0c6908c1 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -486,7 +486,7 @@ func osMutator(bpctx blueprint.BottomUpMutatorContext) {
// dependencies on OsType variants that are explicitly disabled in their
// properties. The CommonOS variant will still depend on disabled variants
// if they are disabled afterwards, e.g. in archMutator if
- if module.Enabled() {
+ if module.Enabled(mctx) {
mctx.AddInterVariantDependency(commonOsToOsSpecificVariantTag, commonOSVariant, module)
}
}
@@ -511,7 +511,7 @@ func GetOsSpecificVariantsOfCommonOSVariant(mctx BaseModuleContext) []Module {
var variants []Module
mctx.VisitDirectDeps(func(m Module) {
if mctx.OtherModuleDependencyTag(m) == commonOsToOsSpecificVariantTag {
- if m.Enabled() {
+ if m.Enabled(mctx) {
variants = append(variants, m)
}
}
diff --git a/android/arch_test.go b/android/arch_test.go
index 5021a67af..f0a58a90b 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -423,7 +423,7 @@ func TestArchMutator(t *testing.T) {
variants := ctx.ModuleVariantsForTests(name)
for _, variant := range variants {
m := ctx.ModuleForTests(name, variant)
- if m.Module().Enabled() {
+ if m.Module().Enabled(PanickingConfigAndErrorContext(ctx)) {
ret = append(ret, variant)
}
}
@@ -533,7 +533,7 @@ func TestArchMutatorNativeBridge(t *testing.T) {
variants := ctx.ModuleVariantsForTests(name)
for _, variant := range variants {
m := ctx.ModuleForTests(name, variant)
- if m.Module().Enabled() {
+ if m.Module().Enabled(PanickingConfigAndErrorContext(ctx)) {
ret = append(ret, variant)
}
}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index c5fe58578..296352057 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -325,7 +325,7 @@ func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag b
return nil
}
- if !aModule.Enabled() {
+ if !aModule.Enabled(b) {
if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
if b.Config().AllowMissingDependencies() {
b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
diff --git a/android/config.go b/android/config.go
index 3ea9d4dfa..f6711e61f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -818,12 +818,12 @@ func (c *config) GetenvWithDefault(key string, defaultValue string) string {
}
func (c *config) IsEnvTrue(key string) bool {
- value := c.Getenv(key)
+ value := strings.ToLower(c.Getenv(key))
return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true"
}
func (c *config) IsEnvFalse(key string) bool {
- value := c.Getenv(key)
+ value := strings.ToLower(c.Getenv(key))
return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
}
diff --git a/android/configurable_properties.go b/android/configurable_properties.go
new file mode 100644
index 000000000..dad42fa1d
--- /dev/null
+++ b/android/configurable_properties.go
@@ -0,0 +1,28 @@
+package android
+
+import "github.com/google/blueprint/proptools"
+
+// CreateSelectOsToBool is a utility function that makes it easy to create a
+// Configurable property value that maps from os to a bool. Use an empty string
+// to indicate a "default" case.
+func CreateSelectOsToBool(cases map[string]*bool) proptools.Configurable[bool] {
+ var resultCases []proptools.ConfigurableCase[bool]
+ for pattern, value := range cases {
+ if pattern == "" {
+ resultCases = append(resultCases, proptools.NewConfigurableCase(
+ []proptools.ConfigurablePattern{proptools.NewDefaultConfigurablePattern()},
+ value,
+ ))
+ } else {
+ resultCases = append(resultCases, proptools.NewConfigurableCase(
+ []proptools.ConfigurablePattern{proptools.NewStringConfigurablePattern(pattern)},
+ value,
+ ))
+ }
+ }
+
+ return proptools.NewConfigurable(
+ []proptools.ConfigurableCondition{proptools.NewConfigurableCondition("os", nil)},
+ resultCases,
+ )
+}
diff --git a/android/early_module_context.go b/android/early_module_context.go
index cf1b5fcab..23f4c90a2 100644
--- a/android/early_module_context.go
+++ b/android/early_module_context.go
@@ -173,5 +173,5 @@ func (e *earlyModuleContext) Namespace() *Namespace {
}
func (e *earlyModuleContext) OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{}) {
- e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args)
+ e.EarlyModuleContext.OtherModulePropertyErrorf(module, property, fmt, args...)
}
diff --git a/android/gen_notice.go b/android/gen_notice.go
index 1acc638e8..6815f6467 100644
--- a/android/gen_notice.go
+++ b/android/gen_notice.go
@@ -62,7 +62,7 @@ func (s *genNoticeBuildRules) GenerateBuildActions(ctx SingletonContext) {
if mod == nil {
continue
}
- if !mod.Enabled() { // don't depend on variants without build rules
+ if !mod.Enabled(ctx) { // don't depend on variants without build rules
continue
}
modules = append(modules, mod)
diff --git a/android/license_metadata.go b/android/license_metadata.go
index eabb1b170..3fea02909 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -36,7 +36,7 @@ var (
func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) {
base := ctx.Module().base()
- if !base.Enabled() {
+ if !base.Enabled(ctx) {
return
}
@@ -69,7 +69,7 @@ func buildLicenseMetadata(ctx ModuleContext, licenseMetadataFile WritablePath) {
if dep == nil {
return
}
- if !dep.Enabled() {
+ if !dep.Enabled(ctx) {
return
}
@@ -195,7 +195,7 @@ func isContainerFromFileExtensions(installPaths InstallPaths, builtPaths Paths)
for _, path := range paths {
switch path.Ext() {
- case ".zip", ".tar", ".tgz", ".tar.gz", ".img", ".srcszip", ".apex":
+ case ".zip", ".tar", ".tgz", ".tar.gz", ".img", ".srcszip", ".apex", ".capex":
return true
}
}
diff --git a/android/logtags.go b/android/logtags.go
new file mode 100644
index 000000000..d11cccf4f
--- /dev/null
+++ b/android/logtags.go
@@ -0,0 +1,56 @@
+// Copyright 2024 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 "github.com/google/blueprint"
+
+func init() {
+ RegisterParallelSingletonType("logtags", LogtagsSingleton)
+}
+
+type LogtagsInfo struct {
+ Logtags Paths
+}
+
+var LogtagsProviderKey = blueprint.NewProvider[*LogtagsInfo]()
+
+func LogtagsSingleton() Singleton {
+ return &logtagsSingleton{}
+}
+
+type logtagsSingleton struct{}
+
+func MergedLogtagsPath(ctx PathContext) OutputPath {
+ return PathForIntermediates(ctx, "all-event-log-tags.txt")
+}
+
+func (l *logtagsSingleton) GenerateBuildActions(ctx SingletonContext) {
+ var allLogtags Paths
+ ctx.VisitAllModules(func(module Module) {
+ if !module.ExportedToMake() {
+ return
+ }
+ if logtagsInfo, ok := SingletonModuleProvider(ctx, module, LogtagsProviderKey); ok {
+ allLogtags = append(allLogtags, logtagsInfo.Logtags...)
+ }
+ })
+
+ builder := NewRuleBuilder(pctx, ctx)
+ builder.Command().
+ BuiltTool("merge-event-log-tags").
+ FlagWithOutput("-o ", MergedLogtagsPath(ctx)).
+ Inputs(SortedUniquePaths(allLogtags))
+ builder.Build("all-event-log-tags.txt", "merge logtags")
+}
diff --git a/android/makevars.go b/android/makevars.go
index 4039e7edb..e73645fdc 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -98,6 +98,7 @@ type MakeVarsContext interface {
BlueprintFile(module blueprint.Module) string
ModuleErrorf(module blueprint.Module, format string, args ...interface{})
+ OtherModulePropertyErrorf(module Module, property, format string, args ...interface{})
Errorf(format string, args ...interface{})
VisitAllModules(visit func(Module))
@@ -265,7 +266,7 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
}
ctx.VisitAllModules(func(m Module) {
- if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled() {
+ if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) {
mctx := &makeVarsContext{
SingletonContext: ctx,
}
diff --git a/android/module.go b/android/module.go
index effca0346..40a591007 100644
--- a/android/module.go
+++ b/android/module.go
@@ -60,7 +60,7 @@ type Module interface {
base() *ModuleBase
Disable()
- Enabled() bool
+ Enabled(ctx ConfigAndErrorContext) bool
Target() Target
MultiTargets() []Target
@@ -287,7 +287,7 @@ type commonProperties struct {
// but are not usually required (e.g. superceded by a prebuilt) should not be
// disabled as that will prevent them from being built by the checkbuild target
// and so prevent early detection of changes that have broken those modules.
- Enabled *bool `android:"arch_variant"`
+ Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
// Controls the visibility of this module to other modules. Allowable values are one or more of
// these formats:
@@ -484,6 +484,11 @@ type commonProperties struct {
// Set by osMutator.
CommonOSVariant bool `blueprint:"mutated"`
+ // When set to true, this module is not installed to the full install path (ex: under
+ // out/target/product/<name>/<partition>). It can be installed only to the packaging
+ // modules like android_filesystem.
+ No_full_install *bool
+
// When HideFromMake is set to true, no entry for this variant will be emitted in the
// generated Android.mk file.
HideFromMake bool `blueprint:"mutated"`
@@ -1392,14 +1397,11 @@ func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
return partition
}
-func (m *ModuleBase) Enabled() bool {
+func (m *ModuleBase) Enabled(ctx ConfigAndErrorContext) bool {
if m.commonProperties.ForcedDisabled {
return false
}
- if m.commonProperties.Enabled == nil {
- return !m.Os().DefaultDisabled
- }
- return *m.commonProperties.Enabled
+ return m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
}
func (m *ModuleBase) Disable() {
@@ -1643,7 +1645,7 @@ func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
// for the current build target.
- if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(a) {
+ if !ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a) {
allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
}
})
@@ -1835,7 +1837,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
checkDistProperties(ctx, fmt.Sprintf("dists[%d]", i), &m.distProperties.Dists[i])
}
- if m.Enabled() {
+ if m.Enabled(ctx) {
// ensure all direct android.Module deps are enabled
ctx.VisitDirectDepsBlueprint(func(bm blueprint.Module) {
if m, ok := bm.(Module); ok {
@@ -2136,7 +2138,7 @@ func (m *ModuleBase) ConfigurableEvaluator(ctx ConfigAndErrorContext) proptools.
}
func (e configurationEvalutor) PropertyErrorf(property string, fmt string, args ...interface{}) {
- e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args)
+ e.ctx.OtherModulePropertyErrorf(e.m, property, fmt, args...)
}
func (e configurationEvalutor) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
@@ -2535,7 +2537,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
}
osDeps := map[osAndCross]Paths{}
ctx.VisitAllModules(func(module Module) {
- if module.Enabled() {
+ if module.Enabled(ctx) {
key := osAndCross{os: module.Target().Os, hostCross: module.Target().HostCross}
osDeps[key] = append(osDeps[key], module.base().checkbuildFiles...)
}
diff --git a/android/module_context.go b/android/module_context.go
index dea22bab4..605d3baeb 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -444,6 +444,21 @@ func (m *moduleContext) skipInstall() bool {
return false
}
+// Tells whether this module is installed to the full install path (ex:
+// out/target/product/<name>/<partition>) or not. If this returns false, the install build rule is
+// not created and this module can only be installed to packaging modules like android_filesystem.
+func (m *moduleContext) requiresFullInstall() bool {
+ if m.skipInstall() {
+ return false
+ }
+
+ if proptools.Bool(m.module.base().commonProperties.No_full_install) {
+ return false
+ }
+
+ return true
+}
+
func (m *moduleContext) InstallFile(installPath InstallPath, name string, srcPath Path,
deps ...InstallPath) InstallPath {
return m.installFile(installPath, name, srcPath, deps, false, true, nil)
@@ -490,7 +505,7 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
m.module.base().hooks.runInstallHooks(m, srcPath, fullInstallPath, false)
}
- if !m.skipInstall() {
+ if m.requiresFullInstall() {
deps = append(deps, InstallPaths(m.module.base().installFilesDepSet.ToList())...)
deps = append(deps, m.module.base().installedInitRcPaths...)
deps = append(deps, m.module.base().installedVintfFragmentsPaths...)
@@ -563,7 +578,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src
if err != nil {
panic(fmt.Sprintf("Unable to generate symlink between %q and %q: %s", fullInstallPath.Base(), srcPath.Base(), err))
}
- if !m.skipInstall() {
+ if m.requiresFullInstall() {
if m.Config().KatiEnabled() {
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
@@ -612,7 +627,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str
fullInstallPath := installPath.Join(m, name)
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
- if !m.skipInstall() {
+ if m.requiresFullInstall() {
if m.Config().KatiEnabled() {
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
// makefile instead of directly to the ninja file so that main.mk can add the
diff --git a/android/mutator.go b/android/mutator.go
index 75ba65048..440b9060f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -293,15 +293,14 @@ type BottomUpMutatorContext interface {
// WalkDeps, etc.
AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
- // ReplaceDependencies replaces all dependencies on the identical variant of the module with the
- // specified name with the current variant of this module. Replacements don't take effect until
- // after the mutator pass is finished.
+ // ReplaceDependencies finds all the variants of the module with the specified name, then
+ // replaces all dependencies onto those variants with the current variant of this module.
+ // Replacements don't take effect until after the mutator pass is finished.
ReplaceDependencies(string)
- // ReplaceDependencies replaces all dependencies on the identical variant of the module with the
- // specified name with the current variant of this module as long as the supplied predicate returns
- // true.
- //
+ // ReplaceDependenciesIf finds all the variants of the module with the specified name, then
+ // replaces all dependencies onto those variants with the current variant of this module
+ // as long as the supplied predicate returns true.
// Replacements don't take effect until after the mutator pass is finished.
ReplaceDependenciesIf(string, blueprint.ReplaceDependencyPredicate)
@@ -595,11 +594,16 @@ func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTr
func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext, variation string) {
if am, ok := ctx.Module().(Module); ok {
+ if variation != "" {
+ // TODO: this should really be checking whether the TransitionMutator affected this module, not
+ // the empty variant, but TransitionMutator has no concept of skipping a module.
+ base := am.base()
+ base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
+ base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
+ }
+
mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
defer bottomUpMutatorContextPool.Put(mctx)
- base := am.base()
- base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
- base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
a.mutator.Mutate(mctx, variation)
}
}
@@ -674,13 +678,11 @@ func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
// on component modules to be added so that they can depend directly on a prebuilt
// module.
func componentDepsMutator(ctx BottomUpMutatorContext) {
- if m := ctx.Module(); m.Enabled() {
- m.ComponentDepsMutator(ctx)
- }
+ ctx.Module().ComponentDepsMutator(ctx)
}
func depsMutator(ctx BottomUpMutatorContext) {
- if m := ctx.Module(); m.Enabled() {
+ if m := ctx.Module(); m.Enabled(ctx) {
m.base().baseDepsMutator(ctx)
m.DepsMutator(ctx)
}
diff --git a/android/override_module.go b/android/override_module.go
index 1341f537c..55f384f1f 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -28,6 +28,7 @@ package android
// module based on it.
import (
+ "fmt"
"sort"
"sync"
@@ -120,7 +121,7 @@ type OverridableModule interface {
addOverride(o OverrideModule)
getOverrides() []OverrideModule
- override(ctx BaseModuleContext, m Module, o OverrideModule)
+ override(ctx BaseModuleContext, bm OverridableModule, o OverrideModule)
GetOverriddenBy() string
GetOverriddenByModuleDir() string
@@ -191,15 +192,14 @@ func (b *OverridableModuleBase) setOverridesProperty(overridesProperty *[]string
}
// Overrides a base module with the given OverrideModule.
-func (b *OverridableModuleBase) override(ctx BaseModuleContext, m Module, o OverrideModule) {
-
+func (b *OverridableModuleBase) override(ctx BaseModuleContext, bm OverridableModule, o OverrideModule) {
for _, p := range b.overridableProperties {
for _, op := range o.getOverridingProperties() {
if proptools.TypeEqual(p, op) {
err := proptools.ExtendProperties(p, op, nil, proptools.OrderReplace)
if err != nil {
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
- ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
+ ctx.OtherModulePropertyErrorf(bm, propertyErr.Property, "%s", propertyErr.Err.Error())
} else {
panic(err)
}
@@ -210,7 +210,7 @@ func (b *OverridableModuleBase) override(ctx BaseModuleContext, m Module, o Over
// Adds the base module to the overrides property, if exists, of the overriding module. See the
// comment on OverridableModuleBase.overridesProperty for details.
if b.overridesProperty != nil {
- *b.overridesProperty = append(*b.overridesProperty, ctx.ModuleName())
+ *b.overridesProperty = append(*b.overridesProperty, ctx.OtherModuleName(bm))
}
b.overridableModuleProperties.OverriddenBy = o.Name()
b.overridableModuleProperties.OverriddenByModuleDir = o.ModuleDir()
@@ -235,7 +235,7 @@ func (b *OverridableModuleBase) OverridablePropertiesDepsMutator(ctx BottomUpMut
// to keep them in this order and not put any order mutators between them.
func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) {
ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel()
- ctx.BottomUp("perform_override", performOverrideMutator).Parallel()
+ ctx.Transition("override", &overrideTransitionMutator{})
// overridableModuleDepsMutator calls OverridablePropertiesDepsMutator so that overridable modules can
// add deps from overridable properties.
ctx.BottomUp("overridable_deps", overridableModuleDepsMutator).Parallel()
@@ -262,18 +262,6 @@ func overrideModuleDepsMutator(ctx BottomUpMutatorContext) {
ctx.PropertyErrorf("base", "%q is not a valid module name", base)
return
}
- // See if there's a prebuilt module that overrides this override module with prefer flag,
- // in which case we call HideFromMake on the corresponding variant later.
- ctx.VisitDirectDepsWithTag(PrebuiltDepTag, func(dep Module) {
- prebuilt := GetEmbeddedPrebuilt(dep)
- if prebuilt == nil {
- panic("PrebuiltDepTag leads to a non-prebuilt module " + dep.Name())
- }
- if prebuilt.UsePrebuilt() {
- module.setOverriddenByPrebuilt(dep)
- return
- }
- })
baseModule := ctx.AddDependency(ctx.Module(), overrideBaseDepTag, *module.getOverrideModuleProperties().Base)[0]
if o, ok := baseModule.(OverridableModule); ok {
overrideModule := ctx.Module().(OverrideModule)
@@ -285,11 +273,13 @@ func overrideModuleDepsMutator(ctx BottomUpMutatorContext) {
// Now, goes through all overridable modules, finds all modules overriding them, creates a local
// variant for each of them, and performs the actual overriding operation by calling override().
-func performOverrideMutator(ctx BottomUpMutatorContext) {
+type overrideTransitionMutator struct{}
+
+func (overrideTransitionMutator) Split(ctx BaseModuleContext) []string {
if b, ok := ctx.Module().(OverridableModule); ok {
overrides := b.getOverrides()
if len(overrides) == 0 {
- return
+ return []string{""}
}
variants := make([]string, len(overrides)+1)
// The first variant is for the original, non-overridden, base module.
@@ -297,32 +287,74 @@ func performOverrideMutator(ctx BottomUpMutatorContext) {
for i, o := range overrides {
variants[i+1] = o.(Module).Name()
}
- mods := ctx.CreateLocalVariations(variants...)
- // Make the original variation the default one to depend on if no other override module variant
- // is specified.
- ctx.AliasVariation(variants[0])
- for i, o := range overrides {
- mods[i+1].(OverridableModule).override(ctx, mods[i+1], o)
- if prebuilt := o.getOverriddenByPrebuilt(); prebuilt != nil {
- // The overriding module itself, too, is overridden by a prebuilt.
- // Perform the same check for replacement
- checkInvariantsForSourceAndPrebuilt(ctx, mods[i+1], prebuilt)
- // Copy the flag and hide it in make
- mods[i+1].ReplacedByPrebuilt()
- }
- }
+ return variants
} else if o, ok := ctx.Module().(OverrideModule); ok {
// Create a variant of the overriding module with its own name. This matches the above local
// variant name rule for overridden modules, and thus allows ReplaceDependencies to match the
// two.
- ctx.CreateLocalVariations(o.Name())
- // To allow dependencies to be added without having to know the above variation.
- ctx.AliasVariation(o.Name())
+ return []string{o.Name()}
+ }
+
+ return []string{""}
+}
+
+func (overrideTransitionMutator) OutgoingTransition(ctx OutgoingTransitionContext, sourceVariation string) string {
+ if o, ok := ctx.Module().(OverrideModule); ok {
+ if ctx.DepTag() == overrideBaseDepTag {
+ return o.Name()
+ }
+ }
+
+ // Variations are always local and shouldn't affect the variant used for dependencies
+ return ""
+}
+
+func (overrideTransitionMutator) IncomingTransition(ctx IncomingTransitionContext, incomingVariation string) string {
+ if _, ok := ctx.Module().(OverridableModule); ok {
+ return incomingVariation
+ } else if o, ok := ctx.Module().(OverrideModule); ok {
+ // To allow dependencies to be added without having to know the variation.
+ return o.Name()
+ }
+
+ return ""
+}
+
+func (overrideTransitionMutator) Mutate(ctx BottomUpMutatorContext, variation string) {
+ if o, ok := ctx.Module().(OverrideModule); ok {
+ overridableDeps := ctx.GetDirectDepsWithTag(overrideBaseDepTag)
+ if len(overridableDeps) > 1 {
+ panic(fmt.Errorf("expected a single dependency with overrideBaseDepTag, found %q", overridableDeps))
+ } else if len(overridableDeps) == 1 {
+ b := overridableDeps[0].(OverridableModule)
+ b.override(ctx, b, o)
+
+ checkPrebuiltReplacesOverride(ctx, b)
+ }
+ }
+}
+
+func checkPrebuiltReplacesOverride(ctx BottomUpMutatorContext, b OverridableModule) {
+ // See if there's a prebuilt module that overrides this override module with prefer flag,
+ // in which case we call HideFromMake on the corresponding variant later.
+ prebuiltDeps := ctx.GetDirectDepsWithTag(PrebuiltDepTag)
+ for _, prebuiltDep := range prebuiltDeps {
+ prebuilt := GetEmbeddedPrebuilt(prebuiltDep)
+ if prebuilt == nil {
+ panic("PrebuiltDepTag leads to a non-prebuilt module " + prebuiltDep.Name())
+ }
+ if prebuilt.UsePrebuilt() {
+ // The overriding module itself, too, is overridden by a prebuilt.
+ // Perform the same check for replacement
+ checkInvariantsForSourceAndPrebuilt(ctx, b, prebuiltDep)
+ // Copy the flag and hide it in make
+ b.ReplacedByPrebuilt()
+ }
}
}
func overridableModuleDepsMutator(ctx BottomUpMutatorContext) {
- if b, ok := ctx.Module().(OverridableModule); ok && b.Enabled() {
+ if b, ok := ctx.Module().(OverridableModule); ok && b.Enabled(ctx) {
b.OverridablePropertiesDepsMutator(ctx)
}
}
diff --git a/android/packaging.go b/android/packaging.go
index 66772183c..fe61da1e9 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -50,6 +50,25 @@ type PackagingSpec struct {
skipInstall bool
}
+func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
+ if other == nil {
+ return false
+ }
+ if p.relPathInPackage != other.relPathInPackage {
+ return false
+ }
+ if p.srcPath != other.srcPath || p.symlinkTarget != other.symlinkTarget {
+ return false
+ }
+ if p.executable != other.executable {
+ return false
+ }
+ if p.partition != other.partition {
+ return false
+ }
+ return true
+}
+
// Get file name of installed package
func (p *PackagingSpec) FileName() string {
if p.relPathInPackage != "" {
@@ -243,9 +262,15 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
continue
}
}
- if _, ok := m[ps.relPathInPackage]; !ok {
- m[ps.relPathInPackage] = ps
+ dstPath := ps.relPathInPackage
+ if existingPs, ok := m[dstPath]; ok {
+ if !existingPs.Equals(&ps) {
+ ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+ }
+ continue
}
+
+ m[dstPath] = ps
}
})
return m
diff --git a/android/paths.go b/android/paths.go
index 2b33f67ce..8d92aa4a9 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -60,6 +60,7 @@ type EarlyModulePathContext interface {
ModuleDir() string
ModuleErrorf(fmt string, args ...interface{})
+ OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{})
}
var _ EarlyModulePathContext = ModuleContext(nil)
@@ -277,6 +278,7 @@ type WritablePath interface {
type genPathProvider interface {
genPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleGenPath
+ genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath
}
type objPathProvider interface {
objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath
@@ -295,6 +297,16 @@ func GenPathWithExt(ctx ModuleOutPathContext, subdir string, p Path, ext string)
return PathForModuleGen(ctx)
}
+// GenPathWithExtAndTrimExt derives a new file path in ctx's generated sources directory
+// from the current path, but with the new extension and trim the suffix.
+func GenPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir string, p Path, ext string, trimExt string) ModuleGenPath {
+ if path, ok := p.(genPathProvider); ok {
+ return path.genPathWithExtAndTrimExt(ctx, subdir, ext, trimExt)
+ }
+ ReportPathErrorf(ctx, "Tried to create generated file from unsupported path: %s(%s)", reflect.TypeOf(p).Name(), p)
+ return PathForModuleGen(ctx)
+}
+
// ObjPathWithExt derives a new file path in ctx's object directory from the
// current path, but with the new extension.
func ObjPathWithExt(ctx ModuleOutPathContext, subdir string, p Path, ext string) ModuleObjPath {
@@ -550,7 +562,7 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag
if module == nil {
return nil, missingDependencyError{[]string{moduleName}}
}
- if aModule, ok := module.(Module); ok && !aModule.Enabled() {
+ if aModule, ok := module.(Module); ok && !aModule.Enabled(ctx) {
return nil, missingDependencyError{[]string{moduleName}}
}
if outProducer, ok := module.(OutputFileProducer); ok {
@@ -1507,6 +1519,17 @@ func (p SourcePath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext string)
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
+func (p SourcePath) genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath {
+ // If Trim_extension being set, force append Output_extension without replace original extension.
+ if trimExt != "" {
+ if ext != "" {
+ return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt)+"."+ext)
+ }
+ return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt))
+ }
+ return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
func (p SourcePath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
@@ -1594,6 +1617,17 @@ func (p ModuleGenPath) genPathWithExt(ctx ModuleOutPathContext, subdir, ext stri
return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
+func (p ModuleGenPath) genPathWithExtAndTrimExt(ctx ModuleOutPathContext, subdir, ext string, trimExt string) ModuleGenPath {
+ // If Trim_extension being set, force append Output_extension without replace original extension.
+ if trimExt != "" {
+ if ext != "" {
+ return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt)+"."+ext)
+ }
+ return PathForModuleGen(ctx, subdir, strings.TrimSuffix(p.path, trimExt))
+ }
+ return PathForModuleGen(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
+}
+
func (p ModuleGenPath) objPathWithExt(ctx ModuleOutPathContext, subdir, ext string) ModuleObjPath {
return PathForModuleObj(ctx, subdir, pathtools.ReplaceExtension(p.path, ext))
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 2b7b55b5d..1f9b33111 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -275,7 +275,7 @@ func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface
srcPropertyName := proptools.PropertyNameForField(srcField)
srcsSupplier := func(ctx BaseModuleContext, _ Module) []string {
- if !module.Enabled() {
+ if !module.Enabled(ctx) {
return nil
}
value := srcPropsValue.FieldByIndex(srcFieldIndex)
@@ -425,7 +425,7 @@ func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
m := ctx.Module()
// If this module is a prebuilt, is enabled and has not been renamed to source then add a
// dependency onto the source if it is present.
- if p := GetEmbeddedPrebuilt(m); p != nil && m.Enabled() && !p.properties.PrebuiltRenamedToSource {
+ if p := GetEmbeddedPrebuilt(m); p != nil && m.Enabled(ctx) && !p.properties.PrebuiltRenamedToSource {
bmn, _ := m.(baseModuleName)
name := bmn.BaseModuleName()
if ctx.OtherModuleReverseDependencyVariantExists(name) {
@@ -702,7 +702,7 @@ func (p *Prebuilt) usePrebuilt(ctx BaseMutatorContext, source Module, prebuilt M
}
// If source is not available or is disabled then always use the prebuilt.
- if source == nil || !source.Enabled() {
+ if source == nil || !source.Enabled(ctx) {
return true
}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 575b9266c..d775ac356 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -351,7 +351,7 @@ func TestPrebuilts(t *testing.T) {
}
})
- moduleIsDisabled := !foo.Module().Enabled()
+ moduleIsDisabled := !foo.Module().Enabled(PanickingConfigAndErrorContext(result.TestContext))
deps := foo.Module().(*sourceModule).deps
if moduleIsDisabled {
if len(deps) > 0 {
diff --git a/android/register.go b/android/register.go
index d00c15fd0..aeb3b4c1b 100644
--- a/android/register.go
+++ b/android/register.go
@@ -16,8 +16,9 @@ package android
import (
"fmt"
- "github.com/google/blueprint"
"reflect"
+
+ "github.com/google/blueprint"
)
// A sortable component is one whose registration order affects the order in which it is executed
diff --git a/android/sdk_version.go b/android/sdk_version.go
index b2ff960ee..01b55d0da 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -40,9 +40,15 @@ type SdkContext interface {
// SdkKind represents a particular category of an SDK spec like public, system, test, etc.
type SdkKind int
+// These are generally ordered from the narrower sdk version to the wider sdk version,
+// but not all entries have a strict subset/superset relationship.
+// For example, SdkTest and SdkModule do not have a strict subset/superset relationship but both
+// are supersets of SdkSystem.
+// The general trend should be kept when an additional sdk kind is added.
const (
SdkInvalid SdkKind = iota
SdkNone
+ SdkToolchain // API surface provided by ART to compile other API domains
SdkCore
SdkCorePlatform
SdkIntraCore // API surface provided by one core module to another
@@ -53,7 +59,6 @@ const (
SdkModule
SdkSystemServer
SdkPrivate
- SdkToolchain // API surface provided by ART to compile other API domains
)
// String returns the string representation of this SdkKind
diff --git a/android/singleton.go b/android/singleton.go
index 76df1ebba..d364384e2 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -284,5 +284,5 @@ func (s *singletonContextAdaptor) moduleProvider(module blueprint.Module, provid
}
func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, property string, format string, args ...interface{}) {
- s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args)
+ s.blueprintSingletonContext().OtherModulePropertyErrorf(module, property, format, args...)
}
diff --git a/android/testing.go b/android/testing.go
index 7b4411e2f..c692c7295 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -1287,3 +1287,21 @@ func EnsureListContainsSuffix(t *testing.T, result []string, expected string) {
t.Errorf("%q is not found in %v", expected, result)
}
}
+
+type panickingConfigAndErrorContext struct {
+ ctx *TestContext
+}
+
+func (ctx *panickingConfigAndErrorContext) OtherModulePropertyErrorf(module Module, property, fmt string, args ...interface{}) {
+ panic(ctx.ctx.PropertyErrorf(module, property, fmt, args...).Error())
+}
+
+func (ctx *panickingConfigAndErrorContext) Config() Config {
+ return ctx.ctx.Config()
+}
+
+func PanickingConfigAndErrorContext(ctx *TestContext) ConfigAndErrorContext {
+ return &panickingConfigAndErrorContext{
+ ctx: ctx,
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index 599f88e3f..419bd61de 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -58,16 +58,16 @@ type variableProperties struct {
// unbundled_build is a catch-all property to annotate modules that don't build in one or
// more unbundled branches, usually due to dependencies missing from the manifest.
Unbundled_build struct {
- Enabled *bool `android:"arch_variant"`
+ Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
} `android:"arch_variant"`
// similar to `Unbundled_build`, but `Always_use_prebuilt_sdks` means that it uses prebuilt
// sdk specifically.
Always_use_prebuilt_sdks struct {
- Enabled *bool `android:"arch_variant"`
+ Enabled proptools.Configurable[bool] `android:"arch_variant,replace_instead_of_append"`
} `android:"arch_variant"`
- Malloc_not_svelte struct {
+ Malloc_low_memory struct {
Cflags []string `android:"arch_variant"`
Shared_libs []string `android:"arch_variant"`
Whole_static_libs []string `android:"arch_variant"`
@@ -278,7 +278,7 @@ type ProductVariables struct {
Unbundled_build_image *bool `json:",omitempty"`
Always_use_prebuilt_sdks *bool `json:",omitempty"`
Skip_boot_jars_check *bool `json:",omitempty"`
- Malloc_not_svelte *bool `json:",omitempty"`
+ Malloc_low_memory *bool `json:",omitempty"`
Malloc_zero_contents *bool `json:",omitempty"`
Malloc_pattern_fill_contents *bool `json:",omitempty"`
Safestack *bool `json:",omitempty"`
@@ -612,7 +612,7 @@ func (v *ProductVariables) SetDefaultConfig() {
AAPTCharacteristics: stringPtr("nosdcard"),
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
- Malloc_not_svelte: boolPtr(true),
+ Malloc_low_memory: boolPtr(false),
Malloc_zero_contents: boolPtr(true),
Malloc_pattern_fill_contents: boolPtr(false),
Safestack: boolPtr(false),