Merge "Convert cc modules to use AndroidMkInfoProvider." into main
diff --git a/Android.bp b/Android.bp
index 34f9bf0..bd4b40f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -161,10 +161,11 @@
name: "system-build.prop",
stem: "build.prop",
product_config: ":product_config",
- // Currently, only microdroid and cf system image can refer to system-build.prop
+ // Currently, only microdroid, Ravenwood, and cf system image can refer to system-build.prop
visibility: [
"//build/make/target/product/generic",
"//packages/modules/Virtualization/build/microdroid",
+ "//frameworks/base/ravenwood",
],
}
diff --git a/aconfig/codegen/aconfig_declarations_group.go b/aconfig/codegen/aconfig_declarations_group.go
index 13daf47..6811d06 100644
--- a/aconfig/codegen/aconfig_declarations_group.go
+++ b/aconfig/codegen/aconfig_declarations_group.go
@@ -59,7 +59,7 @@
func AconfigDeclarationsGroupFactory() android.Module {
module := &AconfigDeclarationsGroup{}
module.AddProperties(&module.properties)
- android.InitAndroidModule(module)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
return module
}
diff --git a/aconfig/codegen/aconfig_declarations_group_test.go b/aconfig/codegen/aconfig_declarations_group_test.go
index c69d21f..ef954ce 100644
--- a/aconfig/codegen/aconfig_declarations_group_test.go
+++ b/aconfig/codegen/aconfig_declarations_group_test.go
@@ -67,7 +67,7 @@
`)
// Check if aconfig_declarations_group module depends on the aconfig_library modules
- java.CheckModuleDependencies(t, result.TestContext, "my_group", "", []string{
+ java.CheckModuleDependencies(t, result.TestContext, "my_group", "android_common", []string{
`bar-java`,
`foo-java`,
})
diff --git a/android/Android.bp b/android/Android.bp
index eb8c64d..3b54326 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -52,6 +52,7 @@
"defs.go",
"depset_generic.go",
"deptag.go",
+ "dirgroup.go",
"early_module_context.go",
"expand.go",
"filegroup.go",
@@ -89,7 +90,6 @@
"prebuilt.go",
"prebuilt_build_tool.go",
"product_config.go",
- "product_config_to_bp.go",
"proto.go",
"provider.go",
"raw_files.go",
diff --git a/android/defaults.go b/android/defaults.go
index 8fe2879..510ebe0 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -273,8 +273,8 @@
}
func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
- ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
- ctx.BottomUp("defaults", defaultsMutator).Parallel().UsesCreateModule()
+ ctx.BottomUp("defaults_deps", defaultsDepsMutator)
+ ctx.BottomUp("defaults", defaultsMutator).UsesCreateModule()
}
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
diff --git a/android/dirgroup.go b/android/dirgroup.go
new file mode 100644
index 0000000..20c4d13
--- /dev/null
+++ b/android/dirgroup.go
@@ -0,0 +1,63 @@
+// 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"
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ RegisterDirgroupBuildComponents(InitRegistrationContext)
+}
+
+func RegisterDirgroupBuildComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("dirgroup", DirGroupFactory)
+}
+
+type dirGroupProperties struct {
+ // dirs lists directories that will be included in this dirgroup
+ Dirs proptools.Configurable[[]string] `android:"path"`
+}
+
+type dirGroup struct {
+ ModuleBase
+ DefaultableModuleBase
+ properties dirGroupProperties
+}
+
+type DirInfo struct {
+ // TODO(b/358302178): Use DirectoryPaths instead of Paths
+ Dirs Paths
+}
+
+var DirProvider = blueprint.NewProvider[DirInfo]()
+
+// dirgroup contains a list of dirs that are referenced by other modules
+// properties using the syntax ":<name>". dirgroup are also be used to export
+// dirs across package boundaries. Currently the only allowed usage is genrule's
+// dir_srcs property.
+func DirGroupFactory() Module {
+ module := &dirGroup{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ InitDefaultableModule(module)
+ return module
+}
+
+func (fg *dirGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
+ dirs := DirectoryPathsForModuleSrc(ctx, fg.properties.Dirs.GetOrDefault(ctx, nil))
+ SetProvider(ctx, DirProvider, DirInfo{Dirs: dirs})
+}
diff --git a/android/licenses.go b/android/licenses.go
index be1eede..949d678 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -106,19 +106,19 @@
//
// This goes before defaults expansion so the defaults can pick up the package default.
func RegisterLicensesPackageMapper(ctx RegisterMutatorsContext) {
- ctx.BottomUp("licensesPackageMapper", licensesPackageMapper).Parallel()
+ ctx.BottomUp("licensesPackageMapper", licensesPackageMapper)
}
// Registers the function that gathers the license dependencies for each module.
//
// This goes after defaults expansion so that it can pick up default licenses and before visibility enforcement.
func RegisterLicensesPropertyGatherer(ctx RegisterMutatorsContext) {
- ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer).Parallel()
+ ctx.BottomUp("licensesPropertyGatherer", licensesPropertyGatherer)
}
// Registers the function that verifies the licenses and license_kinds dependency types for each module.
func RegisterLicensesDependencyChecker(ctx RegisterMutatorsContext) {
- ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker).Parallel()
+ ctx.BottomUp("licensesPropertyChecker", licensesDependencyChecker)
}
// Maps each package to its default applicable licenses.
diff --git a/android/module.go b/android/module.go
index 1979536..ea59b3b 100644
--- a/android/module.go
+++ b/android/module.go
@@ -113,6 +113,10 @@
VintfFragmentModuleNames(ctx ConfigurableEvaluatorContext) []string
ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
+
+ // The usage of this method is experimental and should not be used outside of fsgen package.
+ // This will be removed once product packaging migration to Soong is complete.
+ DecodeMultilib(ctx ConfigContext) (string, string)
}
// Qualified id for a module
@@ -1073,6 +1077,11 @@
modPartition := mod.PartitionTag(deviceConfig)
for _, vintf := range vintfModules {
+ if vintf == nil {
+ // TODO(b/372091092): Remove this. Having it gives us missing dependency errors instead
+ // of nil pointer dereference errors, but we should resolve the missing dependencies.
+ continue
+ }
if vintfModule, ok := vintf.(*vintfFragmentModule); ok {
vintfPartition := vintfModule.PartitionTag(deviceConfig)
if modPartition != vintfPartition {
@@ -2288,6 +2297,10 @@
return proptools.Bool(m.commonProperties.Native_bridge_supported)
}
+func (m *ModuleBase) DecodeMultilib(ctx ConfigContext) (string, string) {
+ return decodeMultilib(ctx, m)
+}
+
type ConfigContext interface {
Config() Config
}
diff --git a/android/module_proxy.go b/android/module_proxy.go
index bc5090e..0f552dd 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -201,3 +201,7 @@
func (m ModuleProxy) ConfigurableEvaluator(ctx ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator {
panic("method is not implemented on ModuleProxy")
}
+
+func (m ModuleProxy) DecodeMultilib(ctx ConfigContext) (string, string) {
+ panic("method is not implemented on ModuleProxy")
+}
diff --git a/android/mutator.go b/android/mutator.go
index 0da3ec7..6bd2e60 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -211,10 +211,7 @@
// AddDependency adds a dependency to the given module. It returns a slice of modules for each
// dependency (some entries may be nil).
//
- // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
- // new dependencies have had the current mutator called on them. If the mutator is not
- // parallel this method does not affect the ordering of the current mutator pass, but will
- // be ordered correctly for all future mutator passes.
+ // This method will pause until the new dependencies have had the current mutator called on them.
AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
// AddReverseDependency adds a dependency from the destination to the given module.
@@ -230,10 +227,7 @@
// each dependency (some entries may be nil). A variant of the dependency must exist that matches
// all the non-local variations of the current module, plus the variations argument.
//
- // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
- // new dependencies have had the current mutator called on them. If the mutator is not
- // parallel this method does not affect the ordering of the current mutator pass, but will
- // be ordered correctly for all future mutator passes.
+ // This method will pause until the new dependencies have had the current mutator called on them.
AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag, names ...string) []blueprint.Module
// AddReverseVariationDependency adds a dependency from the named module to the current
@@ -256,10 +250,7 @@
// Unlike AddVariationDependencies, the variations of the current module are ignored - the
// dependency only needs to match the supplied variations.
//
- // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
- // new dependencies have had the current mutator called on them. If the mutator is not
- // parallel this method does not affect the ordering of the current mutator pass, but will
- // be ordered correctly for all future mutator passes.
+ // This method will pause until the new dependencies have had the current mutator called on them.
AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) []blueprint.Module
// ReplaceDependencies finds all the variants of the module with the specified name, then
@@ -628,9 +619,6 @@
}
// Forward booleans set on the MutatorHandle to the blueprint.MutatorHandle.
- if mutator.parallel {
- handle.Parallel()
- }
if mutator.usesRename {
handle.UsesRename()
}
@@ -655,6 +643,7 @@
// Parallel sets the mutator to visit modules in parallel while maintaining ordering. Calling any
// method on the mutator context is thread-safe, but the mutator must handle synchronization
// for any modifications to global state or any modules outside the one it was invoked on.
+ // Deprecated: all Mutators are parallel by default.
Parallel() MutatorHandle
// UsesRename marks the mutator as using the BottomUpMutatorContext.Rename method, which prevents
@@ -683,7 +672,6 @@
}
func (mutator *mutator) Parallel() MutatorHandle {
- mutator.parallel = true
return mutator
}
@@ -718,7 +706,7 @@
}
func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("component-deps", componentDepsMutator).Parallel()
+ ctx.BottomUp("component-deps", componentDepsMutator)
}
// A special mutator that runs just prior to the deps mutator to allow the dependencies
@@ -736,7 +724,7 @@
}
func registerDepsMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("deps", depsMutator).Parallel().UsesReverseDependencies()
+ ctx.BottomUp("deps", depsMutator).UsesReverseDependencies()
}
// android.topDownMutatorContext either has to embed blueprint.TopDownMutatorContext, in which case every method that
diff --git a/android/mutator_test.go b/android/mutator_test.go
index 33fca9e..1d5f890 100644
--- a/android/mutator_test.go
+++ b/android/mutator_test.go
@@ -17,6 +17,8 @@
import (
"fmt"
"strings"
+ "sync"
+ "sync/atomic"
"testing"
"github.com/google/blueprint"
@@ -220,7 +222,7 @@
}
`
- finalGot := map[string]int{}
+ finalGot := sync.Map{}
GroupFixturePreparers(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
@@ -251,9 +253,11 @@
}
})
ctx.BottomUp("final", func(ctx BottomUpMutatorContext) {
- finalGot[ctx.Module().String()] += 1
+ counter, _ := finalGot.LoadOrStore(ctx.Module().String(), &atomic.Int64{})
+ counter.(*atomic.Int64).Add(1)
ctx.VisitDirectDeps(func(mod Module) {
- finalGot[fmt.Sprintf("%s -> %s", ctx.Module().String(), mod)] += 1
+ counter, _ := finalGot.LoadOrStore(fmt.Sprintf("%s -> %s", ctx.Module().String(), mod), &atomic.Int64{})
+ counter.(*atomic.Int64).Add(1)
})
})
})
@@ -276,7 +280,13 @@
"foo{variant:b} -> common_dep_2{variant:a}": 1,
}
- AssertDeepEquals(t, "final", finalWant, finalGot)
+ finalGotMap := make(map[string]int)
+ finalGot.Range(func(k, v any) bool {
+ finalGotMap[k.(string)] = int(v.(*atomic.Int64).Load())
+ return true
+ })
+
+ AssertDeepEquals(t, "final", finalWant, finalGotMap)
}
func TestTransitionMutatorInFinalDeps(t *testing.T) {
diff --git a/android/namespace.go b/android/namespace.go
index 866d125..8b3ebc4 100644
--- a/android/namespace.go
+++ b/android/namespace.go
@@ -457,7 +457,7 @@
}
func RegisterNamespaceMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("namespace_deps", namespaceMutator).Parallel().MutatesGlobalState()
+ ctx.BottomUp("namespace_deps", namespaceMutator).MutatesGlobalState()
}
func namespaceMutator(ctx BottomUpMutatorContext) {
diff --git a/android/neverallow.go b/android/neverallow.go
index e135f57..439fe2d 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -44,7 +44,7 @@
// - it has none of the "Without" properties matched (same rules as above)
func registerNeverallowMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("neverallow", neverallowMutator).Parallel()
+ ctx.BottomUp("neverallow", neverallowMutator)
}
var neverallows = []Rule{}
@@ -60,6 +60,8 @@
AddNeverAllowRules(createCcStubsRule())
AddNeverAllowRules(createProhibitHeaderOnlyRule())
AddNeverAllowRules(createLimitNdkExportRule()...)
+ AddNeverAllowRules(createLimitDirgroupRule()...)
+ AddNeverAllowRules(createFilesystemIsAutoGeneratedRule())
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -275,6 +277,31 @@
}
}
+func createLimitDirgroupRule() []Rule {
+ reason := "dirgroup module and dir_srcs property of genrule is allowed only to Trusty build rule."
+ return []Rule{
+ NeverAllow().
+ ModuleType("dirgroup").
+ WithMatcher("visibility", NotInList([]string{"//trusty/vendor/google/aosp/scripts"})).Because(reason),
+ NeverAllow().
+ ModuleType("dirgroup").
+ Without("visibility", "//trusty/vendor/google/aosp/scripts").Because(reason),
+ NeverAllow().
+ ModuleType("genrule").
+ Without("name", "lk.elf.arm64").
+ Without("name", "lk.elf.x86_64").
+ WithMatcher("dir_srcs", isSetMatcherInstance).Because(reason),
+ }
+}
+
+func createFilesystemIsAutoGeneratedRule() Rule {
+ return NeverAllow().
+ NotIn("build/soong/fsgen").
+ ModuleType("filesystem", "android_system_image").
+ WithMatcher("is_auto_generated", isSetMatcherInstance).
+ Because("is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory")
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 192c924..caec8c7 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -359,6 +359,21 @@
`headers_only can only be used for generating framework-minus-apex headers for non-updatable modules`,
},
},
+ // Test for the rule restricting use of is_auto_generated
+ {
+ name: `"is_auto_generated" outside allowed directory`,
+ fs: map[string][]byte{
+ "a/b/Android.bp": []byte(`
+ filesystem {
+ name: "baaz",
+ is_auto_generated: true,
+ }
+ `),
+ },
+ expectedErrors: []string{
+ `is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory`,
+ },
+ },
}
var prepareForNeverAllowTest = GroupFixturePreparers(
@@ -367,6 +382,7 @@
ctx.RegisterModuleType("java_library", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
+ ctx.RegisterModuleType("filesystem", newMockFilesystemModule)
}),
)
diff --git a/android/override_module.go b/android/override_module.go
index d844da6..50ddc9b 100644
--- a/android/override_module.go
+++ b/android/override_module.go
@@ -234,18 +234,18 @@
// Mutators for override/overridable modules. All the fun happens in these functions. It is critical
// to keep them in this order and not put any order mutators between them.
func RegisterOverridePostDepsMutators(ctx RegisterMutatorsContext) {
- ctx.BottomUp("override_deps", overrideModuleDepsMutator).Parallel().MutatesDependencies() // modifies deps via addOverride
+ ctx.BottomUp("override_deps", overrideModuleDepsMutator).MutatesDependencies() // modifies deps via addOverride
ctx.Transition("override", &overrideTransitionMutator{})
- ctx.BottomUp("override_apply", overrideApplyMutator).Parallel().MutatesDependencies()
+ ctx.BottomUp("override_apply", overrideApplyMutator).MutatesDependencies()
// overridableModuleDepsMutator calls OverridablePropertiesDepsMutator so that overridable modules can
// add deps from overridable properties.
- ctx.BottomUp("overridable_deps", overridableModuleDepsMutator).Parallel()
+ ctx.BottomUp("overridable_deps", overridableModuleDepsMutator)
// Because overridableModuleDepsMutator is run after PrebuiltPostDepsMutator,
// prebuilt's ReplaceDependencies doesn't affect to those deps added by overridable properties.
// By running PrebuiltPostDepsMutator again after overridableModuleDepsMutator, deps via overridable properties
// can be replaced with prebuilts.
- ctx.BottomUp("replace_deps_on_prebuilts_for_overridable_deps_again", PrebuiltPostDepsMutator).Parallel().UsesReplaceDependencies()
- ctx.BottomUp("replace_deps_on_override", replaceDepsOnOverridingModuleMutator).Parallel().UsesReplaceDependencies()
+ ctx.BottomUp("replace_deps_on_prebuilts_for_overridable_deps_again", PrebuiltPostDepsMutator).UsesReplaceDependencies()
+ ctx.BottomUp("replace_deps_on_override", replaceDepsOnOverridingModuleMutator).UsesReplaceDependencies()
}
type overrideBaseDependencyTag struct {
diff --git a/android/path_properties.go b/android/path_properties.go
index 6210aee..d80a8ed 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -27,7 +27,7 @@
// to the output file of the referenced module.
func registerPathDepsMutator(ctx RegisterMutatorsContext) {
- ctx.BottomUp("pathdeps", pathDepsMutator).Parallel()
+ ctx.BottomUp("pathdeps", pathDepsMutator)
}
// The pathDepsMutator automatically adds dependencies on any module that is listed with the
diff --git a/android/paths.go b/android/paths.go
index ec05831..371aed8 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -550,6 +550,58 @@
return ret
}
+// DirectoryPathsForModuleSrcExcludes returns a Paths{} containing the resolved references in
+// directory paths. Elements of paths are resolved as:
+// - filepath, relative to local module directory, resolves as a filepath relative to the local
+// source directory
+// - other modules using the ":name" syntax. These modules must implement DirProvider.
+//
+// TODO(b/358302178): Implement DirectoryPath and change the return type.
+func DirectoryPathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string) Paths {
+ var ret Paths
+
+ for _, path := range paths {
+ if m, t := SrcIsModuleWithTag(path); m != "" {
+ module := GetModuleFromPathDep(ctx, m, t)
+ if module == nil {
+ ctx.ModuleErrorf(`missing dependency on %q, is the property annotated with android:"path"?`, m)
+ continue
+ }
+ if t != "" {
+ ctx.ModuleErrorf("DirProvider dependency %q does not support the tag %q", module, t)
+ continue
+ }
+ mctx, ok := ctx.(OtherModuleProviderContext)
+ if !ok {
+ panic(fmt.Errorf("%s is not an OtherModuleProviderContext", ctx))
+ }
+ if dirProvider, ok := OtherModuleProvider(mctx, module, DirProvider); ok {
+ ret = append(ret, dirProvider.Dirs...)
+ } else {
+ ReportPathErrorf(ctx, "module %q does not implement DirProvider", module)
+ }
+ } else {
+ p := pathForModuleSrc(ctx, path)
+ if isDir, err := ctx.Config().fs.IsDir(p.String()); err != nil {
+ ReportPathErrorf(ctx, "%s: %s", p, err.Error())
+ } else if !isDir {
+ ReportPathErrorf(ctx, "module directory path %q is not a directory", p)
+ } else {
+ ret = append(ret, p)
+ }
+ }
+ }
+
+ seen := make(map[Path]bool, len(ret))
+ for _, path := range ret {
+ if seen[path] {
+ ReportPathErrorf(ctx, "duplicated path %q", path)
+ }
+ seen[path] = true
+ }
+ return ret
+}
+
// OutputPaths is a slice of OutputPath objects, with helpers to operate on the collection.
type OutputPaths []OutputPath
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 0b0c517..5d75b62 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -272,6 +272,25 @@
InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
}
+// InitConfigurablePrebuiltModuleString is the same as InitPrebuiltModule, but uses a
+// Configurable string property instead of a regular list of strings. It only produces a single
+// source file.
+func InitConfigurablePrebuiltModuleString(module PrebuiltInterface, srcs *proptools.Configurable[string], propertyName string) {
+ if srcs == nil {
+ panic(fmt.Errorf("%s must not be nil", propertyName))
+ }
+
+ srcsSupplier := func(ctx BaseModuleContext, _ Module) []string {
+ src := srcs.GetOrDefault(ctx, "")
+ if src == "" {
+ return nil
+ }
+ return []string{src}
+ }
+
+ InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, propertyName)
+}
+
func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface{}, srcField string) {
srcPropsValue := reflect.ValueOf(srcProps).Elem()
srcStructField, _ := srcPropsValue.Type().FieldByName(srcField)
@@ -400,13 +419,13 @@
}
func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
- ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).Parallel().UsesRename()
+ ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).UsesRename()
}
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
- ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel().UsesReverseDependencies()
- ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
- ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel().UsesReplaceDependencies()
+ ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).UsesReverseDependencies()
+ ctx.BottomUp("prebuilt_select", PrebuiltSelectModuleMutator)
+ ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).UsesReplaceDependencies()
}
// Returns the name of the source module corresponding to a prebuilt module
diff --git a/android/product_config_to_bp.go b/android/product_config_to_bp.go
deleted file mode 100644
index 680328f..0000000
--- a/android/product_config_to_bp.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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
-
-func init() {
- ctx := InitRegistrationContext
- ctx.RegisterParallelSingletonType("product_config_to_bp_singleton", productConfigToBpSingletonFactory)
-}
-
-type productConfigToBpSingleton struct{}
-
-func (s *productConfigToBpSingleton) GenerateBuildActions(ctx SingletonContext) {
- // TODO: update content from make-based product config
- var content string
- generatedBp := PathForOutput(ctx, "soong_generated_product_config.bp")
- WriteFileRule(ctx, generatedBp, content)
- ctx.Phony("product_config_to_bp", generatedBp)
-}
-
-// productConfigToBpSingleton generates a bp file from make-based product config
-func productConfigToBpSingletonFactory() Singleton {
- return &productConfigToBpSingleton{}
-}
diff --git a/android/register.go b/android/register.go
index 94d875d..bb1ead7 100644
--- a/android/register.go
+++ b/android/register.go
@@ -92,7 +92,6 @@
topDownMutator blueprint.TopDownMutator
transitionMutator blueprint.TransitionMutator
- parallel bool
usesRename bool
usesReverseDependencies bool
usesReplaceDependencies bool
diff --git a/android/variable.go b/android/variable.go
index 4210f67..73c0d0e 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -29,7 +29,7 @@
func registerVariableBuildComponents(ctx RegistrationContext) {
ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
- ctx.BottomUp("variable", VariableMutator).Parallel()
+ ctx.BottomUp("variable", VariableMutator)
})
}
diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go
index 329eac9..42eaaf0 100644
--- a/android/vintf_fragment.go
+++ b/android/vintf_fragment.go
@@ -44,7 +44,7 @@
m.AddProperties(
&m.properties,
)
- InitAndroidArchModule(m, DeviceSupported, MultilibFirst)
+ InitAndroidArchModule(m, DeviceSupported, MultilibCommon)
return m
}
diff --git a/android/vintf_fragment_test.go b/android/vintf_fragment_test.go
index 8be534c..cd90b98 100644
--- a/android/vintf_fragment_test.go
+++ b/android/vintf_fragment_test.go
@@ -29,7 +29,7 @@
testResult := PrepareForTestWithAndroidBuildComponents.RunTestWithBp(t, bp)
- vintfFragmentBuild := testResult.TestContext.ModuleForTests("test_vintf_fragment", "android_arm64_armv8-a").Rule("assemble_vintf")
+ vintfFragmentBuild := testResult.TestContext.ModuleForTests("test_vintf_fragment", "android_common").Rule("assemble_vintf")
if !strings.Contains(vintfFragmentBuild.RuleParams.Command, "assemble_vintf") {
t.Errorf("Vintf_manifest build command does not process with assemble_vintf : " + vintfFragmentBuild.RuleParams.Command)
}
diff --git a/android/visibility.go b/android/visibility.go
index 61f2200..cee465e 100644
--- a/android/visibility.go
+++ b/android/visibility.go
@@ -268,7 +268,7 @@
// The rule checker needs to be registered before defaults expansion to correctly check that
// //visibility:xxx isn't combined with other packages in the same list in any one module.
func RegisterVisibilityRuleChecker(ctx RegisterMutatorsContext) {
- ctx.BottomUp("visibilityRuleChecker", visibilityRuleChecker).Parallel()
+ ctx.BottomUp("visibilityRuleChecker", visibilityRuleChecker)
}
// Registers the function that gathers the visibility rules for each module.
@@ -278,12 +278,12 @@
// the complete visibility lists from flat lists and after the package info is gathered to ensure
// that default_visibility is available.
func RegisterVisibilityRuleGatherer(ctx RegisterMutatorsContext) {
- ctx.BottomUp("visibilityRuleGatherer", visibilityRuleGatherer).Parallel()
+ ctx.BottomUp("visibilityRuleGatherer", visibilityRuleGatherer)
}
// This must be registered after the deps have been resolved.
func RegisterVisibilityRuleEnforcer(ctx RegisterMutatorsContext) {
- ctx.BottomUp("visibilityRuleEnforcer", visibilityRuleEnforcer).Parallel()
+ ctx.BottomUp("visibilityRuleEnforcer", visibilityRuleEnforcer)
}
// Checks the per-module visibility rule lists before defaults expansion.
diff --git a/android/visibility_test.go b/android/visibility_test.go
index 1a2eeca..277be0f 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -2098,8 +2098,9 @@
}
type mockFilesystemModuleProperties struct {
- Partition_type *string
- Deps []string
+ Partition_type *string
+ Deps []string
+ Is_auto_generated *bool
}
type mockFilesystemModule struct {
diff --git a/apex/apex.go b/apex/apex.go
index 6bb2a1a..30b16ee 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -55,20 +55,20 @@
}
func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel().UsesReverseDependencies()
+ ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).UsesReverseDependencies()
}
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_info", apexInfoMutator).Parallel()
- ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
- ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
- ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
+ ctx.TopDown("apex_info", apexInfoMutator)
+ ctx.BottomUp("apex_unique", apexUniqueVariationsMutator)
+ ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator)
+ ctx.BottomUp("apex_test_for", apexTestForMutator)
// Run mark_platform_availability before the apexMutator as the apexMutator needs to know whether
// it should create a platform variant.
- ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
+ ctx.BottomUp("mark_platform_availability", markPlatformAvailability)
ctx.Transition("apex", &apexTransitionMutator{})
- ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel().MutatesDependencies()
- ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator).Parallel()
+ ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).MutatesDependencies()
+ ctx.BottomUp("apex_dcla_deps", apexDCLADepsMutator)
}
type apexBundleProperties struct {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b3851e6..042b43d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -82,14 +82,6 @@
return files.AddToFixture()
}
-func withTargets(targets map[android.OsType][]android.Target) android.FixturePreparer {
- return android.FixtureModifyConfig(func(config android.Config) {
- for k, v := range targets {
- config.Targets[k] = v
- }
- })
-}
-
// withNativeBridgeTargets sets configuration with targets including:
// - X86_64 (primary)
// - X86 (secondary)
@@ -4051,11 +4043,20 @@
"libvndk27binder32.so": nil,
}),
withBinder32bit,
- withTargets(map[android.OsType][]android.Target{
- android.Android: {
- {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}},
- NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
- },
+ android.FixtureModifyConfig(func(config android.Config) {
+ target := android.Target{
+ Os: android.Android,
+ Arch: android.Arch{
+ ArchType: android.Arm,
+ ArchVariant: "armv7-a-neon",
+ Abi: []string{"armeabi-v7a"},
+ },
+ NativeBridge: android.NativeBridgeDisabled,
+ NativeBridgeHostArchName: "",
+ NativeBridgeRelativePath: "",
+ }
+ config.Targets[android.Android] = []android.Target{target}
+ config.AndroidFirstDeviceTarget = target
}),
)
@@ -11863,3 +11864,42 @@
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
)
}
+
+// partitions should not package the artifacts that are included inside the apex.
+func TestFilesystemWithApexDeps(t *testing.T) {
+ t.Parallel()
+ result := testApex(t, `
+ android_filesystem {
+ name: "myfilesystem",
+ deps: ["myapex"],
+ }
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ binaries: ["binfoo"],
+ native_shared_libs: ["libfoo"],
+ apps: ["appfoo"],
+ updatable: false,
+ }
+ apex_key {
+ name: "myapex.key",
+ }
+ cc_binary {
+ name: "binfoo",
+ apex_available: ["myapex"],
+ }
+ cc_library {
+ name: "libfoo",
+ apex_available: ["myapex"],
+ }
+ android_app {
+ name: "appfoo",
+ sdk_version: "current",
+ apex_available: ["myapex"],
+ }
+ `, filesystem.PrepareForTestWithFilesystemBuildComponents)
+
+ partition := result.ModuleForTests("myfilesystem", "android_common")
+ fileList := android.ContentFromFileRuleForTests(t, result, partition.Output("fileList"))
+ android.AssertDeepEquals(t, "filesystem with apex", "apex/myapex.apex\n", fileList)
+}
diff --git a/apex/builder.go b/apex/builder.go
index 371d7d5..20b4dbe 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -253,10 +253,10 @@
apexHostVerifierRule = pctx.StaticRule("apexHostVerifierRule", blueprint.RuleParams{
Command: `${host_apex_verifier} --deapexer=${deapexer} --debugfs=${debugfs_static} ` +
- `--fsckerofs=${fsck_erofs} --apex=${in} && touch ${out}`,
+ `--fsckerofs=${fsck_erofs} --apex=${in} --partition_tag=${partition_tag} && touch ${out}`,
CommandDeps: []string{"${host_apex_verifier}", "${deapexer}", "${debugfs_static}", "${fsck_erofs}"},
Description: "run host_apex_verifier",
- })
+ }, "partition_tag")
assembleVintfRule = pctx.StaticRule("assembleVintfRule", blueprint.RuleParams{
Command: `rm -f $out && VINTF_IGNORE_TARGET_FCM_VERSION=true ${assemble_vintf} -i $in -o $out`,
@@ -621,7 +621,8 @@
}
} else {
if installSymbolFiles {
- installedPath = ctx.InstallFile(apexDir.Join(ctx, fi.installDir), fi.stem(), fi.builtFile)
+ // store installedPath. symlinks might be created if required.
+ installedPath = apexDir.Join(ctx, fi.installDir, fi.stem())
}
}
@@ -976,7 +977,7 @@
runApexElfCheckerUnwanted(ctx, unsignedOutputFile.OutputPath, a.properties.Unwanted_transitive_deps))
}
if !a.testApex && android.InList(a.payloadFsType, []fsType{ext4, erofs}) {
- validations = append(validations, runApexHostVerifier(ctx, unsignedOutputFile.OutputPath))
+ validations = append(validations, runApexHostVerifier(ctx, a, unsignedOutputFile.OutputPath))
}
ctx.Build(pctx, android.BuildParams{
Rule: rule,
@@ -1287,12 +1288,15 @@
return timestamp
}
-func runApexHostVerifier(ctx android.ModuleContext, apexFile android.OutputPath) android.Path {
+func runApexHostVerifier(ctx android.ModuleContext, a *apexBundle, apexFile android.OutputPath) android.Path {
timestamp := android.PathForModuleOut(ctx, "host_apex_verifier.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexHostVerifierRule,
Input: apexFile,
Output: timestamp,
+ Args: map[string]string{
+ "partition_tag": a.PartitionTag(ctx.DeviceConfig()),
+ },
})
return timestamp
}
diff --git a/apex/vndk.go b/apex/vndk.go
index 5e630c0..d88808b 100644
--- a/apex/vndk.go
+++ b/apex/vndk.go
@@ -95,7 +95,11 @@
// level for the primary architecture.
a.Disable()
} else {
- mctx.AddDependency(mctx.Module(), prebuiltTag, cc.VndkLibrariesTxtModules(vndkVersion, mctx)...)
+ mctx.AddVariationDependencies(
+ mctx.Config().AndroidFirstDeviceTarget.Variations(),
+ prebuiltTag,
+ cc.VndkLibrariesTxtModules(vndkVersion, mctx)...,
+ )
}
}
}
diff --git a/cc/Android.bp b/cc/Android.bp
index 88a793c..a5ad9ce 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -27,6 +27,7 @@
"builder.go",
"cc.go",
"ccdeps.go",
+ "cc_preprocess_no_configuration.go",
"check.go",
"coverage.go",
"gen.go",
@@ -88,6 +89,7 @@
testSrcs: [
"afdo_test.go",
"binary_test.go",
+ "cc_preprocess_no_configuration_test.go",
"cc_test.go",
"cc_test_only_property_test.go",
"cmake_snapshot_test.go",
diff --git a/cc/cc.go b/cc/cc.go
index 9aff7df..80ae6a0 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -48,10 +48,10 @@
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.Transition("sdk", &sdkTransitionMutator{})
- ctx.BottomUp("llndk", llndkMutator).Parallel()
+ ctx.BottomUp("llndk", llndkMutator)
ctx.Transition("link", &linkageTransitionMutator{})
ctx.Transition("version", &versionTransitionMutator{})
- ctx.BottomUp("begin", BeginMutator).Parallel()
+ ctx.BottomUp("begin", BeginMutator)
})
ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -59,10 +59,10 @@
san.registerMutators(ctx)
}
- ctx.BottomUp("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
- ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
+ ctx.BottomUp("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
+ ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator)
- ctx.BottomUp("fuzz_deps", fuzzMutatorDeps)
+ ctx.Transition("fuzz", &fuzzTransitionMutator{})
ctx.Transition("coverage", &coverageTransitionMutator{})
@@ -72,8 +72,8 @@
ctx.Transition("lto", <oTransitionMutator{})
- ctx.BottomUp("check_linktype", checkLinkTypeMutator).Parallel()
- ctx.BottomUp("double_loadable", checkDoubleLoadableLibraries).Parallel()
+ ctx.BottomUp("check_linktype", checkLinkTypeMutator)
+ ctx.BottomUp("double_loadable", checkDoubleLoadableLibraries)
})
ctx.PostApexMutators(func(ctx android.RegisterMutatorsContext) {
diff --git a/cc/cc_preprocess_no_configuration.go b/cc/cc_preprocess_no_configuration.go
new file mode 100644
index 0000000..3d1d0a5
--- /dev/null
+++ b/cc/cc_preprocess_no_configuration.go
@@ -0,0 +1,108 @@
+// 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 cc
+
+import (
+ "android/soong/android"
+ "strings"
+)
+
+func init() {
+ RegisterCCPreprocessNoConfiguration(android.InitRegistrationContext)
+}
+
+func RegisterCCPreprocessNoConfiguration(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_preprocess_no_configuration", ccPreprocessNoConfigurationFactory)
+}
+
+// cc_preprocess_no_configuration modules run the c preprocessor on a single input source file.
+// They also have "no configuration", meaning they don't have an arch or os associated with them,
+// they should be thought of as pure textual transformations of the input file. In some cases this
+// is good, in others you might want to do different transformations depending on what arch the
+// result will be compiled in, in which case you can use cc_object instead of this module.
+func ccPreprocessNoConfigurationFactory() android.Module {
+ m := &ccPreprocessNoConfiguration{}
+ m.AddProperties(&m.properties)
+ android.InitAndroidModule(m)
+ return m
+}
+
+type ccPreprocessNoConfigurationProps struct {
+ // Called Srcs for consistency with the other cc module types, but only accepts 1 input source
+ // file.
+ Srcs []string `android:"path"`
+ // The flags to pass to the c compiler. Must include -E in order to enable preprocessing-only
+ // mode.
+ Cflags []string `android:"path"`
+}
+
+type ccPreprocessNoConfiguration struct {
+ android.ModuleBase
+ properties ccPreprocessNoConfigurationProps
+}
+
+func (m *ccPreprocessNoConfiguration) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
+ if len(srcs) != 1 {
+ ctx.PropertyErrorf("Srcs", "cc_preprocess_no_configuration only accepts 1 source file, found: %v", srcs.Strings())
+ return
+ }
+ src := srcs[0]
+
+ hasE := false
+ for _, cflag := range m.properties.Cflags {
+ if cflag == "-E" {
+ hasE = true
+ break
+ } else if cflag == "-P" || strings.HasPrefix(cflag, "-D") {
+ // do nothing, allow it
+ } else {
+ ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration only allows -D and -P flags, found: %q", cflag)
+ return
+ }
+ }
+ if !hasE {
+ ctx.PropertyErrorf("Cflags", "cc_preprocess_no_configuration must have a -E cflag")
+ return
+ }
+
+ var ccCmd string
+ switch src.Ext() {
+ case ".c":
+ ccCmd = "clang"
+ case ".cpp", ".cc", ".cxx", ".mm":
+ ccCmd = "clang++"
+ default:
+ ctx.PropertyErrorf("srcs", "File %s has unknown extension. Supported extensions: .c, .cpp, .cc, .cxx, .mm", src)
+ return
+ }
+
+ ccCmd = "${config.ClangBin}/" + ccCmd
+
+ outFile := android.PathForModuleOut(ctx, src.Base())
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: cc,
+ Description: ccCmd + " " + src.Rel(),
+ Output: outFile,
+ Input: src,
+ Args: map[string]string{
+ "cFlags": strings.Join(m.properties.Cflags, " "),
+ "ccCmd": ccCmd,
+ },
+ })
+
+ ctx.SetOutputFiles([]android.Path{outFile}, "")
+}
diff --git a/cc/cc_preprocess_no_configuration_test.go b/cc/cc_preprocess_no_configuration_test.go
new file mode 100644
index 0000000..43e726d
--- /dev/null
+++ b/cc/cc_preprocess_no_configuration_test.go
@@ -0,0 +1,40 @@
+// Copyright 2019 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 cc
+
+import (
+ "android/soong/android"
+ "testing"
+)
+
+func TestCcPreprocessNoConfiguration(t *testing.T) {
+ fixture := android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ android.FixtureRegisterWithContext(RegisterCCPreprocessNoConfiguration),
+ )
+
+ result := fixture.RunTestWithBp(t, `
+cc_preprocess_no_configuration {
+ name: "foo",
+ srcs: ["main.cc"],
+ cflags: ["-E", "-DANDROID"],
+}
+`)
+
+ foo := result.ModuleForTests("foo", "")
+ actual := foo.Rule("cc").Args["cFlags"]
+ expected := "-E -DANDROID"
+ android.AssertStringEquals(t, "cflags should be correct", expected, actual)
+}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 8b930e9..d7ad6bc 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1903,11 +1903,11 @@
moduleName = "afl_fuzz_static_lib"
checkPcGuardFlag(moduleName, variant+"_static", false)
- checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
+ checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
moduleName = "second_static_lib"
checkPcGuardFlag(moduleName, variant+"_static", false)
- checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
+ checkPcGuardFlag(moduleName, variant+"_static_fuzzer_afl", true)
ctx.ModuleForTests("afl_fuzz_shared_lib",
"android_arm64_armv8-a_shared").Rule("cc")
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 3f21bc6..0aa9d4b 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -57,38 +57,76 @@
return []interface{}{&fuzzer.Properties}
}
-func fuzzMutatorDeps(mctx android.BottomUpMutatorContext) {
- currentModule, ok := mctx.Module().(*Module)
+// fuzzTransitionMutator creates variants to propagate the FuzzFramework value down to dependencies.
+type fuzzTransitionMutator struct{}
+
+func (f *fuzzTransitionMutator) Split(ctx android.BaseModuleContext) []string {
+ return []string{""}
+}
+
+func (f *fuzzTransitionMutator) OutgoingTransition(ctx android.OutgoingTransitionContext, sourceVariation string) string {
+ m, ok := ctx.Module().(*Module)
+ if !ok {
+ return ""
+ }
+
+ if m.fuzzer == nil {
+ return ""
+ }
+
+ if m.sanitize == nil {
+ return ""
+ }
+
+ isFuzzerPointer := m.sanitize.getSanitizerBoolPtr(Fuzzer)
+ if isFuzzerPointer == nil || !*isFuzzerPointer {
+ return ""
+ }
+
+ if m.fuzzer.Properties.FuzzFramework != "" {
+ return m.fuzzer.Properties.FuzzFramework.Variant()
+ }
+
+ return sourceVariation
+}
+
+func (f *fuzzTransitionMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
+ m, ok := ctx.Module().(*Module)
+ if !ok {
+ return ""
+ }
+
+ if m.fuzzer == nil {
+ return ""
+ }
+
+ if m.sanitize == nil {
+ return ""
+ }
+
+ isFuzzerPointer := m.sanitize.getSanitizerBoolPtr(Fuzzer)
+ if isFuzzerPointer == nil || !*isFuzzerPointer {
+ return ""
+ }
+
+ return incomingVariation
+}
+
+func (f *fuzzTransitionMutator) Mutate(ctx android.BottomUpMutatorContext, variation string) {
+ m, ok := ctx.Module().(*Module)
if !ok {
return
}
- if currentModule.fuzzer == nil {
+ if m.fuzzer == nil {
return
}
- mctx.WalkDeps(func(child android.Module, parent android.Module) bool {
- c, ok := child.(*Module)
- if !ok {
- return false
- }
-
- if c.sanitize == nil {
- return false
- }
-
- isFuzzerPointer := c.sanitize.getSanitizerBoolPtr(Fuzzer)
- if isFuzzerPointer == nil || !*isFuzzerPointer {
- return false
- }
-
- if c.fuzzer == nil {
- return false
- }
-
- c.fuzzer.Properties.FuzzFramework = currentModule.fuzzer.Properties.FuzzFramework
- return true
- })
+ if variation != "" {
+ m.fuzzer.Properties.FuzzFramework = fuzz.FrameworkFromVariant(variation)
+ m.SetHideFromMake()
+ m.SetPreventInstall()
+ }
}
// cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 18851d1..124dda4 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -176,7 +176,7 @@
switch t {
case cfi, Hwasan, Asan, tsan, Fuzzer, scs, Memtag_stack:
sanitizer := &sanitizerSplitMutator{t}
- ctx.BottomUp(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator).Parallel()
+ ctx.BottomUp(t.variationName()+"_markapexes", sanitizer.markSanitizableApexesMutator)
ctx.Transition(t.variationName(), sanitizer)
case Memtag_heap, Memtag_globals, intOverflow:
// do nothing
diff --git a/cmd/release_config/build_flag/main.go b/cmd/release_config/build_flag/main.go
index 5d183ee..46efce7 100644
--- a/cmd/release_config/build_flag/main.go
+++ b/cmd/release_config/build_flag/main.go
@@ -329,7 +329,7 @@
return err
}
updatedFiles = append(updatedFiles, flagPath)
- fmt.Printf("Added/Updated: %s\n", strings.Join(updatedFiles, " "))
+ fmt.Printf("\033[1mAdded/Updated: %s\033[0m\n", strings.Join(updatedFiles, " "))
return nil
}
diff --git a/etc/adb_keys.go b/etc/adb_keys.go
index 1bce2f1..a2df41c 100644
--- a/etc/adb_keys.go
+++ b/etc/adb_keys.go
@@ -37,7 +37,6 @@
func (m *AdbKeysModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
productVariables := ctx.Config().ProductVariables()
if !(android.Bool(productVariables.Debuggable) && len(android.String(productVariables.AdbKeys)) > 0) {
- m.Disable()
m.SkipInstall()
return
}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index fc6d1f7..fbe24d1 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -78,9 +78,16 @@
Src proptools.Configurable[string] `android:"path,arch_variant,replace_instead_of_append"`
// Source files of this prebuilt. Can reference a genrule type module with the ":module" syntax.
- // Mutually exclusive with src. When used, filename_from_src is set to true.
+ // Mutually exclusive with src. When used, filename_from_src is set to true unless dsts is also
+ // set. May use globs in filenames.
Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
+ // Destination files of this prebuilt. Requires srcs to be used and causes srcs not to implicitly
+ // set filename_from_src. This can be used to install each source file to a different directory
+ // and/or change filenames when files are installed. Must be exactly one entry per source file,
+ // which means care must be taken if srcs has globs.
+ Dsts proptools.Configurable[[]string] `android:"path,arch_variant"`
+
// Optional name for the installed file. If unspecified, name of the module is used as the file
// name. Only available when using a single source (src).
Filename *string `android:"arch_variant"`
@@ -166,7 +173,7 @@
// The base install location when soc_specific property is set to true, e.g. "firmware" for
// prebuilt_firmware.
socInstallDirBase string
- installDirPath android.InstallPath
+ installDirPaths []android.InstallPath
additionalDependencies *android.Paths
usedSrcsProperty bool
@@ -279,7 +286,10 @@
}
func (p *PrebuiltEtc) InstallDirPath() android.InstallPath {
- return p.installDirPath
+ if len(p.installDirPaths) != 1 {
+ panic(fmt.Errorf("InstallDirPath not available on multi-source prebuilt %q", p.Name()))
+ }
+ return p.installDirPaths[0]
}
// This allows other derivative modules (e.g. prebuilt_etc_xml) to perform
@@ -338,12 +348,16 @@
if srcProperty.IsPresent() && len(srcsProperty) > 0 {
ctx.PropertyErrorf("src", "src is set. Cannot set srcs")
}
+ dstsProperty := p.properties.Dsts.GetOrDefault(ctx, nil)
+ if len(dstsProperty) > 0 && len(srcsProperty) == 0 {
+ ctx.PropertyErrorf("dsts", "dsts is set. Must use srcs")
+ }
// Check that `sub_dir` and `relative_install_path` are not set at the same time.
if p.subdirProperties.Sub_dir != nil && p.subdirProperties.Relative_install_path != nil {
ctx.PropertyErrorf("sub_dir", "relative_install_path is set. Cannot set sub_dir")
}
- p.installDirPath = android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())
+ baseInstallDirPath := android.PathForModuleInstall(ctx, p.installBaseDir(ctx), p.SubDir())
filename := proptools.String(p.properties.Filename)
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
@@ -379,10 +393,11 @@
filename: filename,
sourceFilePath: p.sourceFilePaths[0],
outputFilePath: p.outputFilePaths[0],
- installDirPath: p.installDirPath,
+ installDirPath: baseInstallDirPath,
symlinks: p.properties.Symlinks,
}
installs = append(installs, ip)
+ p.installDirPaths = append(p.installDirPaths, baseInstallDirPath)
} else if len(srcsProperty) > 0 {
p.usedSrcsProperty = true
if filename != "" {
@@ -392,20 +407,39 @@
ctx.PropertyErrorf("symlinks", "symlinks cannot be set when using srcs")
}
if p.properties.Filename_from_src != nil {
- ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
+ if len(dstsProperty) > 0 {
+ ctx.PropertyErrorf("filename_from_src", "dsts is set. Cannot set filename_from_src")
+ } else {
+ ctx.PropertyErrorf("filename_from_src", "filename_from_src is implicitly set to true when using srcs")
+ }
}
p.sourceFilePaths = android.PathsForModuleSrc(ctx, srcsProperty)
- for _, src := range p.sourceFilePaths {
- filename := src.Base()
+ if len(dstsProperty) > 0 && len(p.sourceFilePaths) != len(dstsProperty) {
+ ctx.PropertyErrorf("dsts", "Must have one entry in dsts per source file")
+ }
+ for i, src := range p.sourceFilePaths {
+ var filename string
+ var installDirPath android.InstallPath
+
+ if len(dstsProperty) > 0 {
+ var dstdir string
+
+ dstdir, filename = filepath.Split(dstsProperty[i])
+ installDirPath = baseInstallDirPath.Join(ctx, dstdir)
+ } else {
+ filename = src.Base()
+ installDirPath = baseInstallDirPath
+ }
output := android.PathForModuleOut(ctx, filename).OutputPath
ip := installProperties{
filename: filename,
sourceFilePath: src,
outputFilePath: output,
- installDirPath: p.installDirPath,
+ installDirPath: installDirPath,
}
p.outputFilePaths = append(p.outputFilePaths, output)
installs = append(installs, ip)
+ p.installDirPaths = append(p.installDirPaths, installDirPath)
}
} else if ctx.Config().AllowMissingDependencies() {
// If no srcs was set and AllowMissingDependencies is enabled then
@@ -421,9 +455,10 @@
filename: filename,
sourceFilePath: p.sourceFilePaths[0],
outputFilePath: p.outputFilePaths[0],
- installDirPath: p.installDirPath,
+ installDirPath: baseInstallDirPath,
}
installs = append(installs, ip)
+ p.installDirPaths = append(p.installDirPaths, baseInstallDirPath)
} else {
ctx.PropertyErrorf("src", "missing prebuilt source file")
return
@@ -493,7 +528,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPaths[0].String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePaths[0].Base())
if len(p.properties.Symlinks) > 0 {
entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index e739afe..75c6d12 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -119,6 +119,113 @@
android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[2].Base())
}
+func TestPrebuiltEtcDsts(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["foo.conf", "bar.conf"],
+ dsts: ["foodir/foo.conf", "bardir/extradir/different.name"],
+ }
+ `)
+
+ p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
+ android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[0].Base())
+ android.AssertStringEquals(t, "output file path", "different.name", p.outputFilePaths[1].Base())
+
+ expectedPaths := [...]string{
+ "out/soong/target/product/test_device/system/etc/foodir",
+ "out/soong/target/product/test_device/system/etc/bardir/extradir",
+ }
+ android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[0], p.installDirPaths[0])
+ android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[1], p.installDirPaths[1])
+}
+
+func TestPrebuiltEtcDstsPlusRelativeInstallPath(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["foo.conf", "bar.conf"],
+ dsts: ["foodir/foo.conf", "bardir/extradir/different.name"],
+ relative_install_path: "somewhere",
+ }
+ `)
+
+ p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
+ android.AssertStringEquals(t, "output file path", "foo.conf", p.outputFilePaths[0].Base())
+ android.AssertStringEquals(t, "output file path", "different.name", p.outputFilePaths[1].Base())
+
+ expectedPaths := [...]string{
+ "out/soong/target/product/test_device/system/etc/somewhere/foodir",
+ "out/soong/target/product/test_device/system/etc/somewhere/bardir/extradir",
+ }
+ android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[0], p.installDirPaths[0])
+ android.AssertPathRelativeToTopEquals(t, "install dir", expectedPaths[1], p.installDirPaths[1])
+}
+
+func TestPrebuiltEtcDstsSrcGlob(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["*.conf"],
+ dsts: ["a.conf", "b.conf", "c.conf"],
+ }
+ `)
+
+ p := result.Module("foo", "android_arm64_armv8-a").(*PrebuiltEtc)
+ android.AssertStringEquals(t, "output file path", "a.conf", p.outputFilePaths[0].Base())
+ android.AssertStringEquals(t, "output file path", "b.conf", p.outputFilePaths[1].Base())
+ android.AssertStringEquals(t, "output file path", "c.conf", p.outputFilePaths[2].Base())
+}
+
+func TestPrebuiltEtcDstsSrcGlobDstsTooShort(t *testing.T) {
+ prepareForPrebuiltEtcTest.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("Must have one entry in dsts per source file")).
+ RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["*.conf"],
+ dsts: ["a.conf", "b.conf"],
+ }
+ `)
+}
+
+func TestPrebuiltEtcDstsSrcGlobDstsTooLong(t *testing.T) {
+ prepareForPrebuiltEtcTest.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("Must have one entry in dsts per source file")).
+ RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo",
+ srcs: ["*.conf"],
+ dsts: ["a.conf", "b.conf", "c.conf", "d.conf"],
+ }
+ `)
+}
+
+func TestPrebuiltEtcCannotDstsWithSrc(t *testing.T) {
+ prepareForPrebuiltEtcTest.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("dsts is set. Must use srcs")).
+ RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo.conf",
+ src: "foo.conf",
+ dsts: ["a.conf"],
+ }
+ `)
+}
+
+func TestPrebuiltEtcCannotDstsWithFilenameFromSrc(t *testing.T) {
+ prepareForPrebuiltEtcTest.
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("dsts is set. Cannot set filename_from_src")).
+ RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo.conf",
+ srcs: ["foo.conf"],
+ dsts: ["a.conf"],
+ filename_from_src: true,
+ }
+ `)
+}
+
func TestPrebuiltEtcAndroidMk(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_etc {
@@ -165,7 +272,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/etc/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltEtcCannotSetRelativeInstallPathAndSubDir(t *testing.T) {
@@ -231,7 +338,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltRootInstallDirPathValidate(t *testing.T) {
@@ -256,7 +363,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/root/avb"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltAvdInstallDirPathValidate(t *testing.T) {
@@ -280,7 +387,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/usr/share/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) {
@@ -295,7 +402,7 @@
buildOS := result.Config.BuildOS.String()
p := result.Module("foo.conf", buildOS+"_common").(*PrebuiltEtc)
expected := filepath.Join("out/soong/host", result.Config.PrebuiltOS(), "usr", "share", "bar")
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltPrebuiltUserHyphenDataInstallDirPath(t *testing.T) {
@@ -309,7 +416,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/usr/hyphen-data/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltPrebuiltUserKeyLayoutInstallDirPath(t *testing.T) {
@@ -323,7 +430,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/usr/keylayout/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltPrebuiltUserKeyCharsInstallDirPath(t *testing.T) {
@@ -337,7 +444,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/usr/keychars/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltPrebuiltUserIdcInstallDirPath(t *testing.T) {
@@ -351,7 +458,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/usr/idc/bar"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltFontInstallDirPath(t *testing.T) {
@@ -364,7 +471,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/fonts"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltOverlayInstallDirPath(t *testing.T) {
@@ -377,7 +484,7 @@
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
expected := "out/soong/target/product/test_device/system/overlay"
- android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPaths[0])
}
func TestPrebuiltFirmwareDirPath(t *testing.T) {
@@ -409,7 +516,7 @@
t.Run(tt.description, func(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
})
}
}
@@ -443,7 +550,7 @@
t.Run(tt.description, func(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
})
}
}
@@ -477,7 +584,7 @@
t.Run(tt.description, func(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, tt.config)
p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
- android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPath)
+ android.AssertPathRelativeToTopEquals(t, "install dir", tt.expectedPath, p.installDirPaths[0])
})
}
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 9b3eae4..4bdd0a4 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -92,7 +92,7 @@
// Name of the partition stored in vbmeta desc. Defaults to the name of this module.
Partition_name *string
- // Type of the filesystem. Currently, ext4, cpio, and compressed_cpio are supported. Default
+ // Type of the filesystem. Currently, ext4, erofs, cpio, and compressed_cpio are supported. Default
// is ext4.
Type *string
@@ -143,6 +143,24 @@
// build modules, where we want to emit some not-yet-working filesystems and we don't want them
// to be built.
Unchecked_module *bool `blueprint:"mutated"`
+
+ Erofs ErofsProperties
+
+ // Determines if the module is auto-generated from Soong or not. If the module is
+ // auto-generated, its deps are exempted from visibility enforcement.
+ Is_auto_generated *bool
+}
+
+// Additional properties required to generate erofs FS partitions.
+type ErofsProperties struct {
+ // Compressor and Compression level passed to mkfs.erofs. e.g. (lz4hc,9)
+ // Please see external/erofs-utils/README for complete documentation.
+ Compressor *string
+
+ // Used as --compress-hints for mkfs.erofs
+ Compress_hints *string `android:"path"`
+
+ Sparse *bool
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -165,24 +183,45 @@
android.InitDefaultableModule(module)
}
-var dependencyTag = struct {
+type depTag struct {
blueprint.BaseDependencyTag
android.PackagingItemAlwaysDepTag
-}{}
+}
+
+var dependencyTag = depTag{}
+
+type depTagWithVisibilityEnforcementBypass struct {
+ depTag
+}
+
+var _ android.ExcludeFromVisibilityEnforcementTag = (*depTagWithVisibilityEnforcementBypass)(nil)
+
+func (t depTagWithVisibilityEnforcementBypass) ExcludeFromVisibilityEnforcement() {}
+
+var dependencyTagWithVisibilityEnforcementBypass = depTagWithVisibilityEnforcementBypass{}
func (f *filesystem) DepsMutator(ctx android.BottomUpMutatorContext) {
- f.AddDeps(ctx, dependencyTag)
+ if proptools.Bool(f.properties.Is_auto_generated) {
+ f.AddDeps(ctx, dependencyTagWithVisibilityEnforcementBypass)
+ } else {
+ f.AddDeps(ctx, dependencyTag)
+ }
}
type fsType int
const (
ext4Type fsType = iota
+ erofsType
compressedCpioType
cpioType // uncompressed
unknown
)
+func (fs fsType) IsUnknown() bool {
+ return fs == unknown
+}
+
type FilesystemInfo struct {
// A text file containing the list of paths installed on the partition.
FileListFile android.Path
@@ -190,21 +229,30 @@
var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
-func (f *filesystem) fsType(ctx android.ModuleContext) fsType {
- typeStr := proptools.StringDefault(f.properties.Type, "ext4")
+func GetFsTypeFromString(ctx android.EarlyModuleContext, typeStr string) fsType {
switch typeStr {
case "ext4":
return ext4Type
+ case "erofs":
+ return erofsType
case "compressed_cpio":
return compressedCpioType
case "cpio":
return cpioType
default:
- ctx.PropertyErrorf("type", "%q not supported", typeStr)
return unknown
}
}
+func (f *filesystem) fsType(ctx android.ModuleContext) fsType {
+ typeStr := proptools.StringDefault(f.properties.Type, "ext4")
+ fsType := GetFsTypeFromString(ctx, typeStr)
+ if fsType == unknown {
+ ctx.PropertyErrorf("type", "%q not supported", typeStr)
+ }
+ return fsType
+}
+
func (f *filesystem) installFileName() string {
return f.BaseModuleName() + ".img"
}
@@ -224,7 +272,7 @@
func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
validatePartitionType(ctx, f)
switch f.fsType(ctx) {
- case ext4Type:
+ case ext4Type, erofsType:
f.output = f.buildImageUsingBuildImage(ctx)
case compressedCpioType:
f.output = f.buildCpioImage(ctx, true)
@@ -437,6 +485,8 @@
// TODO(372522486): add more types like f2fs, erofs, etc.
case ext4Type:
return "ext4"
+ case erofsType:
+ return "erofs"
}
panic(fmt.Errorf("unsupported fs type %v", t))
}
@@ -486,6 +536,24 @@
addStr("uuid", uuid)
addStr("hash_seed", uuid)
}
+ // Add erofs properties
+ if f.fsType(ctx) == erofsType {
+ if compressor := f.properties.Erofs.Compressor; compressor != nil {
+ addStr("erofs_default_compressor", proptools.String(compressor))
+ }
+ if compressHints := f.properties.Erofs.Compress_hints; compressHints != nil {
+ addPath("erofs_default_compress_hints", android.PathForModuleSrc(ctx, *compressHints))
+ }
+ if proptools.BoolDefault(f.properties.Erofs.Sparse, true) {
+ // https://source.corp.google.com/h/googleplex-android/platform/build/+/88b1c67239ca545b11580237242774b411f2fed9:core/Makefile;l=2292;bpv=1;bpt=0;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b
+ addStr("erofs_sparse_flag", "-s")
+ }
+ } else if f.properties.Erofs.Compressor != nil || f.properties.Erofs.Compress_hints != nil || f.properties.Erofs.Sparse != nil {
+ // Raise an exception if the propfile contains erofs properties, but the fstype is not erofs
+ fs := fsTypeStr(f.fsType(ctx))
+ ctx.PropertyErrorf("erofs", "erofs is non-empty, but FS type is %s\n. Please delete erofs properties if this partition should use %s\n", fs, fs)
+ }
+
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
android.WriteFileRuleVerbatim(ctx, propFile, propFileString.String())
return propFile, deps
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 8c0d111..057dcaa 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -559,3 +559,28 @@
}
}
}
+
+func TestErofsPartition(t *testing.T) {
+ result := fixture.RunTestWithBp(t, `
+ android_filesystem {
+ name: "erofs_partition",
+ type: "erofs",
+ erofs: {
+ compressor: "lz4hc,9",
+ compress_hints: "compress_hints.txt",
+ },
+ deps: ["binfoo"],
+ }
+
+ cc_binary {
+ name: "binfoo",
+ }
+ `)
+
+ partition := result.ModuleForTests("erofs_partition", "android_common")
+ buildImageConfig := android.ContentFromFileRuleForTests(t, result.TestContext, partition.Output("prop"))
+ android.AssertStringDoesContain(t, "erofs fs type", buildImageConfig, "fs_type=erofs")
+ android.AssertStringDoesContain(t, "erofs fs type compress algorithm", buildImageConfig, "erofs_default_compressor=lz4hc,9")
+ android.AssertStringDoesContain(t, "erofs fs type compress hint", buildImageConfig, "erofs_default_compress_hints=compress_hints.txt")
+ android.AssertStringDoesContain(t, "erofs fs type sparse", buildImageConfig, "erofs_sparse_flag=-s")
+}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index d75a4a2..f446c2b 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -15,13 +15,18 @@
package fsgen
import (
- "android/soong/android"
- "android/soong/filesystem"
"crypto/sha256"
"fmt"
+ "slices"
"strconv"
+ "strings"
+ "sync"
+
+ "android/soong/android"
+ "android/soong/filesystem"
"github.com/google/blueprint"
+ "github.com/google/blueprint/parser"
"github.com/google/blueprint/proptools"
)
@@ -33,6 +38,229 @@
func registerBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("soong_filesystem_creator", filesystemCreatorFactory)
+ ctx.PreDepsMutators(RegisterCollectFileSystemDepsMutators)
+}
+
+func RegisterCollectFileSystemDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("fs_collect_deps", collectDepsMutator).MutatesGlobalState()
+ ctx.BottomUp("fs_set_deps", setDepsMutator)
+}
+
+var fsGenStateOnceKey = android.NewOnceKey("FsGenState")
+
+// Map of partition module name to its partition that may be generated by Soong.
+// Note that it is not guaranteed that all modules returned by this function are successfully
+// created.
+func getAllSoongGeneratedPartitionNames(config android.Config, partitions []string) map[string]string {
+ ret := map[string]string{}
+ for _, partition := range partitions {
+ ret[generatedModuleNameForPartition(config, partition)] = partition
+ }
+ return ret
+}
+
+type depCandidateProps struct {
+ Namespace string
+ Multilib string
+ Arch []android.ArchType
+}
+
+// Map of module name to depCandidateProps
+type multilibDeps *map[string]*depCandidateProps
+
+// Information necessary to generate the filesystem modules, including details about their
+// dependencies
+type FsGenState struct {
+ // List of modules in `PRODUCT_PACKAGES` and `PRODUCT_PACKAGES_DEBUG`
+ depCandidates []string
+ // Map of names of partition to the information of modules to be added as deps
+ fsDeps map[string]multilibDeps
+ // List of name of partitions to be generated by the filesystem_creator module
+ soongGeneratedPartitions []string
+ // Mutex to protect the fsDeps
+ fsDepsMutex sync.Mutex
+}
+
+func newMultilibDeps() multilibDeps {
+ return &map[string]*depCandidateProps{}
+}
+
+func defaultDepCandidateProps(config android.Config) *depCandidateProps {
+ return &depCandidateProps{
+ Namespace: ".",
+ Arch: []android.ArchType{config.BuildArch},
+ }
+}
+
+func createFsGenState(ctx android.LoadHookContext) *FsGenState {
+ return ctx.Config().Once(fsGenStateOnceKey, func() interface{} {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ candidates := android.FirstUniqueStrings(android.Concat(partitionVars.ProductPackages, partitionVars.ProductPackagesDebug))
+
+ generatedPartitions := []string{"system"}
+ if ctx.DeviceConfig().SystemExtPath() == "system_ext" {
+ generatedPartitions = append(generatedPartitions, "system_ext")
+ }
+
+ return &FsGenState{
+ depCandidates: candidates,
+ fsDeps: map[string]multilibDeps{
+ // These additional deps are added according to the cuttlefish system image bp.
+ "system": &map[string]*depCandidateProps{
+ "com.android.apex.cts.shim.v1_prebuilt": defaultDepCandidateProps(ctx.Config()),
+ "dex_bootjars": defaultDepCandidateProps(ctx.Config()),
+ "framework_compatibility_matrix.device.xml": defaultDepCandidateProps(ctx.Config()),
+ "idc_data": defaultDepCandidateProps(ctx.Config()),
+ "init.environ.rc-soong": defaultDepCandidateProps(ctx.Config()),
+ "keychars_data": defaultDepCandidateProps(ctx.Config()),
+ "keylayout_data": defaultDepCandidateProps(ctx.Config()),
+ "libclang_rt.asan": defaultDepCandidateProps(ctx.Config()),
+ "libcompiler_rt": defaultDepCandidateProps(ctx.Config()),
+ "libdmabufheap": defaultDepCandidateProps(ctx.Config()),
+ "libgsi": defaultDepCandidateProps(ctx.Config()),
+ "llndk.libraries.txt": defaultDepCandidateProps(ctx.Config()),
+ "logpersist.start": defaultDepCandidateProps(ctx.Config()),
+ "preloaded-classes": defaultDepCandidateProps(ctx.Config()),
+ "public.libraries.android.txt": defaultDepCandidateProps(ctx.Config()),
+ "update_engine_sideload": defaultDepCandidateProps(ctx.Config()),
+ },
+ "vendor": newMultilibDeps(),
+ "odm": newMultilibDeps(),
+ "product": newMultilibDeps(),
+ "system_ext": newMultilibDeps(),
+ },
+ soongGeneratedPartitions: generatedPartitions,
+ fsDepsMutex: sync.Mutex{},
+ }
+ }).(*FsGenState)
+}
+
+func checkDepModuleInMultipleNamespaces(mctx android.BottomUpMutatorContext, foundDeps map[string]*depCandidateProps, module string, partitionName string) {
+ otherNamespace := mctx.Namespace().Path
+ if val, found := foundDeps[module]; found && otherNamespace != "." && !android.InList(val.Namespace, []string{".", otherNamespace}) {
+ mctx.ModuleErrorf("found in multiple namespaces(%s and %s) when including in %s partition", val.Namespace, otherNamespace, partitionName)
+ }
+}
+
+func appendDepIfAppropriate(mctx android.BottomUpMutatorContext, deps *map[string]*depCandidateProps, installPartition string) {
+ checkDepModuleInMultipleNamespaces(mctx, *deps, mctx.Module().Name(), installPartition)
+ if _, ok := (*deps)[mctx.Module().Name()]; ok {
+ // Prefer the namespace-specific module over the platform module
+ if mctx.Namespace().Path != "." {
+ (*deps)[mctx.Module().Name()].Namespace = mctx.Namespace().Path
+ }
+ (*deps)[mctx.Module().Name()].Arch = append((*deps)[mctx.Module().Name()].Arch, mctx.Module().Target().Arch.ArchType)
+ } else {
+ multilib, _ := mctx.Module().DecodeMultilib(mctx)
+ (*deps)[mctx.Module().Name()] = &depCandidateProps{
+ Namespace: mctx.Namespace().Path,
+ Multilib: multilib,
+ Arch: []android.ArchType{mctx.Module().Target().Arch.ArchType},
+ }
+ }
+}
+
+func collectDepsMutator(mctx android.BottomUpMutatorContext) {
+ fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+
+ m := mctx.Module()
+ if slices.Contains(fsGenState.depCandidates, m.Name()) {
+ installPartition := m.PartitionTag(mctx.DeviceConfig())
+ fsGenState.fsDepsMutex.Lock()
+ // Only add the module as dependency when:
+ // - its enabled
+ // - its namespace is included in PRODUCT_SOONG_NAMESPACES
+ if m.Enabled(mctx) && m.ExportedToMake() {
+ appendDepIfAppropriate(mctx, fsGenState.fsDeps[installPartition], installPartition)
+ }
+ fsGenState.fsDepsMutex.Unlock()
+ }
+}
+
+type depsStruct struct {
+ Deps []string
+}
+
+type multilibDepsStruct struct {
+ Common depsStruct
+ Lib32 depsStruct
+ Lib64 depsStruct
+ Both depsStruct
+ Prefer32 depsStruct
+}
+
+type packagingPropsStruct struct {
+ Deps []string
+ Multilib multilibDepsStruct
+}
+
+func fullyQualifiedModuleName(moduleName, namespace string) string {
+ if namespace == "." {
+ return moduleName
+ }
+ return fmt.Sprintf("//%s:%s", namespace, moduleName)
+}
+
+// Returns the sorted unique list of module names with namespace, if the module specifies one.
+func fullyQualifiedModuleNames(modules multilibDeps) (ret []string) {
+ for moduleName, moduleProp := range *modules {
+ ret = append(ret, fullyQualifiedModuleName(moduleName, moduleProp.Namespace))
+ }
+ return android.SortedUniqueStrings(ret)
+}
+
+func getBitness(archTypes []android.ArchType) (ret []string) {
+ for _, archType := range archTypes {
+ if archType.Multilib == "" {
+ ret = append(ret, android.COMMON_VARIANT)
+ } else {
+ ret = append(ret, archType.Bitness())
+ }
+ }
+ return ret
+}
+
+func setDepsMutator(mctx android.BottomUpMutatorContext) {
+ fsGenState := mctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+ fsDeps := fsGenState.fsDeps
+ soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
+ m := mctx.Module()
+ if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok {
+ depsStruct := packagingPropsStruct{}
+ for depName, depProps := range *fsDeps[partition] {
+ bitness := getBitness(depProps.Arch)
+ fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace)
+ if android.InList("32", bitness) && android.InList("64", bitness) {
+ // If both 32 and 64 bit variants are enabled for this module
+ switch depProps.Multilib {
+ case string(android.MultilibBoth):
+ depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
+ case string(android.MultilibCommon), string(android.MultilibFirst):
+ depsStruct.Deps = append(depsStruct.Deps, fullyQualifiedDepName)
+ case "32":
+ depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
+ case "64", "darwin_universal":
+ depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
+ case "prefer32", "first_prefer32":
+ depsStruct.Multilib.Prefer32.Deps = append(depsStruct.Multilib.Prefer32.Deps, fullyQualifiedDepName)
+ default:
+ depsStruct.Multilib.Both.Deps = append(depsStruct.Multilib.Both.Deps, fullyQualifiedDepName)
+ }
+ } else if android.InList("64", bitness) {
+ // If only 64 bit variant is enabled
+ depsStruct.Multilib.Lib64.Deps = append(depsStruct.Multilib.Lib64.Deps, fullyQualifiedDepName)
+ } else if android.InList("32", bitness) {
+ // If only 32 bit variant is enabled
+ depsStruct.Multilib.Lib32.Deps = append(depsStruct.Multilib.Lib32.Deps, fullyQualifiedDepName)
+ } else {
+ // If only common variant is enabled
+ depsStruct.Multilib.Common.Deps = append(depsStruct.Multilib.Common.Deps, fullyQualifiedDepName)
+ }
+ }
+ if err := proptools.AppendMatchingProperties(m.GetProperties(), &depsStruct, nil); err != nil {
+ mctx.ModuleErrorf(err.Error())
+ }
+ }
}
type filesystemCreatorProps struct {
@@ -49,9 +277,10 @@
func filesystemCreatorFactory() android.Module {
module := &filesystemCreator{}
- android.InitAndroidModule(module)
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
module.AddProperties(&module.properties)
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ createFsGenState(ctx)
module.createInternalModules(ctx)
})
@@ -59,17 +288,19 @@
}
func (f *filesystemCreator) createInternalModules(ctx android.LoadHookContext) {
- for _, partitionType := range []string{"system"} {
+ soongGeneratedPartitions := &ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions
+ for _, partitionType := range *soongGeneratedPartitions {
if f.createPartition(ctx, partitionType) {
f.properties.Generated_partition_types = append(f.properties.Generated_partition_types, partitionType)
} else {
f.properties.Unsupported_partition_types = append(f.properties.Unsupported_partition_types, partitionType)
+ _, *soongGeneratedPartitions = android.RemoveFromList(partitionType, *soongGeneratedPartitions)
}
}
f.createDeviceModule(ctx)
}
-func (f *filesystemCreator) generatedModuleName(cfg android.Config, suffix string) string {
+func generatedModuleName(cfg android.Config, suffix string) string {
prefix := "soong"
if cfg.HasDeviceProduct() {
prefix = cfg.DeviceProduct()
@@ -77,44 +308,89 @@
return fmt.Sprintf("%s_generated_%s", prefix, suffix)
}
-func (f *filesystemCreator) generatedModuleNameForPartition(cfg android.Config, partitionType string) string {
- return f.generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
+func generatedModuleNameForPartition(cfg android.Config, partitionType string) string {
+ return generatedModuleName(cfg, fmt.Sprintf("%s_image", partitionType))
}
func (f *filesystemCreator) createDeviceModule(ctx android.LoadHookContext) {
baseProps := &struct {
Name *string
}{
- Name: proptools.StringPtr(f.generatedModuleName(ctx.Config(), "device")),
+ Name: proptools.StringPtr(generatedModuleName(ctx.Config(), "device")),
}
- // Currently, only the system partition module is created.
+ // Currently, only the system and system_ext partition module is created.
partitionProps := &filesystem.PartitionNameProperties{}
if android.InList("system", f.properties.Generated_partition_types) {
- partitionProps.System_partition_name = proptools.StringPtr(f.generatedModuleNameForPartition(ctx.Config(), "system"))
+ partitionProps.System_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+ }
+ if android.InList("system_ext", f.properties.Generated_partition_types) {
+ partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
ctx.CreateModule(filesystem.AndroidDeviceFactory, baseProps, partitionProps)
}
+var (
+ // https://source.corp.google.com/h/googleplex-android/platform/build/+/639d79f5012a6542ab1f733b0697db45761ab0f3:core/packaging/flags.mk;l=21;drc=5ba8a8b77507f93aa48cc61c5ba3f31a4d0cbf37;bpv=1;bpt=0
+ partitionsWithAconfig = []string{"system", "product", "vendor"}
+)
+
// Creates a soong module to build the given partition. Returns false if we can't support building
// it.
func (f *filesystemCreator) createPartition(ctx android.LoadHookContext, partitionType string) bool {
- baseProps := &struct {
- Name *string
- }{
- Name: proptools.StringPtr(f.generatedModuleNameForPartition(ctx.Config(), partitionType)),
+ baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
+
+ fsProps, supported := generateFsProps(ctx, partitionType)
+ if !supported {
+ return false
}
+ var module android.Module
+ if partitionType == "system" {
+ module = ctx.CreateModule(filesystem.SystemImageFactory, baseProps, fsProps)
+ } else {
+ // Explicitly set the partition.
+ fsProps.Partition_type = proptools.StringPtr(partitionType)
+ module = ctx.CreateModule(filesystem.FilesystemFactory, baseProps, fsProps)
+ }
+ module.HideFromMake()
+ return true
+}
+
+type filesystemBaseProperty struct {
+ Name *string
+ Compile_multilib *string
+}
+
+func generateBaseProps(namePtr *string) *filesystemBaseProperty {
+ return &filesystemBaseProperty{
+ Name: namePtr,
+ Compile_multilib: proptools.StringPtr("both"),
+ }
+}
+
+func generateFsProps(ctx android.EarlyModuleContext, partitionType string) (*filesystem.FilesystemProperties, bool) {
fsProps := &filesystem.FilesystemProperties{}
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ specificPartitionVars := partitionVars.PartitionQualifiedVariables[partitionType]
+
+ // BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE
+ fsType := specificPartitionVars.BoardFileSystemType
+ if fsType == "" {
+ fsType = "ext4" //default
+ }
+ fsProps.Type = proptools.StringPtr(fsType)
+ if filesystem.GetFsTypeFromString(ctx, *fsProps.Type).IsUnknown() {
+ // Currently the android_filesystem module type only supports a handful of FS types like ext4, erofs
+ return nil, false
+ }
+
// Don't build this module on checkbuilds, the soong-built partitions are still in-progress
// and sometimes don't build.
fsProps.Unchecked_module = proptools.BoolPtr(true)
- partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
- specificPartitionVars := partitionVars.PartitionQualifiedVariables[partitionType]
-
// BOARD_AVB_ENABLE
fsProps.Use_avb = proptools.BoolPtr(partitionVars.BoardAvbEnable)
// BOARD_AVB_KEY_PATH
@@ -127,18 +403,12 @@
}
fsProps.Partition_name = proptools.StringPtr(partitionType)
- // BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE
- fsProps.Type = proptools.StringPtr(specificPartitionVars.BoardFileSystemType)
- if *fsProps.Type != "ext4" {
- // TODO(b/372522486): Support other FS types.
- // Currently the android_filesystem module type only supports ext4:
- // https://cs.android.com/android/platform/superproject/main/+/main:build/soong/filesystem/filesystem.go;l=416;drc=98047cfd07944b297a12d173453bc984806760d2
- return false
- }
fsProps.Base_dir = proptools.StringPtr(partitionType)
- fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(true)
+ fsProps.Gen_aconfig_flags_pb = proptools.BoolPtr(android.InList(partitionType, partitionsWithAconfig))
+
+ fsProps.Is_auto_generated = proptools.BoolPtr(true)
// Identical to that of the generic_system_image
fsProps.Fsverity.Inputs = []string{
@@ -163,18 +433,12 @@
// - filesystemProperties.Build_logtags
// - filesystemProperties.Fsverity.Libs
// - systemImageProperties.Linker_config_src
- var module android.Module
- if partitionType == "system" {
- module = ctx.CreateModule(filesystem.SystemImageFactory, baseProps, fsProps)
- } else {
- module = ctx.CreateModule(filesystem.FilesystemFactory, baseProps, fsProps)
- }
- module.HideFromMake()
- return true
+
+ return fsProps, true
}
func (f *filesystemCreator) createDiffTest(ctx android.ModuleContext, partitionType string) android.Path {
- partitionModuleName := f.generatedModuleNameForPartition(ctx.Config(), partitionType)
+ partitionModuleName := generatedModuleNameForPartition(ctx.Config(), partitionType)
systemImage := ctx.GetDirectDepWithTag(partitionModuleName, generatedFilesystemDepTag)
filesystemInfo, ok := android.OtherModuleProvider(ctx, systemImage, filesystem.FilesystemProvider)
if !ok {
@@ -218,7 +482,7 @@
func (f *filesystemCreator) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, partitionType := range f.properties.Generated_partition_types {
- ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, f.generatedModuleNameForPartition(ctx.Config(), partitionType))
+ ctx.AddDependency(ctx.Module(), generatedFilesystemDepTag, generatedModuleNameForPartition(ctx.Config(), partitionType))
}
}
@@ -228,6 +492,11 @@
}
f.HideFromMake()
+ content := generateBpContent(ctx, "system")
+ generatedBp := android.PathForOutput(ctx, "soong_generated_product_config.bp")
+ android.WriteFileRule(ctx, generatedBp, content)
+ ctx.Phony("product_config_to_bp", generatedBp)
+
var diffTestFiles []android.Path
for _, partitionType := range f.properties.Generated_partition_types {
diffTestFiles = append(diffTestFiles, f.createDiffTest(ctx, partitionType))
@@ -237,3 +506,37 @@
}
ctx.Phony("soong_generated_filesystem_tests", diffTestFiles...)
}
+
+func generateBpContent(ctx android.EarlyModuleContext, partitionType string) string {
+ // Currently only system partition is supported
+ if partitionType != "system" {
+ return ""
+ }
+
+ baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
+ fsProps, _ := generateFsProps(ctx, partitionType)
+
+ deps := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps
+ depProps := &android.PackagingProperties{
+ Deps: android.NewSimpleConfigurable(fullyQualifiedModuleNames(deps[partitionType])),
+ }
+
+ result, err := proptools.RepackProperties([]interface{}{baseProps, fsProps, depProps})
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ }
+
+ file := &parser.File{
+ Defs: []parser.Definition{
+ &parser.Module{
+ Type: "module",
+ Map: *result,
+ },
+ },
+ }
+ bytes, err := parser.Print(file)
+ if err != nil {
+ ctx.ModuleErrorf(err.Error())
+ }
+ return strings.TrimSpace(string(bytes))
+}
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 554b66b..484cc38 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -17,6 +17,7 @@
import (
"android/soong/android"
"android/soong/filesystem"
+ "android/soong/java"
"testing"
"github.com/google/blueprint/proptools"
@@ -28,6 +29,7 @@
result := android.GroupFixturePreparers(
android.PrepareForIntegrationTestWithAndroid,
android.PrepareForTestWithAndroidBuildComponents,
+ android.PrepareForTestWithAllowMissingDependencies,
filesystem.PrepareForTestWithFilesystemBuildComponents,
prepareForTestWithFsgenBuildComponents,
android.FixtureModifyConfig(func(config android.Config) {
@@ -86,3 +88,132 @@
proptools.String(fooSystem.FsProps().Type),
)
}
+
+func TestFileSystemCreatorSetPartitionDeps(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ android.PrepareForTestWithAndroidBuildComponents,
+ android.PrepareForTestWithAllowMissingDependencies,
+ filesystem.PrepareForTestWithFilesystemBuildComponents,
+ prepareForTestWithFsgenBuildComponents,
+ java.PrepareForTestWithJavaBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"bar", "baz"}
+ config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables =
+ map[string]android.PartitionQualifiedVariablesType{
+ "system": {
+ BoardFileSystemType: "ext4",
+ },
+ }
+ }),
+ android.FixtureMergeMockFs(android.MockFS{
+ "external/avb/test/data/testkey_rsa4096.pem": nil,
+ "build/soong/fsgen/Android.bp": []byte(`
+ soong_filesystem_creator {
+ name: "foo",
+ }
+ `),
+ }),
+ ).RunTestWithBp(t, `
+ java_library {
+ name: "bar",
+ srcs: ["A.java"],
+ }
+ java_library {
+ name: "baz",
+ srcs: ["A.java"],
+ product_specific: true,
+ }
+ `)
+
+ android.AssertBoolEquals(
+ t,
+ "Generated system image expected to depend on system partition installed \"bar\"",
+ true,
+ java.CheckModuleHasDependency(t, result.TestContext, "test_product_generated_system_image", "android_common", "bar"),
+ )
+ android.AssertBoolEquals(
+ t,
+ "Generated system image expected to not depend on product partition installed \"baz\"",
+ false,
+ java.CheckModuleHasDependency(t, result.TestContext, "test_product_generated_system_image", "android_common", "baz"),
+ )
+}
+
+func TestFileSystemCreatorDepsWithNamespace(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ android.PrepareForIntegrationTestWithAndroid,
+ android.PrepareForTestWithAndroidBuildComponents,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithNamespace,
+ android.PrepareForTestWithArchMutator,
+ filesystem.PrepareForTestWithFilesystemBuildComponents,
+ prepareForTestWithFsgenBuildComponents,
+ java.PrepareForTestWithJavaBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.ProductPackages = []string{"bar"}
+ config.TestProductVariables.NamespacesToExport = []string{"a/b"}
+ config.TestProductVariables.PartitionVarsForSoongMigrationOnlyDoNotUse.PartitionQualifiedVariables =
+ map[string]android.PartitionQualifiedVariablesType{
+ "system": {
+ BoardFileSystemType: "ext4",
+ },
+ }
+ config.Targets[android.Android] = []android.Target{
+ {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: "", HostCross: false},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: "", HostCross: false},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86_64", NativeBridgeRelativePath: "arm64", HostCross: false},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridge: android.NativeBridgeEnabled, NativeBridgeHostArchName: "x86", NativeBridgeRelativePath: "arm", HostCross: false},
+ }
+ }),
+ android.FixtureMergeMockFs(android.MockFS{
+ "external/avb/test/data/testkey_rsa4096.pem": nil,
+ "build/soong/fsgen/Android.bp": []byte(`
+ soong_filesystem_creator {
+ name: "foo",
+ }
+ `),
+ "a/b/Android.bp": []byte(`
+ soong_namespace{
+ }
+ java_library {
+ name: "bar",
+ srcs: ["A.java"],
+ compile_multilib: "64",
+ }
+ `),
+ "c/d/Android.bp": []byte(`
+ soong_namespace{
+ }
+ java_library {
+ name: "bar",
+ srcs: ["A.java"],
+ }
+ `),
+ }),
+ ).RunTest(t)
+
+ var packagingProps android.PackagingProperties
+ for _, prop := range result.ModuleForTests("test_product_generated_system_image", "android_common").Module().GetProperties() {
+ if packagingPropStruct, ok := prop.(*android.PackagingProperties); ok {
+ packagingProps = *packagingPropStruct
+ }
+ }
+ moduleDeps := packagingProps.Multilib.Lib64.Deps
+
+ eval := result.ModuleForTests("test_product_generated_system_image", "android_common").Module().ConfigurableEvaluator(android.PanickingConfigAndErrorContext(result.TestContext))
+ android.AssertStringListContains(
+ t,
+ "Generated system image expected to depend on \"bar\" defined in \"a/b\" namespace",
+ moduleDeps.GetOrDefault(eval, nil),
+ "//a/b:bar",
+ )
+ android.AssertStringListDoesNotContain(
+ t,
+ "Generated system image expected to not depend on \"bar\" defined in \"c/d\" namespace",
+ moduleDeps.GetOrDefault(eval, nil),
+ "//c/d:bar",
+ )
+}
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index a059837..42fd228 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -44,6 +44,32 @@
UnknownFramework Framework = "unknownframework"
)
+func (f Framework) Variant() string {
+ switch f {
+ case AFL:
+ return "afl"
+ case LibFuzzer:
+ return "libfuzzer"
+ case Jazzer:
+ return "jazzer"
+ default:
+ panic(fmt.Errorf("unknown fuzzer %q when getting variant", f))
+ }
+}
+
+func FrameworkFromVariant(v string) Framework {
+ switch v {
+ case "afl":
+ return AFL
+ case "libfuzzer":
+ return LibFuzzer
+ case "jazzer":
+ return Jazzer
+ default:
+ panic(fmt.Errorf("unknown variant %q when getting fuzzer", v))
+ }
+}
+
var BoolDefault = proptools.BoolDefault
type FuzzModule struct {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8721f15..f2a761c 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -63,7 +63,7 @@
ctx.RegisterModuleType("genrule", GenRuleFactory)
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("genrule_tool_deps", toolDepsMutator).Parallel()
+ ctx.BottomUp("genrule_tool_deps", toolDepsMutator)
})
}
@@ -219,6 +219,7 @@
// For nsjail tasks
useNsjail bool
+ dirSrcs android.Paths
}
func (g *Module) GeneratedSourceFiles() android.Paths {
@@ -579,10 +580,12 @@
}
if task.useNsjail {
- for _, input := range task.in {
- // can fail if input is a file.
+ for _, input := range task.dirSrcs {
+ cmd.Implicit(input)
if paths, err := ctx.GlobWithDeps(filepath.Join(input.String(), "**/*"), nil); err == nil {
rule.NsjailImplicits(android.PathsForSource(ctx, paths))
+ } else {
+ ctx.PropertyErrorf("dir_srcs", "can't glob %q", input.String())
}
}
}
@@ -645,6 +648,12 @@
}
g.setOutputFiles(ctx)
+
+ if ctx.Os() == android.Windows {
+ // Make doesn't support windows:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/module_arch_supported.mk;l=66;drc=f264690860bb6ee7762784d6b7201aae057ba6f2
+ g.HideFromMake()
+ }
}
func (g *Module) setOutputFiles(ctx android.ModuleContext) {
@@ -852,6 +861,12 @@
taskGenerator := func(ctx android.ModuleContext, rawCommand string, srcFiles android.Paths) []generateTask {
useNsjail := Bool(properties.Use_nsjail)
+ dirSrcs := android.DirectoryPathsForModuleSrc(ctx, properties.Dir_srcs)
+ if len(dirSrcs) > 0 && !useNsjail {
+ ctx.PropertyErrorf("dir_srcs", "can't use dir_srcs if use_nsjail is false")
+ return nil
+ }
+
outs := make(android.WritablePaths, len(properties.Out))
for i, out := range properties.Out {
outs[i] = android.PathForModuleGen(ctx, out)
@@ -862,6 +877,7 @@
genDir: android.PathForModuleGen(ctx),
cmd: rawCommand,
useNsjail: useNsjail,
+ dirSrcs: dirSrcs,
}}
}
@@ -878,6 +894,10 @@
type genRuleProperties struct {
Use_nsjail *bool
+ // List of input directories. Can be set only when use_nsjail is true. Currently, usage of
+ // dir_srcs is limited only to Trusty build.
+ Dir_srcs []string `android:"path"`
+
// names of the output files that will be generated
Out []string `android:"arch_variant"`
}
diff --git a/go.mod b/go.mod
index aa43066..57b59c0 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module android/soong
-go 1.22
+go 1.23
require (
github.com/google/blueprint v0.0.0
diff --git a/go.work b/go.work
index 46a135b..e538915 100644
--- a/go.work
+++ b/go.work
@@ -1,4 +1,4 @@
-go 1.22
+go 1.23
use (
.
diff --git a/java/app_import.go b/java/app_import.go
index a54cf2f..f5d9f3e 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -61,6 +61,9 @@
func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_app_import", AndroidAppImportFactory)
ctx.RegisterModuleType("android_test_import", AndroidTestImportFactory)
+ ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("disable_prebuilts_without_apk", disablePrebuiltsWithoutApkMutator)
+ })
}
type AndroidAppImport struct {
@@ -90,7 +93,7 @@
type AndroidAppImportProperties struct {
// A prebuilt apk to import
- Apk *string `android:"path"`
+ Apk proptools.Configurable[string] `android:"path,replace_instead_of_append"`
// The name of a certificate in the default certificate directory or an android_app_certificate
// module name in the form ":module". Should be empty if presigned or default_dev_cert is set.
@@ -193,13 +196,6 @@
}
}
}
-
- if String(a.properties.Apk) == "" {
- // Disable this module since the apk property is still empty after processing all matching
- // variants. This likely means there is no matching variant, and the default variant doesn't
- // have an apk property value either.
- a.Disable()
- }
}
func MergePropertiesFromVariant(ctx android.EarlyModuleContext,
@@ -219,6 +215,30 @@
}
}
+// disablePrebuiltsWithoutApkMutator is a pre-arch mutator that disables AndroidAppImport or
+// AndroidTestImport modules that don't have an apk set. We need this separate mutator instead
+// of doing it in processVariants because processVariants is a defaultable hook, and configurable
+// properties can only be evaluated after the defaults (and eventually, base configurabtion)
+// mutators.
+func disablePrebuiltsWithoutApkMutator(ctx android.BottomUpMutatorContext) {
+ switch a := ctx.Module().(type) {
+ case *AndroidAppImport:
+ if a.properties.Apk.GetOrDefault(ctx, "") == "" {
+ // Disable this module since the apk property is still empty after processing all
+ // matching variants. This likely means there is no matching variant, and the default
+ // variant doesn't have an apk property value either.
+ a.Disable()
+ }
+ case *AndroidTestImport:
+ if a.properties.Apk.GetOrDefault(ctx, "") == "" {
+ // Disable this module since the apk property is still empty after processing all
+ // matching variants. This likely means there is no matching variant, and the default
+ // variant doesn't have an apk property value either.
+ a.Disable()
+ }
+ }
+}
+
func (a *AndroidAppImport) DepsMutator(ctx android.BottomUpMutatorContext) {
cert := android.SrcIsModule(String(a.properties.Certificate))
if cert != "" {
@@ -409,7 +429,7 @@
if apexInfo.IsForPlatform() {
a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
- artifactPath := android.PathForModuleSrc(ctx, *a.properties.Apk)
+ artifactPath := android.PathForModuleSrc(ctx, a.properties.Apk.GetOrDefault(ctx, ""))
a.provenanceMetaDataFile = provenance.GenerateArtifactProvenanceMetaData(ctx, artifactPath, a.installPath)
}
@@ -633,7 +653,7 @@
android.InitApexModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
- android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
+ android.InitConfigurablePrebuiltModuleString(module, &module.properties.Apk, "Apk")
module.usesLibrary.enforce = true
@@ -686,7 +706,7 @@
android.InitApexModule(module)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
- android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
+ android.InitConfigurablePrebuiltModuleString(module, &module.properties.Apk, "Apk")
return module
}
diff --git a/java/bootclasspath.go b/java/bootclasspath.go
index 029f6f6..3413cf3 100644
--- a/java/bootclasspath.go
+++ b/java/bootclasspath.go
@@ -29,7 +29,7 @@
func registerBootclasspathBuildComponents(ctx android.RegistrationContext) {
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator).Parallel()
+ ctx.BottomUp("bootclasspath_deps", bootclasspathDepsMutator)
})
}
diff --git a/java/builder.go b/java/builder.go
index e5d5109..895ddb6 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -301,7 +301,7 @@
gatherReleasedFlaggedApisRule = pctx.AndroidStaticRule("gatherReleasedFlaggedApisRule",
blueprint.RuleParams{
- Command: `${aconfig} dump-cache --dedup --format='{fully_qualified_name}={state:bool}' ` +
+ Command: `${aconfig} dump-cache --dedup --format='{fully_qualified_name}' ` +
`--out ${out} ` +
`${flags_path} ` +
`${filter_args} `,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 5c69ff1..8c60d23 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -465,7 +465,7 @@
ctx.RegisterParallelSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory)
ctx.RegisterModuleType("art_boot_images", artBootImagesFactory)
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator).Parallel()
+ ctx.BottomUp("dex_bootjars_deps", DexpreoptBootJarsMutator)
})
}
@@ -1442,7 +1442,7 @@
func (dbj *artBootImages) DepsMutator(ctx android.BottomUpMutatorContext) {
// Create a dependency on `dex_bootjars` to access the intermediate locations of host art boot image.
- ctx.AddDependency(ctx.Module(), dexpreoptBootJarDepTag, "dex_bootjars")
+ ctx.AddVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(), dexpreoptBootJarDepTag, "dex_bootjars")
}
func (d *artBootImages) GenerateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/java.go b/java/java.go
index d972887..288042b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -70,9 +70,9 @@
// established, to not get the dependencies split into the wrong variants and
// to support the checks in dexpreoptDisabled().
ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel()
+ ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator)
// needs access to ApexInfoProvider which is available after variant creation
- ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel()
+ ctx.BottomUp("jacoco_deps", jacocoDepsMutator)
})
ctx.RegisterParallelSingletonType("kythe_java_extract", kytheExtractJavaFactory)
@@ -2454,7 +2454,7 @@
ret := []string{}
ret = append(ret, al.properties.Libs.GetOrDefault(ctx, nil)...)
ret = append(ret, al.properties.Static_libs.GetOrDefault(ctx, nil)...)
- if al.properties.System_modules != nil {
+ if proptools.StringDefault(al.properties.System_modules, "none") != "none" {
ret = append(ret, proptools.String(al.properties.System_modules))
}
// Other non java_library dependencies like java_api_contribution are ignored for now.
diff --git a/java/jdeps_test.go b/java/jdeps_test.go
index 7a0fb10..1435000 100644
--- a/java/jdeps_test.go
+++ b/java/jdeps_test.go
@@ -134,3 +134,42 @@
android.AssertStringListContains(t, "IdeInfo.Deps should contain versioned sdk module", dpInfo.Deps, "sdk_public_29_android")
}
+
+func TestDoNotAddNoneSystemModulesToDeps(t *testing.T) {
+ ctx := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureMergeEnv(
+ map[string]string{
+ "DISABLE_STUB_VALIDATION": "true",
+ },
+ ),
+ ).RunTestWithBp(t,
+ `
+ java_library {
+ name: "javalib",
+ srcs: ["foo.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+
+ java_api_library {
+ name: "javalib.stubs",
+ stubs_type: "everything",
+ api_contributions: ["javalib-current.txt"],
+ api_surface: "public",
+ system_modules: "none",
+ }
+ java_api_contribution {
+ name: "javalib-current.txt",
+ api_file: "javalib-current.txt",
+ api_surface: "public",
+ }
+ `)
+ javalib := ctx.ModuleForTests("javalib", "android_common").Module().(*Library)
+ dpInfo, _ := android.OtherModuleProvider(ctx, javalib, android.IdeInfoProviderKey)
+ android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
+
+ javalib_stubs := ctx.ModuleForTests("javalib.stubs", "android_common").Module().(*ApiLibrary)
+ dpInfo, _ = android.OtherModuleProvider(ctx, javalib_stubs, android.IdeInfoProviderKey)
+ android.AssertStringListDoesNotContain(t, "IdeInfo.Deps should contain not contain `none`", dpInfo.Deps, "none")
+}
diff --git a/rust/rust.go b/rust/rust.go
index a044a99..b22ebf7 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -47,11 +47,11 @@
func registerPreDepsMutators(ctx android.RegisterMutatorsContext) {
ctx.Transition("rust_libraries", &libraryTransitionMutator{})
ctx.Transition("rust_stdlinkage", &libstdTransitionMutator{})
- ctx.BottomUp("rust_begin", BeginMutator).Parallel()
+ ctx.BottomUp("rust_begin", BeginMutator)
}
func registerPostDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator).Parallel()
+ ctx.BottomUp("rust_sanitizers", rustSanitizerRuntimeMutator)
}
type Flags struct {
diff --git a/scripts/keep-flagged-apis.sh b/scripts/keep-flagged-apis.sh
index 9c48fdb..48efb7a 100755
--- a/scripts/keep-flagged-apis.sh
+++ b/scripts/keep-flagged-apis.sh
@@ -25,21 +25,12 @@
# Convert the list of feature flags in the input file to Metalava options
# of the form `--revert-annotation !android.annotation.FlaggedApi("<flag>")`
# to prevent the annotated APIs from being hidden, i.e. include the annotated
-# APIs in the SDK snapshots. This also preserves the line comments, they will
-# be ignored by Metalava but might be useful when debugging.
+# APIs in the SDK snapshots.
while read -r line; do
- key=$(echo "$line" | cut -d= -f1)
- value=$(echo "$line" | cut -d= -f2)
-
- # Skip if value is not true and line does not start with '#'
- if [[ ( $value != "true" ) && ( $line =~ ^[^#] )]]; then
- continue
- fi
-
# Escape and quote the key for sed
- escaped_key=$(echo "$key" | sed "s/'/\\\'/g; s/ /\\ /g")
+ escaped_line=$(echo "$line" | sed "s/'/\\\'/g; s/ /\\ /g")
- echo $line | sed "s|^[^#].*$|--revert-annotation '!$FLAGGED(\"$escaped_key\")'|"
+ echo "--revert-annotation '!$FLAGGED(\"$escaped_line\")'"
done < "$FLAGS"
# Revert all flagged APIs, unless listed above.
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index 2ec8972..a8044df 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -16,6 +16,8 @@
import (
"strings"
+
+ "android/soong/android"
)
var androidmk_denylist []string = []string{
@@ -64,3 +66,29 @@
}
}
}
+
+// The Android.mk files in these directories are for NDK build system.
+var external_ndk_androidmks []string = []string{
+ "external/fmtlib/",
+ "external/google-breakpad/",
+ "external/googletest/",
+ "external/libaom/",
+ "external/libusb/",
+ "external/libvpx/",
+ "external/libwebm/",
+ "external/libwebsockets/",
+ "external/vulkan-validation-layers/",
+ "external/walt/",
+ "external/webp/",
+}
+
+func ignoreNdkAndroidMks(androidMks []string) []string {
+ return android.FilterListPred(androidMks, func(s string) bool {
+ for _, d := range external_ndk_androidmks {
+ if strings.HasPrefix(s, d) {
+ return false
+ }
+ }
+ return true
+ })
+}
diff --git a/ui/build/finder.go b/ui/build/finder.go
index 573df21..a899822 100644
--- a/ui/build/finder.go
+++ b/ui/build/finder.go
@@ -128,6 +128,7 @@
// Stop searching a subdirectory recursively after finding an Android.mk.
androidMks := f.FindFirstNamedAt(".", "Android.mk")
+ androidMks = ignoreNdkAndroidMks(androidMks)
blockAndroidMks(ctx, androidMks)
err := dumpListToFile(ctx, config, androidMks, filepath.Join(dumpDir, "Android.mk.list"))
if err != nil {