summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/Android.bp3
-rw-r--r--android/android_info.go91
-rw-r--r--android/apex.go2
-rw-r--r--android/apex_contributions.go12
-rw-r--r--android/base_module_context.go20
-rw-r--r--android/build_prop.go33
-rw-r--r--android/build_prop_test.go41
-rw-r--r--android/config.go87
-rw-r--r--android/config_test.go45
-rw-r--r--android/dirgroup.go3
-rw-r--r--android/filegroup_test.go46
-rw-r--r--android/init.go1
-rw-r--r--android/module.go31
-rw-r--r--android/module_context.go49
-rw-r--r--android/module_proxy.go16
-rw-r--r--android/mutator.go26
-rw-r--r--android/neverallow.go44
-rw-r--r--android/neverallow_test.go28
-rw-r--r--android/packaging.go216
-rw-r--r--android/path_properties.go23
-rw-r--r--android/paths.go72
-rw-r--r--android/paths_test.go6
-rw-r--r--android/prebuilt.go2
-rw-r--r--android/register.go1
-rw-r--r--android/rule_builder.go60
-rw-r--r--android/singleton.go29
-rw-r--r--android/util.go10
-rw-r--r--android/variable.go39
-rw-r--r--android/vintf_data.go171
29 files changed, 992 insertions, 215 deletions
diff --git a/android/Android.bp b/android/Android.bp
index 1ed2dbaa1..a9a3564ab 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -31,6 +31,7 @@ bootstrap_go_package {
srcs: [
"aconfig_providers.go",
"all_teams.go",
+ "android_info.go",
"androidmk.go",
"apex.go",
"apex_contributions.go",
@@ -111,6 +112,7 @@ bootstrap_go_package {
"util.go",
"variable.go",
"vintf_fragment.go",
+ "vintf_data.go",
"visibility.go",
],
testSrcs: [
@@ -120,6 +122,7 @@ bootstrap_go_package {
"apex_test.go",
"arch_test.go",
"blueprint_e2e_test.go",
+ "build_prop_test.go",
"config_test.go",
"configured_jars_test.go",
"csuite_config_test.go",
diff --git a/android/android_info.go b/android/android_info.go
new file mode 100644
index 000000000..a8d3d4e2c
--- /dev/null
+++ b/android/android_info.go
@@ -0,0 +1,91 @@
+// Copyright 2024 The Android Open Source Project
+//
+// 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"
+)
+
+var (
+ mergeAndRemoveComments = pctx.AndroidStaticRule("merge_and_remove_comments",
+ blueprint.RuleParams{
+ Command: "cat $in | grep -v '#' > $out",
+ },
+ )
+ androidInfoTxtToProp = pctx.AndroidStaticRule("android_info_txt_to_prop",
+ blueprint.RuleParams{
+ Command: "grep 'require version-' $in | sed -e 's/require version-/ro.build.expect./g' > $out",
+ },
+ )
+)
+
+type androidInfoProperties struct {
+ // Name of output file. Defaults to module name
+ Stem *string
+
+ // Paths of board-info.txt files.
+ Board_info_files []string `android:"path"`
+
+ // Name of bootloader board. If board_info_files is empty, `board={bootloader_board_name}` will
+ // be printed to output. Ignored if board_info_files is not empty.
+ Bootloader_board_name *string
+}
+
+type androidInfoModule struct {
+ ModuleBase
+
+ properties androidInfoProperties
+}
+
+func (p *androidInfoModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ if len(p.properties.Board_info_files) > 0 && p.properties.Bootloader_board_name != nil {
+ ctx.ModuleErrorf("Either Board_info_files or Bootloader_board_name should be set. Please remove one of them\n")
+ return
+ }
+ androidInfoTxtName := proptools.StringDefault(p.properties.Stem, ctx.ModuleName()+".txt")
+ androidInfoTxt := PathForModuleOut(ctx, androidInfoTxtName)
+ androidInfoProp := androidInfoTxt.ReplaceExtension(ctx, "prop")
+
+ if boardInfoFiles := PathsForModuleSrc(ctx, p.properties.Board_info_files); len(boardInfoFiles) > 0 {
+ ctx.Build(pctx, BuildParams{
+ Rule: mergeAndRemoveComments,
+ Inputs: boardInfoFiles,
+ Output: androidInfoTxt,
+ })
+ } else if bootloaderBoardName := proptools.String(p.properties.Bootloader_board_name); bootloaderBoardName != "" {
+ WriteFileRule(ctx, androidInfoTxt, "board="+bootloaderBoardName)
+ } else {
+ WriteFileRule(ctx, androidInfoTxt, "")
+ }
+
+ // Create android_info.prop
+ ctx.Build(pctx, BuildParams{
+ Rule: androidInfoTxtToProp,
+ Input: androidInfoTxt,
+ Output: androidInfoProp,
+ })
+
+ ctx.SetOutputFiles(Paths{androidInfoProp}, "")
+}
+
+// android_info module generate a file named android-info.txt that contains various information
+// about the device we're building for. This file is typically packaged up with everything else.
+func AndroidInfoFactory() Module {
+ module := &androidInfoModule{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ return module
+}
diff --git a/android/apex.go b/android/apex.go
index 79ab13caf..e73b3e662 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -833,7 +833,7 @@ func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) {
// If this is the FinalModule (last visited module) copy
// AnyVariantDirectlyInAnyApex to all the other variants
- if am == mctx.FinalModule().(ApexModule) {
+ if mctx.IsFinalModule(am) {
mctx.VisitAllModuleVariants(func(variant Module) {
variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex =
base.ApexProperties.AnyVariantDirectlyInAnyApex
diff --git a/android/apex_contributions.go b/android/apex_contributions.go
index 4cd8dda93..ce3427840 100644
--- a/android/apex_contributions.go
+++ b/android/apex_contributions.go
@@ -26,7 +26,7 @@ func init() {
func RegisterApexContributionsBuildComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("apex_contributions", apexContributionsFactory)
ctx.RegisterModuleType("apex_contributions_defaults", apexContributionsDefaultsFactory)
- ctx.RegisterSingletonModuleType("all_apex_contributions", allApexContributionsFactory)
+ ctx.RegisterModuleType("all_apex_contributions", allApexContributionsFactory)
}
type apexContributions struct {
@@ -87,10 +87,10 @@ func apexContributionsDefaultsFactory() Module {
// Based on product_config, it will create a dependency on the selected
// apex_contributions per mainline module
type allApexContributions struct {
- SingletonModuleBase
+ ModuleBase
}
-func allApexContributionsFactory() SingletonModule {
+func allApexContributionsFactory() Module {
module := &allApexContributions{}
InitAndroidModule(module)
return module
@@ -191,7 +191,7 @@ func (p *PrebuiltSelectionInfoMap) GetSelectedModulesForApiDomain(apiDomain stri
// This module type does not have any build actions.
func (a *allApexContributions) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-func (a *allApexContributions) GenerateSingletonBuildActions(ctx SingletonContext) {
+ if ctx.ModuleName() != "all_apex_contributions" {
+ ctx.ModuleErrorf("There can only be 1 all_apex_contributions module in build/soong")
+ }
}
diff --git a/android/base_module_context.go b/android/base_module_context.go
index 7fa58766f..060fae5bc 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -88,6 +88,10 @@ type BaseModuleContext interface {
// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
+ // OtherModuleIsAutoGenerated returns true if the module is auto generated by another module
+ // instead of being defined in Android.bp file.
+ OtherModuleIsAutoGenerated(m blueprint.Module) bool
+
// Provider returns the value for a provider for the current module. If the value is
// not set it returns nil and false. It panics if called before the appropriate
// mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
@@ -194,9 +198,15 @@ type BaseModuleContext interface {
// singleton actions that are only done once for all variants of a module.
FinalModule() Module
+ // IsFinalModule returns if the current module is the last variant. Variants of a module are always visited in
+ // order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
+ // variants using VisitAllModuleVariants if the current module is the last one. This can be used to perform
+ // singleton actions that are only done once for all variants of a module.
+ IsFinalModule(module Module) bool
+
// VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always
// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
- // from all variants if the current module == FinalModule(). Otherwise, care must be taken to not access any
+ // from all variants if the current module is the last one. Otherwise, care must be taken to not access any
// data modified by the current mutator.
VisitAllModuleVariants(visit func(Module))
@@ -276,6 +286,10 @@ func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blu
return b.bp.OtherModuleProvider(m, provider)
}
+func (b *baseModuleContext) OtherModuleIsAutoGenerated(m blueprint.Module) bool {
+ return b.bp.OtherModuleIsAutoGenerated(m)
+}
+
func (b *baseModuleContext) provider(provider blueprint.AnyProviderKey) (any, bool) {
return b.bp.Provider(provider)
}
@@ -584,6 +598,10 @@ func (b *baseModuleContext) FinalModule() Module {
return b.bp.FinalModule().(Module)
}
+func (b *baseModuleContext) IsFinalModule(module Module) bool {
+ return b.bp.IsFinalModule(module)
+}
+
// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
if tag == licenseKindTag {
diff --git a/android/build_prop.go b/android/build_prop.go
index 7c3c50645..838947045 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -19,8 +19,12 @@ import (
)
func init() {
- ctx := InitRegistrationContext
+ registerBuildPropComponents(InitRegistrationContext)
+}
+
+func registerBuildPropComponents(ctx RegistrationContext) {
ctx.RegisterModuleType("build_prop", BuildPropFactory)
+ ctx.RegisterModuleType("android_info", AndroidInfoFactory)
}
type buildPropProperties struct {
@@ -38,6 +42,10 @@ type buildPropProperties struct {
// Path to a JSON file containing product configs.
Product_config *string `android:"path"`
+ // Path to android-info.txt file containing board specific info.
+ // This is empty for build.prop of all partitions except vendor.
+ Android_info *string `android:"path"`
+
// Optional subdirectory under which this file is installed into
Relative_install_path *string
}
@@ -66,7 +74,10 @@ func (p *buildPropModule) propFiles(ctx ModuleContext) Paths {
} else if partition == "odm" {
return ctx.Config().OdmPropFiles(ctx)
} else if partition == "vendor" {
- // TODO (b/375500423): Add android-info.txt to prop files
+ if p.properties.Android_info != nil {
+ androidInfo := PathForModuleSrc(ctx, proptools.String(p.properties.Android_info))
+ return append(ctx.Config().VendorPropFiles(ctx), androidInfo)
+ }
return ctx.Config().VendorPropFiles(ctx)
}
return nil
@@ -98,6 +109,12 @@ func (p *buildPropModule) partition(config DeviceConfig) string {
return "product"
} else if p.SystemExtSpecific() {
return "system_ext"
+ } else if p.InstallInSystemDlkm() {
+ return "system_dlkm"
+ } else if p.InstallInVendorDlkm() {
+ return "vendor_dlkm"
+ } else if p.InstallInOdmDlkm() {
+ return "odm_dlkm"
}
return "system"
}
@@ -108,16 +125,18 @@ var validPartitions = []string{
"product",
"odm",
"vendor",
+ "system_dlkm",
+ "vendor_dlkm",
+ "odm_dlkm",
}
func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
- p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
- if !ctx.Config().KatiEnabled() {
- WriteFileRule(ctx, p.outputFilePath, "# no build.prop if kati is disabled")
- ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
- return
+ if !p.SocSpecific() && p.properties.Android_info != nil {
+ ctx.ModuleErrorf("Android_info cannot be set if build.prop is not installed in vendor partition")
}
+ p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
+
partition := p.partition(ctx.DeviceConfig())
if !InList(partition, validPartitions) {
ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions)
diff --git a/android/build_prop_test.go b/android/build_prop_test.go
new file mode 100644
index 000000000..e75975a0a
--- /dev/null
+++ b/android/build_prop_test.go
@@ -0,0 +1,41 @@
+// 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 (
+ "testing"
+)
+
+func TestPropFileInputs(t *testing.T) {
+ bp := `
+build_prop {
+ name: "vendor-build.prop",
+ stem: "build.prop",
+ vendor: true,
+ android_info: ":board-info",
+ //product_config: ":product_config",
+}
+android_info {
+ name: "board-info",
+ stem: "android-info.txt",
+}
+`
+
+ res := GroupFixturePreparers(
+ FixtureRegisterWithContext(registerBuildPropComponents),
+ ).RunTestWithBp(t, bp)
+ buildPropCmd := res.ModuleForTests("vendor-build.prop", "").Rule("vendor-build.prop_.vendor-build.prop").RuleParams.Command
+ AssertStringDoesContain(t, "Could not find android-info in prop files of vendor build.prop", buildPropCmd, "--prop-files=out/soong/.intermediates/board-info/android-info.prop")
+}
diff --git a/android/config.go b/android/config.go
index feed22f6a..d9db64ef6 100644
--- a/android/config.go
+++ b/android/config.go
@@ -413,18 +413,21 @@ type jsonConfigurable interface {
// To add a new feature to the list, add the field in the struct
// `partialCompileFlags` above, and then add the name of the field in the
// switch statement below.
-func (c *config) parsePartialCompileFlags() (partialCompileFlags, error) {
- defaultFlags := partialCompileFlags{
- // Set any opt-out flags here. Opt-in flags are off by default.
- enabled: false,
+var defaultPartialCompileFlags = partialCompileFlags{
+ // Set any opt-out flags here. Opt-in flags are off by default.
+ enabled: false,
+}
+
+func (c *config) parsePartialCompileFlags(isEngBuild bool) (partialCompileFlags, error) {
+ if !isEngBuild {
+ return partialCompileFlags{}, nil
}
value := c.Getenv("SOONG_PARTIAL_COMPILE")
-
if value == "" {
- return defaultFlags, nil
+ return defaultPartialCompileFlags, nil
}
- ret := defaultFlags
+ ret := defaultPartialCompileFlags
tokens := strings.Split(strings.ToLower(value), ",")
makeVal := func(state string, defaultValue bool) bool {
switch state {
@@ -455,17 +458,17 @@ func (c *config) parsePartialCompileFlags() (partialCompileFlags, error) {
}
switch tok {
case "true":
- ret = defaultFlags
+ ret = defaultPartialCompileFlags
ret.enabled = true
case "false":
// Set everything to false.
ret = partialCompileFlags{}
case "enabled":
- ret.enabled = makeVal(state, defaultFlags.enabled)
+ ret.enabled = makeVal(state, defaultPartialCompileFlags.enabled)
case "use_d8":
- ret.use_d8 = makeVal(state, defaultFlags.use_d8)
+ ret.use_d8 = makeVal(state, defaultPartialCompileFlags.use_d8)
default:
- return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", value)
+ return partialCompileFlags{}, fmt.Errorf("Unknown SOONG_PARTIAL_COMPILE value: %v", tok)
}
}
return ret, nil
@@ -616,6 +619,8 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error)
buildFromSourceStub: cmdArgs.BuildFromSourceStub,
}
+ variant, ok := os.LookupEnv("TARGET_BUILD_VARIANT")
+ isEngBuild := !ok || variant == "eng"
config.deviceConfig = &deviceConfig{
config: config,
@@ -657,7 +662,7 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error)
return Config{}, err
}
- config.partialCompileFlags, err = config.parsePartialCompileFlags()
+ config.partialCompileFlags, err = config.parsePartialCompileFlags(isEngBuild)
if err != nil {
return Config{}, err
}
@@ -862,7 +867,7 @@ func (c *config) IsEnvFalse(key string) bool {
}
func (c *config) TargetsJava21() bool {
- return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_21")
+ return c.productVariables.GetBuildFlagBool("RELEASE_TARGET_JAVA_21")
}
// EnvDeps returns the environment variables this build depends on. The first
@@ -1517,6 +1522,13 @@ func (c *deviceConfig) VendorPath() string {
return "vendor"
}
+func (c *deviceConfig) VendorDlkmPath() string {
+ if c.config.productVariables.VendorDlkmPath != nil {
+ return *c.config.productVariables.VendorDlkmPath
+ }
+ return "vendor_dlkm"
+}
+
func (c *deviceConfig) BuildingVendorImage() bool {
return proptools.Bool(c.config.productVariables.BuildingVendorImage)
}
@@ -1544,6 +1556,17 @@ func (c *deviceConfig) OdmPath() string {
return "odm"
}
+func (c *deviceConfig) BuildingOdmImage() bool {
+ return proptools.Bool(c.config.productVariables.BuildingOdmImage)
+}
+
+func (c *deviceConfig) OdmDlkmPath() string {
+ if c.config.productVariables.OdmDlkmPath != nil {
+ return *c.config.productVariables.OdmDlkmPath
+ }
+ return "odm_dlkm"
+}
+
func (c *deviceConfig) ProductPath() string {
if c.config.productVariables.ProductPath != nil {
return *c.config.productVariables.ProductPath
@@ -1562,6 +1585,20 @@ func (c *deviceConfig) SystemExtPath() string {
return "system_ext"
}
+func (c *deviceConfig) SystemDlkmPath() string {
+ if c.config.productVariables.SystemDlkmPath != nil {
+ return *c.config.productVariables.SystemDlkmPath
+ }
+ return "system_dlkm"
+}
+
+func (c *deviceConfig) OemPath() string {
+ if c.config.productVariables.OemPath != nil {
+ return *c.config.productVariables.OemPath
+ }
+ return "oem"
+}
+
func (c *deviceConfig) BtConfigIncludeDir() string {
return String(c.config.productVariables.BtConfigIncludeDir)
}
@@ -2229,3 +2266,27 @@ func (c *config) BoardAvbSystemAddHashtreeFooterArgs() []string {
func (c Config) InstallApexSystemServerDexpreoptSamePartition() bool {
return c.config.productVariables.GetBuildFlagBool("RELEASE_INSTALL_APEX_SYSTEMSERVER_DEXPREOPT_SAME_PARTITION")
}
+
+func (c *config) DeviceMatrixFile() []string {
+ return c.productVariables.DeviceMatrixFile
+}
+
+func (c *config) ProductManifestFiles() []string {
+ return c.productVariables.ProductManifestFiles
+}
+
+func (c *config) SystemManifestFile() []string {
+ return c.productVariables.SystemManifestFile
+}
+
+func (c *config) SystemExtManifestFiles() []string {
+ return c.productVariables.SystemExtManifestFiles
+}
+
+func (c *config) DeviceManifestFiles() []string {
+ return c.productVariables.DeviceManifestFiles
+}
+
+func (c *config) OdmManifestFiles() []string {
+ return c.productVariables.OdmManifestFiles
+}
diff --git a/android/config_test.go b/android/config_test.go
index 773216844..adb5ffac5 100644
--- a/android/config_test.go
+++ b/android/config_test.go
@@ -212,3 +212,48 @@ func TestConfiguredJarList(t *testing.T) {
assertStringEquals(t, "apex1:jarA", list5.String())
})
}
+
+func (p partialCompileFlags) updateEnabled(value bool) partialCompileFlags {
+ p.enabled = value
+ return p
+}
+
+func (p partialCompileFlags) updateUseD8(value bool) partialCompileFlags {
+ p.use_d8 = value
+ return p
+}
+
+func TestPartialCompile(t *testing.T) {
+ mockConfig := func(value string) *config {
+ c := &config{
+ env: map[string]string{
+ "SOONG_PARTIAL_COMPILE": value,
+ },
+ }
+ return c
+ }
+ tests := []struct {
+ value string
+ isEngBuild bool
+ expected partialCompileFlags
+ }{
+ {"", true, defaultPartialCompileFlags},
+ {"false", true, partialCompileFlags{}},
+ {"true", true, defaultPartialCompileFlags.updateEnabled(true)},
+ {"true", false, partialCompileFlags{}},
+ {"true,use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(true)},
+ {"true,-use_d8", true, defaultPartialCompileFlags.updateEnabled(true).updateUseD8(false)},
+ {"use_d8,false", true, partialCompileFlags{}},
+ {"false,+use_d8", true, partialCompileFlags{}.updateUseD8(true)},
+ }
+
+ for _, test := range tests {
+ t.Run(test.value, func(t *testing.T) {
+ config := mockConfig(test.value)
+ flags, _ := config.parsePartialCompileFlags(test.isEngBuild)
+ if flags != test.expected {
+ t.Errorf("expected %v found %v", test.expected, flags)
+ }
+ })
+ }
+}
diff --git a/android/dirgroup.go b/android/dirgroup.go
index 20c4d13a6..62fbaa5c8 100644
--- a/android/dirgroup.go
+++ b/android/dirgroup.go
@@ -39,8 +39,7 @@ type dirGroup struct {
}
type DirInfo struct {
- // TODO(b/358302178): Use DirectoryPaths instead of Paths
- Dirs Paths
+ Dirs DirectoryPaths
}
var DirProvider = blueprint.NewProvider[DirInfo]()
diff --git a/android/filegroup_test.go b/android/filegroup_test.go
index 14e9368ca..670037d56 100644
--- a/android/filegroup_test.go
+++ b/android/filegroup_test.go
@@ -1,55 +1,9 @@
package android
import (
- "path/filepath"
"testing"
)
-func TestFileGroupWithPathProp(t *testing.T) {
- // TODO(b/247782695), TODO(b/242847534) Fix mixed builds for filegroups
- t.Skip("Re-enable once filegroups are corrected for mixed builds")
- outBaseDir := "outputbase"
- pathPrefix := outBaseDir + "/execroot/__main__"
- expectedOutputfile := filepath.Join(pathPrefix, "a/b/c/d/test.aidl")
-
- testCases := []struct {
- bp string
- rel string
- }{
- {
- bp: `
- filegroup {
- name: "baz",
- srcs: ["a/b/c/d/test.aidl"],
- path: "a/b",
- bazel_module: { label: "//:baz" },
- }
-`,
- rel: "c/d/test.aidl",
- },
- {
- bp: `
- filegroup {
- name: "baz",
- srcs: ["a/b/c/d/test.aidl"],
- bazel_module: { label: "//:baz" },
- }
-`,
- rel: "a/b/c/d/test.aidl",
- },
- }
-
- for _, testCase := range testCases {
- result := GroupFixturePreparers(
- PrepareForTestWithFilegroup,
- ).RunTestWithBp(t, testCase.bp)
-
- fg := result.Module("baz", "").(*fileGroup)
- AssertStringEquals(t, "src relativeRoot", testCase.rel, fg.srcs[0].Rel())
- AssertStringEquals(t, "src full path", expectedOutputfile, fg.srcs[0].String())
- }
-}
-
func TestFilegroupDefaults(t *testing.T) {
bp := FixtureAddTextFile("p/Android.bp", `
filegroup_defaults {
diff --git a/android/init.go b/android/init.go
index 1ace34494..d3a13d0ed 100644
--- a/android/init.go
+++ b/android/init.go
@@ -20,6 +20,7 @@ func init() {
gob.Register(extraFilesZip{})
gob.Register(InstallPath{})
gob.Register(ModuleGenPath{})
+ gob.Register(ModuleObjPath{})
gob.Register(ModuleOutPath{})
gob.Register(OutputPath{})
gob.Register(PhonyPath{})
diff --git a/android/module.go b/android/module.go
index 114843056..58ae885c8 100644
--- a/android/module.go
+++ b/android/module.go
@@ -81,10 +81,14 @@ type Module interface {
InstallInProduct() bool
InstallInVendor() bool
InstallInSystemExt() bool
+ InstallInSystemDlkm() bool
+ InstallInVendorDlkm() bool
+ InstallInOdmDlkm() bool
InstallForceOS() (*OsType, *ArchType)
PartitionTag(DeviceConfig) string
HideFromMake()
IsHideFromMake() bool
+ SkipInstall()
IsSkipInstall() bool
MakeUninstallable()
ReplacedByPrebuilt()
@@ -385,6 +389,15 @@ type commonProperties struct {
// Whether this module is installed to debug ramdisk
Debug_ramdisk *bool
+ // Install to partition system_dlkm when set to true.
+ System_dlkm_specific *bool
+
+ // Install to partition vendor_dlkm when set to true.
+ Vendor_dlkm_specific *bool
+
+ // Install to partition odm_dlkm when set to true.
+ Odm_dlkm_specific *bool
+
// Whether this module is built for non-native architectures (also known as native bridge binary)
Native_bridge_supported *bool `android:"arch_variant"`
@@ -1421,6 +1434,7 @@ func (m *ModuleBase) IsSkipInstall() bool {
func (m *ModuleBase) MakeUninstallable() {
m.commonProperties.UninstallableApexPlatformVariant = true
m.HideFromMake()
+ m.SkipInstall()
}
func (m *ModuleBase) ReplacedByPrebuilt() {
@@ -1533,6 +1547,18 @@ func (m *ModuleBase) InstallInRoot() bool {
return false
}
+func (m *ModuleBase) InstallInSystemDlkm() bool {
+ return Bool(m.commonProperties.System_dlkm_specific)
+}
+
+func (m *ModuleBase) InstallInVendorDlkm() bool {
+ return Bool(m.commonProperties.Vendor_dlkm_specific)
+}
+
+func (m *ModuleBase) InstallInOdmDlkm() bool {
+ return Bool(m.commonProperties.Odm_dlkm_specific)
+}
+
func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
return nil, nil
}
@@ -1820,6 +1846,8 @@ type CommonPropertiesProviderData struct {
Enabled bool
// Whether the module has been replaced by a prebuilt
ReplacedByPrebuilt bool
+ // The Target of artifacts that this module variant is responsible for creating.
+ CompileTarget Target
}
var CommonPropertiesProviderKey = blueprint.NewProvider[CommonPropertiesProviderData]()
@@ -2008,7 +2036,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
ctx.GetMissingDependencies()
}
- if m == ctx.FinalModule().(Module).base() {
+ if ctx.IsFinalModule(m.module) {
m.generateModuleTarget(ctx)
if ctx.Failed() {
return
@@ -2084,6 +2112,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
commonData := CommonPropertiesProviderData{
ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
+ CompileTarget: m.commonProperties.CompileTarget,
}
if m.commonProperties.ForcedDisabled {
commonData.Enabled = false
diff --git a/android/module_context.go b/android/module_context.go
index 9fa3a6211..41cb0ccb2 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -19,6 +19,7 @@ import (
"github.com/google/blueprint/depset"
"path"
"path/filepath"
+ "slices"
"strings"
"github.com/google/blueprint"
@@ -195,6 +196,9 @@ type ModuleContext interface {
InstallInOdm() bool
InstallInProduct() bool
InstallInVendor() bool
+ InstallInSystemDlkm() bool
+ InstallInVendorDlkm() bool
+ InstallInOdmDlkm() bool
InstallForceOS() (*OsType, *ArchType)
RequiredModuleNames(ctx ConfigurableEvaluatorContext) []string
@@ -492,15 +496,23 @@ func (m *moduleContext) InstallInVendor() bool {
return m.module.InstallInVendor()
}
+func (m *moduleContext) InstallInSystemDlkm() bool {
+ return m.module.InstallInSystemDlkm()
+}
+
+func (m *moduleContext) InstallInVendorDlkm() bool {
+ return m.module.InstallInVendorDlkm()
+}
+
+func (m *moduleContext) InstallInOdmDlkm() bool {
+ return m.module.InstallInOdmDlkm()
+}
+
func (m *moduleContext) skipInstall() bool {
if m.module.base().commonProperties.SkipInstall {
return true
}
- if m.module.base().commonProperties.HideFromMake {
- return true
- }
-
// We'll need a solution for choosing which of modules with the same name in different
// namespaces to install. For now, reuse the list of namespaces exported to Make as the
// list of namespaces to install in a Soong-only build.
@@ -519,6 +531,10 @@ func (m *moduleContext) requiresFullInstall() bool {
return false
}
+ if m.module.base().commonProperties.HideFromMake {
+ return false
+ }
+
if proptools.Bool(m.module.base().commonProperties.No_full_install) {
return false
}
@@ -562,9 +578,22 @@ func (m *moduleContext) setAconfigPaths(paths Paths) {
m.aconfigFilePaths = paths
}
+func (m *moduleContext) getOwnerAndOverrides() (string, []string) {
+ owner := m.ModuleName()
+ overrides := slices.Clone(m.Module().base().commonProperties.Overrides)
+ if b, ok := m.Module().(OverridableModule); ok {
+ if b.GetOverriddenBy() != "" {
+ // overriding variant of base module
+ overrides = append(overrides, m.ModuleName()) // com.android.foo
+ owner = m.Module().Name() // com.company.android.foo
+ }
+ }
+ return owner, overrides
+}
+
func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
licenseFiles := m.Module().EffectiveLicenseFiles()
- overrides := CopyOf(m.Module().base().commonProperties.Overrides)
+ owner, overrides := m.getOwnerAndOverrides()
spec := PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: srcPath,
@@ -576,7 +605,7 @@ func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, e
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
overrides: &overrides,
- owner: m.ModuleName(),
+ owner: owner,
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
@@ -695,7 +724,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src
m.installFiles = append(m.installFiles, fullInstallPath)
}
- overrides := CopyOf(m.Module().base().commonProperties.Overrides)
+ owner, overrides := m.getOwnerAndOverrides()
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -706,7 +735,7 @@ func (m *moduleContext) InstallSymlink(installPath InstallPath, name string, src
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
overrides: &overrides,
- owner: m.ModuleName(),
+ owner: owner,
})
return fullInstallPath
@@ -742,7 +771,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str
m.installFiles = append(m.installFiles, fullInstallPath)
}
- overrides := CopyOf(m.Module().base().commonProperties.Overrides)
+ owner, overrides := m.getOwnerAndOverrides()
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -753,7 +782,7 @@ func (m *moduleContext) InstallAbsoluteSymlink(installPath InstallPath, name str
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
overrides: &overrides,
- owner: m.ModuleName(),
+ owner: owner,
})
return fullInstallPath
diff --git a/android/module_proxy.go b/android/module_proxy.go
index 2a650729f..1f9679926 100644
--- a/android/module_proxy.go
+++ b/android/module_proxy.go
@@ -106,6 +106,18 @@ func (m ModuleProxy) InstallInSystemExt() bool {
panic("method is not implemented on ModuleProxy")
}
+func (m ModuleProxy) InstallInSystemDlkm() bool {
+ panic("method is not implemented on ModuleProxy")
+}
+
+func (m ModuleProxy) InstallInVendorDlkm() bool {
+ panic("method is not implemented on ModuleProxy")
+}
+
+func (m ModuleProxy) InstallInOdmDlkm() bool {
+ panic("method is not implemented on ModuleProxy")
+}
+
func (m ModuleProxy) InstallForceOS() (*OsType, *ArchType) {
panic("method is not implemented on ModuleProxy")
}
@@ -122,6 +134,10 @@ func (m ModuleProxy) IsHideFromMake() bool {
panic("method is not implemented on ModuleProxy")
}
+func (m ModuleProxy) SkipInstall() {
+ panic("method is not implemented on ModuleProxy")
+}
+
func (m ModuleProxy) IsSkipInstall() bool {
panic("method is not implemented on ModuleProxy")
}
diff --git a/android/mutator.go b/android/mutator.go
index 4ddc606b1..fdd16a889 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -70,7 +70,7 @@ type RegisterMutatorsContext interface {
TopDown(name string, m TopDownMutator) MutatorHandle
BottomUp(name string, m BottomUpMutator) MutatorHandle
BottomUpBlueprint(name string, m blueprint.BottomUpMutator) MutatorHandle
- Transition(name string, m TransitionMutator)
+ Transition(name string, m TransitionMutator) TransitionMutatorHandle
}
type RegisterMutatorFunc func(RegisterMutatorsContext)
@@ -579,7 +579,7 @@ func (a *androidTransitionMutator) Mutate(ctx blueprint.BottomUpMutatorContext,
}
}
-func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) {
+func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) TransitionMutatorHandle {
atm := &androidTransitionMutator{
finalPhase: x.finalPhase,
mutator: m,
@@ -587,8 +587,10 @@ func (x *registerMutatorsContext) Transition(name string, m TransitionMutator) {
}
mutator := &mutator{
name: name,
- transitionMutator: atm}
+ transitionMutator: atm,
+ }
x.mutators = append(x.mutators, mutator)
+ return mutator
}
func (x *registerMutatorsContext) mutatorName(name string) string {
@@ -625,7 +627,10 @@ func (mutator *mutator) register(ctx *Context) {
} else if mutator.topDownMutator != nil {
handle = blueprintCtx.RegisterTopDownMutator(mutator.name, mutator.topDownMutator)
} else if mutator.transitionMutator != nil {
- blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
+ handle := blueprintCtx.RegisterTransitionMutator(mutator.name, mutator.transitionMutator)
+ if mutator.neverFar {
+ handle.NeverFar()
+ }
}
// Forward booleans set on the MutatorHandle to the blueprint.MutatorHandle.
@@ -681,6 +686,14 @@ type MutatorHandle interface {
MutatesGlobalState() MutatorHandle
}
+type TransitionMutatorHandle interface {
+ // NeverFar causes the variations created by this mutator to never be ignored when adding
+ // far variation dependencies. Normally, far variation dependencies ignore all the variants
+ // of the source module, and only use the variants explicitly requested by the
+ // AddFarVariationDependencies call.
+ NeverFar() MutatorHandle
+}
+
func (mutator *mutator) Parallel() MutatorHandle {
return mutator
}
@@ -715,6 +728,11 @@ func (mutator *mutator) MutatesGlobalState() MutatorHandle {
return mutator
}
+func (mutator *mutator) NeverFar() MutatorHandle {
+ mutator.neverFar = true
+ return mutator
+}
+
func RegisterComponentsMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("component-deps", componentDepsMutator)
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 44ac2cd6c..6176a996a 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -63,6 +63,7 @@ func init() {
AddNeverAllowRules(createLimitDirgroupRule()...)
AddNeverAllowRules(createFilesystemIsAutoGeneratedRule())
AddNeverAllowRules(createKotlinPluginRule()...)
+ AddNeverAllowRules(createPrebuiltEtcBpDefineRule())
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -321,6 +322,27 @@ func createKotlinPluginRule() []Rule {
}
}
+// These module types are introduced to convert PRODUCT_COPY_FILES to Soong,
+// and is only intended to be used by filesystem_creator.
+func createPrebuiltEtcBpDefineRule() Rule {
+ return NeverAllow().
+ ModuleType(
+ "prebuilt_usr_srec",
+ "prebuilt_priv_app",
+ "prebuilt_rfs",
+ "prebuilt_framework",
+ "prebuilt_res",
+ "prebuilt_wlc_upt",
+ "prebuilt_odm",
+ "prebuilt_vendor_dlkm",
+ "prebuilt_bt_firmware",
+ "prebuilt_tvservice",
+ "prebuilt_optee",
+ ).
+ DefinedInBpFile().
+ Because("module type not allowed to be defined in bp file")
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
@@ -354,6 +376,10 @@ func neverallowMutator(ctx BottomUpMutatorContext) {
continue
}
+ if !n.appliesToBpDefinedModule(ctx) {
+ continue
+ }
+
ctx.ModuleErrorf("violates " + n.String())
}
}
@@ -477,6 +503,8 @@ type Rule interface {
WithoutMatcher(properties string, matcher ValueMatcher) Rule
+ DefinedInBpFile() Rule
+
Because(reason string) Rule
}
@@ -498,6 +526,8 @@ type rule struct {
unlessProps ruleProperties
onlyBootclasspathJar bool
+
+ definedInBp bool
}
// Create a new NeverAllow rule.
@@ -571,6 +601,13 @@ func (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule {
return r
}
+// DefinedInBpFile specifies that this rule applies to modules that are defined
+// in bp files, and does not apply to modules that are auto generated by other modules.
+func (r *rule) DefinedInBpFile() Rule {
+ r.definedInBp = true
+ return r
+}
+
func selectMatcher(expected string) ValueMatcher {
if expected == "*" {
return anyMatcherInstance
@@ -665,6 +702,13 @@ func (r *rule) appliesToProperties(ctx BottomUpMutatorContext, properties []inte
return includeProps && !excludeProps
}
+func (r *rule) appliesToBpDefinedModule(ctx BottomUpMutatorContext) bool {
+ if !r.definedInBp {
+ return true
+ }
+ return !ctx.OtherModuleIsAutoGenerated(ctx.Module()) == r.definedInBp
+}
+
func StartsWith(prefix string) ValueMatcher {
return &startsWithMatcher{prefix}
}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index caec8c7d9..c74d5ff58 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -374,6 +374,20 @@ var neverallowTests = []struct {
`is_auto_generated property is only allowed for filesystem modules in build/soong/fsgen directory`,
},
},
+ // Test for the rule restricting use of prebuilt_* module
+ {
+ name: `"prebuilt_usr_srec" defined in Android.bp file`,
+ fs: map[string][]byte{
+ "a/b/Android.bp": []byte(`
+ prebuilt_usr_srec {
+ name: "foo",
+ }
+ `),
+ },
+ expectedErrors: []string{
+ `module type not allowed to be defined in bp file`,
+ },
+ },
}
var prepareForNeverAllowTest = GroupFixturePreparers(
@@ -383,6 +397,7 @@ var prepareForNeverAllowTest = GroupFixturePreparers(
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("filesystem", newMockFilesystemModule)
+ ctx.RegisterModuleType("prebuilt_usr_srec", newMockPrebuiltUsrSrecModule)
}),
)
@@ -482,3 +497,16 @@ func newMockJavaLibraryModule() Module {
func (p *mockJavaLibraryModule) GenerateAndroidBuildActions(ModuleContext) {
}
+
+type mockPrebuiltUsrSrecModule struct {
+ ModuleBase
+}
+
+func (p *mockPrebuiltUsrSrecModule) GenerateAndroidBuildActions(ModuleContext) {
+}
+
+func newMockPrebuiltUsrSrecModule() Module {
+ m := &mockPrebuiltUsrSrecModule{}
+ InitAndroidModule(m)
+ return m
+}
diff --git a/android/packaging.go b/android/packaging.go
index acafcd4f2..98c85fa0c 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -207,38 +207,49 @@ type PackagingBase struct {
// If this is set to true by a module type inheriting PackagingBase, the deps property
// collects the first target only even with compile_multilib: true.
DepsCollectFirstTargetOnly bool
+
+ // If this is set to try by a module type inheriting PackagingBase, the module type is
+ // allowed to utilize High_priority_deps.
+ AllowHighPriorityDeps bool
}
-type depsProperty struct {
+type DepsProperty struct {
+ // Deps that have higher priority in packaging when there is a packaging conflict.
+ // For example, if multiple files are being installed to same filepath, the install file
+ // of the module listed in this property will have a higher priority over those in other
+ // deps properties.
+ High_priority_deps []string `android:"arch_variant"`
+
// Modules to include in this package
Deps proptools.Configurable[[]string] `android:"arch_variant"`
}
type packagingMultilibProperties struct {
- First depsProperty `android:"arch_variant"`
- Common depsProperty `android:"arch_variant"`
- Lib32 depsProperty `android:"arch_variant"`
- Lib64 depsProperty `android:"arch_variant"`
- Both depsProperty `android:"arch_variant"`
- Prefer32 depsProperty `android:"arch_variant"`
+ First DepsProperty `android:"arch_variant"`
+ Common DepsProperty `android:"arch_variant"`
+ Lib32 DepsProperty `android:"arch_variant"`
+ Lib64 DepsProperty `android:"arch_variant"`
+ Both DepsProperty `android:"arch_variant"`
+ Prefer32 DepsProperty `android:"arch_variant"`
}
type packagingArchProperties struct {
- Arm64 depsProperty
- Arm depsProperty
- X86_64 depsProperty
- X86 depsProperty
+ Arm64 DepsProperty
+ Arm DepsProperty
+ X86_64 DepsProperty
+ X86 DepsProperty
}
type PackagingProperties struct {
- Deps proptools.Configurable[[]string] `android:"arch_variant"`
- Multilib packagingMultilibProperties `android:"arch_variant"`
+ DepsProperty
+
+ Multilib packagingMultilibProperties `android:"arch_variant"`
Arch packagingArchProperties
}
func InitPackageModule(p PackageModule) {
base := p.packagingBase()
- p.AddProperties(&base.properties)
+ p.AddProperties(&base.properties, &base.properties.DepsProperty)
}
func (p *PackagingBase) packagingBase() *PackagingBase {
@@ -249,55 +260,72 @@ func (p *PackagingBase) packagingBase() *PackagingBase {
// the current archicture when this module is not configured for multi target. When configured for
// multi target, deps is selected for each of the targets and is NOT selected for the current
// architecture which would be Common.
-func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []string {
- get := func(prop proptools.Configurable[[]string]) []string {
- return prop.GetOrDefault(ctx, nil)
+// It returns two lists, the normal and high priority deps, respectively.
+func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) ([]string, []string) {
+ var normalDeps []string
+ var highPriorityDeps []string
+
+ get := func(prop DepsProperty) {
+ normalDeps = append(normalDeps, prop.Deps.GetOrDefault(ctx, nil)...)
+ highPriorityDeps = append(highPriorityDeps, prop.High_priority_deps...)
+ }
+ has := func(prop DepsProperty) bool {
+ return len(prop.Deps.GetOrDefault(ctx, nil)) > 0 || len(prop.High_priority_deps) > 0
}
- var ret []string
if arch == ctx.Target().Arch.ArchType && len(ctx.MultiTargets()) == 0 {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
} else if arch.Multilib == "lib32" {
- ret = append(ret, get(p.properties.Multilib.Lib32.Deps)...)
+ get(p.properties.Multilib.Lib32)
// multilib.prefer32.deps are added for lib32 only when they support 32-bit arch
- for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
+ for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) {
+ if checkIfOtherModuleSupportsLib32(ctx, dep) {
+ normalDeps = append(normalDeps, dep)
+ }
+ }
+ for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps {
if checkIfOtherModuleSupportsLib32(ctx, dep) {
- ret = append(ret, dep)
+ highPriorityDeps = append(highPriorityDeps, dep)
}
}
} else if arch.Multilib == "lib64" {
- ret = append(ret, get(p.properties.Multilib.Lib64.Deps)...)
+ get(p.properties.Multilib.Lib64)
// multilib.prefer32.deps are added for lib64 only when they don't support 32-bit arch
- for _, dep := range get(p.properties.Multilib.Prefer32.Deps) {
+ for _, dep := range p.properties.Multilib.Prefer32.Deps.GetOrDefault(ctx, nil) {
if !checkIfOtherModuleSupportsLib32(ctx, dep) {
- ret = append(ret, dep)
+ normalDeps = append(normalDeps, dep)
+ }
+ }
+ for _, dep := range p.properties.Multilib.Prefer32.High_priority_deps {
+ if !checkIfOtherModuleSupportsLib32(ctx, dep) {
+ highPriorityDeps = append(highPriorityDeps, dep)
}
}
} else if arch == Common {
- ret = append(ret, get(p.properties.Multilib.Common.Deps)...)
+ get(p.properties.Multilib.Common)
}
if p.DepsCollectFirstTargetOnly {
- if len(get(p.properties.Multilib.First.Deps)) > 0 {
+ if has(p.properties.Multilib.First) {
ctx.PropertyErrorf("multilib.first.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, get(p.properties.Multilib.Both.Deps)...)
+ get(p.properties.Multilib.Both)
if i == 0 {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
}
}
}
} else {
- if len(get(p.properties.Multilib.Both.Deps)) > 0 {
+ if has(p.properties.Multilib.Both) {
ctx.PropertyErrorf("multilib.both.deps", "not supported. use \"deps\" instead")
}
for i, t := range ctx.MultiTargets() {
if t.Arch.ArchType == arch {
- ret = append(ret, get(p.properties.Deps)...)
+ get(p.properties.DepsProperty)
if i == 0 {
- ret = append(ret, get(p.properties.Multilib.First.Deps)...)
+ get(p.properties.Multilib.First)
}
}
}
@@ -306,17 +334,21 @@ func (p *PackagingBase) getDepsForArch(ctx BaseModuleContext, arch ArchType) []s
if ctx.Arch().ArchType == Common {
switch arch {
case Arm64:
- ret = append(ret, get(p.properties.Arch.Arm64.Deps)...)
+ get(p.properties.Arch.Arm64)
case Arm:
- ret = append(ret, get(p.properties.Arch.Arm.Deps)...)
+ get(p.properties.Arch.Arm)
case X86_64:
- ret = append(ret, get(p.properties.Arch.X86_64.Deps)...)
+ get(p.properties.Arch.X86_64)
case X86:
- ret = append(ret, get(p.properties.Arch.X86.Deps)...)
+ get(p.properties.Arch.X86)
}
}
- return FirstUniqueStrings(ret)
+ if len(highPriorityDeps) > 0 && !p.AllowHighPriorityDeps {
+ ctx.ModuleErrorf("Usage of high_priority_deps is not allowed for %s module type", ctx.ModuleType())
+ }
+
+ return FirstUniqueStrings(normalDeps), FirstUniqueStrings(highPriorityDeps)
}
func getSupportedTargets(ctx BaseModuleContext) []Target {
@@ -360,6 +392,8 @@ type PackagingItem interface {
IsPackagingItem() bool
}
+var _ PackagingItem = (*PackagingItemAlwaysDepTag)(nil)
+
// DepTag provides default implementation of PackagingItem interface.
// PackagingBase-derived modules can define their own dependency tag by embedding this, which
// can be passed to AddDeps() or AddDependencies().
@@ -371,31 +405,52 @@ func (PackagingItemAlwaysDepTag) IsPackagingItem() bool {
return true
}
+// highPriorityDepTag provides default implementation of HighPriorityPackagingItem interface.
+type highPriorityDepTag struct {
+ blueprint.DependencyTag
+}
+
// See PackageModule.AddDeps
func (p *PackagingBase) AddDeps(ctx BottomUpMutatorContext, depTag blueprint.DependencyTag) {
+ addDep := func(t Target, dep string, highPriority bool) {
+ if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
+ return
+ }
+ targetVariation := t.Variations()
+ sharedVariation := blueprint.Variation{
+ Mutator: "link",
+ Variation: "shared",
+ }
+ // If a shared variation exists, use that. Static variants do not provide any standalone files
+ // for packaging.
+ if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
+ targetVariation = append(targetVariation, sharedVariation)
+ }
+ depTagToUse := depTag
+ if highPriority {
+ depTagToUse = highPriorityDepTag{depTag}
+ }
+
+ ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep)
+ }
for _, t := range getSupportedTargets(ctx) {
- for _, dep := range p.getDepsForArch(ctx, t.Arch.ArchType) {
- if p.IgnoreMissingDependencies && !ctx.OtherModuleExists(dep) {
- continue
- }
- targetVariation := t.Variations()
- sharedVariation := blueprint.Variation{
- Mutator: "link",
- Variation: "shared",
- }
- // If a shared variation exists, use that. Static variants do not provide any standalone files
- // for packaging.
- if ctx.OtherModuleFarDependencyVariantExists([]blueprint.Variation{sharedVariation}, dep) {
- targetVariation = append(targetVariation, sharedVariation)
- }
- ctx.AddFarVariationDependencies(targetVariation, depTag, dep)
+ normalDeps, highPriorityDeps := p.getDepsForArch(ctx, t.Arch.ArchType)
+ for _, dep := range normalDeps {
+ addDep(t, dep, false)
+ }
+ for _, dep := range highPriorityDeps {
+ addDep(t, dep, true)
}
}
}
func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
- // all packaging specs gathered from the dep.
- var all []PackagingSpec
+ // packaging specs gathered from the dep that are not high priorities.
+ var regularPriorities []PackagingSpec
+
+ // all packaging specs gathered from the high priority deps.
+ var highPriorities []PackagingSpec
+
// Name of the dependency which requested the packaging spec.
// If this dep is overridden, the packaging spec will not be installed via this dependency chain.
// (the packaging spec might still be installed if there are some other deps which depend on it).
@@ -420,7 +475,8 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
ctx.VisitDirectDeps(func(child Module) {
- if pi, ok := ctx.OtherModuleDependencyTag(child).(PackagingItem); !ok || !pi.IsPackagingItem() {
+ depTag := ctx.OtherModuleDependencyTag(child)
+ if pi, ok := depTag.(PackagingItem); !ok || !pi.IsPackagingItem() {
return
}
for _, ps := range OtherModuleProviderOrDefault(
@@ -434,7 +490,13 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
continue
}
}
- all = append(all, ps)
+
+ if _, ok := depTag.(highPriorityDepTag); ok {
+ highPriorities = append(highPriorities, ps)
+ } else {
+ regularPriorities = append(regularPriorities, ps)
+ }
+
depNames = append(depNames, child.Name())
if ps.overrides != nil {
overridden = append(overridden, *ps.overrides...)
@@ -442,21 +504,26 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
})
- // all minus packaging specs that are overridden
- var filtered []PackagingSpec
- for index, ps := range all {
- if ps.owner != "" && InList(ps.owner, overridden) {
- continue
- }
- // The dependency which requested this packaging spec has been overridden.
- if InList(depNames[index], overridden) {
- continue
+ filterOverridden := func(input []PackagingSpec) []PackagingSpec {
+ // input minus packaging specs that are overridden
+ var filtered []PackagingSpec
+ for index, ps := range input {
+ if ps.owner != "" && InList(ps.owner, overridden) {
+ continue
+ }
+ // The dependency which requested this packaging spec has been overridden.
+ if InList(depNames[index], overridden) {
+ continue
+ }
+ filtered = append(filtered, ps)
}
- filtered = append(filtered, ps)
+ return filtered
}
+ filteredRegularPriority := filterOverridden(regularPriorities)
+
m := make(map[string]PackagingSpec)
- for _, ps := range filtered {
+ for _, ps := range filteredRegularPriority {
dstPath := ps.relPathInPackage
if existingPs, ok := m[dstPath]; ok {
if !existingPs.Equals(&ps) {
@@ -466,6 +533,21 @@ func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter
}
m[dstPath] = ps
}
+
+ filteredHighPriority := filterOverridden(highPriorities)
+ highPriorityPs := make(map[string]PackagingSpec)
+ for _, ps := range filteredHighPriority {
+ dstPath := ps.relPathInPackage
+ if existingPs, ok := highPriorityPs[dstPath]; ok {
+ if !existingPs.Equals(&ps) {
+ ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+ }
+ continue
+ }
+ highPriorityPs[dstPath] = ps
+ m[dstPath] = ps
+ }
+
return m
}
diff --git a/android/path_properties.go b/android/path_properties.go
index f3c62ea43..55a4dc066 100644
--- a/android/path_properties.go
+++ b/android/path_properties.go
@@ -52,16 +52,12 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
var pathProperties []string
var pathDeviceFirstProperties []string
var pathDeviceFirstPrefer32Properties []string
- var pathDeviceFirstVendorProperties []string
- var pathDeviceFirstVendorSharedProperties []string
var pathDeviceCommonProperties []string
var pathCommonOsProperties []string
for _, ps := range props {
pathProperties = append(pathProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path")...)
pathDeviceFirstProperties = append(pathDeviceFirstProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first")...)
pathDeviceFirstPrefer32Properties = append(pathDeviceFirstPrefer32Properties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first_prefer32")...)
- pathDeviceFirstVendorProperties = append(pathDeviceFirstVendorProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first_vendor")...)
- pathDeviceFirstVendorSharedProperties = append(pathDeviceFirstVendorSharedProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_first_vendor_shared")...)
pathDeviceCommonProperties = append(pathDeviceCommonProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_device_common")...)
pathCommonOsProperties = append(pathCommonOsProperties, taggedPropertiesForPropertyStruct(ctx, ps, "path_common_os")...)
}
@@ -70,8 +66,6 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
pathProperties = FirstUniqueStrings(pathProperties)
pathDeviceFirstProperties = FirstUniqueStrings(pathDeviceFirstProperties)
pathDeviceFirstPrefer32Properties = FirstUniqueStrings(pathDeviceFirstPrefer32Properties)
- pathDeviceFirstVendorProperties = FirstUniqueStrings(pathDeviceFirstVendorProperties)
- pathDeviceFirstVendorSharedProperties = FirstUniqueStrings(pathDeviceFirstVendorSharedProperties)
pathDeviceCommonProperties = FirstUniqueStrings(pathDeviceCommonProperties)
pathCommonOsProperties = FirstUniqueStrings(pathCommonOsProperties)
@@ -108,23 +102,6 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) {
}
}
}
- // path_device_first_vendor is path_device_first + vendor variation
- deviceFirstVendorVariations := ctx.Config().AndroidFirstDeviceTarget.Variations()
- deviceFirstVendorVariations = append(deviceFirstVendorVariations,
- blueprint.Variation{Mutator: "image", Variation: "vendor"})
- for _, s := range pathDeviceFirstVendorProperties {
- if m, t := SrcIsModuleWithTag(s); m != "" {
- ctx.AddVariationDependencies(deviceFirstVendorVariations, sourceOrOutputDepTag(m, t), m)
- }
- }
- // path_device_first_vendor_shared is path_device_first_vendor + shared linkage variation
- deviceFirstVendorSharedVariations := append(deviceFirstVendorVariations,
- blueprint.Variation{Mutator: "link", Variation: "shared"})
- for _, s := range pathDeviceFirstVendorSharedProperties {
- if m, t := SrcIsModuleWithTag(s); m != "" {
- ctx.AddVariationDependencies(deviceFirstVendorSharedVariations, sourceOrOutputDepTag(m, t), m)
- }
- }
// properties tagged "path_device_common" get the device common variant
for _, s := range pathDeviceCommonProperties {
if m, t := SrcIsModuleWithTag(s); m != "" {
diff --git a/android/paths.go b/android/paths.go
index bf2c3a097..9cb872d6f 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -117,6 +117,9 @@ type ModuleInstallPathContext interface {
InstallInOdm() bool
InstallInProduct() bool
InstallInVendor() bool
+ InstallInSystemDlkm() bool
+ InstallInVendorDlkm() bool
+ InstallInOdmDlkm() bool
InstallForceOS() (*OsType, *ArchType)
}
@@ -170,6 +173,18 @@ func (ctx *baseModuleContextToModuleInstallPathContext) InstallInVendor() bool {
return ctx.Module().InstallInVendor()
}
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInSystemDlkm() bool {
+ return ctx.Module().InstallInSystemDlkm()
+}
+
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInVendorDlkm() bool {
+ return ctx.Module().InstallInVendorDlkm()
+}
+
+func (ctx *baseModuleContextToModuleInstallPathContext) InstallInOdmDlkm() bool {
+ return ctx.Module().InstallInOdmDlkm()
+}
+
func (ctx *baseModuleContextToModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return ctx.Module().InstallForceOS()
}
@@ -551,15 +566,35 @@ func PathsRelativeToModuleSourceDir(input SourceInput) Paths {
return ret
}
+type directoryPath struct {
+ basePath
+}
+
+func (d *directoryPath) String() string {
+ return d.basePath.String()
+}
+
+func (d *directoryPath) base() basePath {
+ return d.basePath
+}
+
+// DirectoryPath represents a source path for directories. Incompatible with Path by design.
+type DirectoryPath interface {
+ String() string
+ base() basePath
+}
+
+var _ DirectoryPath = (*directoryPath)(nil)
+
+type DirectoryPaths []DirectoryPath
+
// 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
+func DirectoryPathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string) DirectoryPaths {
+ var ret DirectoryPaths
for _, path := range paths {
if m, t := SrcIsModuleWithTag(path); m != "" {
@@ -588,12 +623,12 @@ func DirectoryPathsForModuleSrc(ctx ModuleMissingDepsPathContext, paths []string
} else if !isDir {
ReportPathErrorf(ctx, "module directory path %q is not a directory", p)
} else {
- ret = append(ret, p)
+ ret = append(ret, &directoryPath{basePath{path: p.path, rel: p.rel}})
}
}
}
- seen := make(map[Path]bool, len(ret))
+ seen := make(map[DirectoryPath]bool, len(ret))
for _, path := range ret {
if seen[path] {
ReportPathErrorf(ctx, "duplicated path %q", path)
@@ -2057,6 +2092,10 @@ func PathForMainlineSdksInstall(ctx PathContext, paths ...string) InstallPath {
return base.Join(ctx, paths...)
}
+func PathForSuiteInstall(ctx PathContext, suite string, pathComponents ...string) InstallPath {
+ return pathForPartitionInstallDir(ctx, "test_suites", "test_suites", false).Join(ctx, suite).Join(ctx, pathComponents...)
+}
+
func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
rel := Rel(ctx, strings.TrimSuffix(path.PartitionDir(), path.partition), path.String())
return "/" + rel
@@ -2111,6 +2150,12 @@ func modulePartition(ctx ModuleInstallPathContext, device bool) string {
partition = ctx.DeviceConfig().SystemExtPath()
} else if ctx.InstallInRoot() {
partition = "root"
+ } else if ctx.InstallInSystemDlkm() {
+ partition = ctx.DeviceConfig().SystemDlkmPath()
+ } else if ctx.InstallInVendorDlkm() {
+ partition = ctx.DeviceConfig().VendorDlkmPath()
+ } else if ctx.InstallInOdmDlkm() {
+ partition = ctx.DeviceConfig().OdmDlkmPath()
} else {
partition = "system"
}
@@ -2314,6 +2359,9 @@ type testModuleInstallPathContext struct {
inOdm bool
inProduct bool
inVendor bool
+ inSystemDlkm bool
+ inVendorDlkm bool
+ inOdmDlkm bool
forceOS *OsType
forceArch *ArchType
}
@@ -2368,6 +2416,18 @@ func (m testModuleInstallPathContext) InstallInVendor() bool {
return m.inVendor
}
+func (m testModuleInstallPathContext) InstallInSystemDlkm() bool {
+ return m.inSystemDlkm
+}
+
+func (m testModuleInstallPathContext) InstallInVendorDlkm() bool {
+ return m.inVendorDlkm
+}
+
+func (m testModuleInstallPathContext) InstallInOdmDlkm() bool {
+ return m.inOdmDlkm
+}
+
func (m testModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return m.forceOS, m.forceArch
}
diff --git a/android/paths_test.go b/android/paths_test.go
index 941f0ca78..5e618f914 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1592,6 +1592,12 @@ func TestPathRelativeToTop(t *testing.T) {
})
}
+func TestDirectoryPathIsIncompatibleWithPath(t *testing.T) {
+ d := (DirectoryPath)(&directoryPath{})
+ _, ok := d.(Path)
+ AssertBoolEquals(t, "directoryPath shouldn't implement Path", ok, false)
+}
+
func ExampleOutputPath_ReplaceExtension() {
ctx := &configErrorWrapper{
config: TestConfig("out", nil, "", nil),
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 5d75b62fe..51e72af9a 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -569,6 +569,7 @@ func hideUnflaggedModules(ctx BottomUpMutatorContext, psi PrebuiltSelectionInfoM
for _, moduleInFamily := range allModulesInFamily {
if moduleInFamily.Name() != selectedModuleInFamily.Name() {
moduleInFamily.HideFromMake()
+ moduleInFamily.SkipInstall()
// If this is a prebuilt module, unset properties.UsePrebuilt
// properties.UsePrebuilt might evaluate to true via soong config var fallback mechanism
// Set it to false explicitly so that the following mutator does not replace rdeps to this unselected prebuilt
@@ -639,6 +640,7 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
}
} else {
m.HideFromMake()
+ m.SkipInstall()
}
}
}
diff --git a/android/register.go b/android/register.go
index bb1ead73c..8d2f19e73 100644
--- a/android/register.go
+++ b/android/register.go
@@ -98,6 +98,7 @@ type mutator struct {
usesCreateModule bool
mutatesDependencies bool
mutatesGlobalState bool
+ neverFar bool
}
var _ sortableComponent = &mutator{}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 56de9cd00..403c18418 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -575,25 +575,28 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
nsjailCmd.WriteString(r.outDir.String())
nsjailCmd.WriteString(":nsjail_build_sandbox/out")
- for _, input := range inputs {
+ addBindMount := func(src, dst string) {
nsjailCmd.WriteString(" -R $PWD/")
- nsjailCmd.WriteString(input.String())
+ nsjailCmd.WriteString(src)
nsjailCmd.WriteString(":nsjail_build_sandbox/")
- nsjailCmd.WriteString(r.nsjailPathForInputRel(input))
+ nsjailCmd.WriteString(dst)
+ }
+
+ for _, input := range inputs {
+ addBindMount(input.String(), r.nsjailPathForInputRel(input))
}
for _, tool := range tools {
- nsjailCmd.WriteString(" -R $PWD/")
- nsjailCmd.WriteString(tool.String())
- nsjailCmd.WriteString(":nsjail_build_sandbox/")
- nsjailCmd.WriteString(nsjailPathForToolRel(r.ctx, tool))
+ addBindMount(tool.String(), nsjailPathForToolRel(r.ctx, tool))
}
inputs = append(inputs, tools...)
for _, c := range r.commands {
+ for _, directory := range c.implicitDirectories {
+ addBindMount(directory.String(), directory.String())
+ // TODO(b/375551969): Add implicitDirectories to BuildParams, rather than relying on implicits
+ inputs = append(inputs, SourcePath{basePath: directory.base()})
+ }
for _, tool := range c.packagedTools {
- nsjailCmd.WriteString(" -R $PWD/")
- nsjailCmd.WriteString(tool.srcPath.String())
- nsjailCmd.WriteString(":nsjail_build_sandbox/")
- nsjailCmd.WriteString(nsjailPathForPackagedToolRel(tool))
+ addBindMount(tool.srcPath.String(), nsjailPathForPackagedToolRel(tool))
inputs = append(inputs, tool.srcPath)
}
}
@@ -917,16 +920,17 @@ func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString b
type RuleBuilderCommand struct {
rule *RuleBuilder
- buf strings.Builder
- inputs Paths
- implicits Paths
- orderOnlys Paths
- validations Paths
- outputs WritablePaths
- depFiles WritablePaths
- tools Paths
- packagedTools []PackagingSpec
- rspFiles []rspFileAndPaths
+ buf strings.Builder
+ inputs Paths
+ implicits Paths
+ orderOnlys Paths
+ validations Paths
+ outputs WritablePaths
+ depFiles WritablePaths
+ tools Paths
+ packagedTools []PackagingSpec
+ rspFiles []rspFileAndPaths
+ implicitDirectories DirectoryPaths
}
type rspFileAndPaths struct {
@@ -951,6 +955,10 @@ func (c *RuleBuilderCommand) addImplicit(path Path) {
c.implicits = append(c.implicits, path)
}
+func (c *RuleBuilderCommand) addImplicitDirectory(path DirectoryPath) {
+ c.implicitDirectories = append(c.implicitDirectories, path)
+}
+
func (c *RuleBuilderCommand) addOrderOnly(path Path) {
checkPathNotNil(path)
c.orderOnlys = append(c.orderOnlys, path)
@@ -1313,6 +1321,16 @@ func (c *RuleBuilderCommand) Implicits(paths Paths) *RuleBuilderCommand {
return c
}
+// ImplicitDirectory adds the specified input directory to the dependencies without modifying the
+// command line. Added directories will be bind-mounted for the nsjail.
+func (c *RuleBuilderCommand) ImplicitDirectory(path DirectoryPath) *RuleBuilderCommand {
+ if !c.rule.nsjail {
+ panic("ImplicitDirectory() must be called after Nsjail()")
+ }
+ c.addImplicitDirectory(path)
+ return c
+}
+
// GetImplicits returns the command's implicit inputs.
func (c *RuleBuilderCommand) GetImplicits() Paths {
return c.implicits
diff --git a/android/singleton.go b/android/singleton.go
index 913bf6a56..0754b0ccb 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -64,6 +64,7 @@ type SingletonContext interface {
VisitAllModulesBlueprint(visit func(blueprint.Module))
VisitAllModules(visit func(Module))
+ VisitAllModuleProxies(visit func(proxy ModuleProxy))
VisitAllModulesIf(pred func(Module) bool, visit func(Module))
VisitDirectDeps(module Module, visit func(Module))
@@ -77,8 +78,10 @@ type SingletonContext interface {
VisitAllModuleVariants(module Module, visit func(Module))
+ VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy))
+
PrimaryModule(module Module) Module
- FinalModule(module Module) Module
+ IsFinalModule(module Module) bool
AddNinjaFileDeps(deps ...string)
@@ -193,7 +196,7 @@ func (s *singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (st
}
// visitAdaptor wraps a visit function that takes an android.Module parameter into
-// a function that takes an blueprint.Module parameter and only calls the visit function if the
+// a function that takes a blueprint.Module parameter and only calls the visit function if the
// blueprint.Module is an android.Module.
func visitAdaptor(visit func(Module)) func(blueprint.Module) {
return func(module blueprint.Module) {
@@ -203,6 +206,16 @@ func visitAdaptor(visit func(Module)) func(blueprint.Module) {
}
}
+// visitProxyAdaptor wraps a visit function that takes an android.ModuleProxy parameter into
+// a function that takes a blueprint.ModuleProxy parameter.
+func visitProxyAdaptor(visit func(proxy ModuleProxy)) func(proxy blueprint.ModuleProxy) {
+ return func(module blueprint.ModuleProxy) {
+ visit(ModuleProxy{
+ module: module,
+ })
+ }
+}
+
// predAdaptor wraps a pred function that takes an android.Module parameter
// into a function that takes an blueprint.Module parameter and only calls the visit function if the
// blueprint.Module is an android.Module, otherwise returns false.
@@ -224,6 +237,10 @@ func (s *singletonContextAdaptor) VisitAllModules(visit func(Module)) {
s.SingletonContext.VisitAllModules(visitAdaptor(visit))
}
+func (s *singletonContextAdaptor) VisitAllModuleProxies(visit func(proxy ModuleProxy)) {
+ s.SingletonContext.VisitAllModuleProxies(visitProxyAdaptor(visit))
+}
+
func (s *singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
}
@@ -248,12 +265,16 @@ func (s *singletonContextAdaptor) VisitAllModuleVariants(module Module, visit fu
s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
}
+func (s *singletonContextAdaptor) VisitAllModuleVariantProxies(module Module, visit func(proxy ModuleProxy)) {
+ s.SingletonContext.VisitAllModuleVariantProxies(module, visitProxyAdaptor(visit))
+}
+
func (s *singletonContextAdaptor) PrimaryModule(module Module) Module {
return s.SingletonContext.PrimaryModule(module).(Module)
}
-func (s *singletonContextAdaptor) FinalModule(module Module) Module {
- return s.SingletonContext.FinalModule(module).(Module)
+func (s *singletonContextAdaptor) IsFinalModule(module Module) bool {
+ return s.SingletonContext.IsFinalModule(module)
}
func (s *singletonContextAdaptor) ModuleVariantsFromName(referer Module, name string) []Module {
diff --git a/android/util.go b/android/util.go
index 2d269b724..3fc4608e0 100644
--- a/android/util.go
+++ b/android/util.go
@@ -660,3 +660,13 @@ func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (actual V, loaded bool) {
v, loaded := m.Map.LoadOrStore(key, value)
return v.(V), loaded
}
+
+// AppendIfNotZero append the given value to the slice if it is not the zero value
+// for its type.
+func AppendIfNotZero[T comparable](slice []T, value T) []T {
+ var zeroValue T // Get the zero value of the type T
+ if value != zeroValue {
+ return append(slice, value)
+ }
+ return slice
+}
diff --git a/android/variable.go b/android/variable.go
index 6693d9197..f82c9cae8 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -339,11 +339,16 @@ type ProductVariables struct {
HWASanExcludePaths []string `json:",omitempty"`
VendorPath *string `json:",omitempty"`
+ VendorDlkmPath *string `json:",omitempty"`
BuildingVendorImage *bool `json:",omitempty"`
OdmPath *string `json:",omitempty"`
+ BuildingOdmImage *bool `json:",omitempty"`
+ OdmDlkmPath *string `json:",omitempty"`
ProductPath *string `json:",omitempty"`
BuildingProductImage *bool `json:",omitempty"`
SystemExtPath *string `json:",omitempty"`
+ SystemDlkmPath *string `json:",omitempty"`
+ OemPath *string `json:",omitempty"`
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
@@ -535,6 +540,13 @@ type ProductVariables struct {
ExtraAllowedDepsTxt *string `json:",omitempty"`
AdbKeys *string `json:",omitempty"`
+
+ DeviceMatrixFile []string `json:",omitempty"`
+ ProductManifestFiles []string `json:",omitempty"`
+ SystemManifestFile []string `json:",omitempty"`
+ SystemExtManifestFiles []string `json:",omitempty"`
+ DeviceManifestFiles []string `json:",omitempty"`
+ OdmManifestFiles []string `json:",omitempty"`
}
type PartitionQualifiedVariablesType struct {
@@ -565,6 +577,14 @@ type PartitionQualifiedVariablesType struct {
BoardAvbRollbackIndexLocation string `json:",omitempty"`
}
+type ChainedAvbPartitionProps struct {
+ Partitions []string `json:",omitempty"`
+ Key string `json:",omitempty"`
+ Algorithm string `json:",omitempty"`
+ RollbackIndex string `json:",omitempty"`
+ RollbackIndexLocation string `json:",omitempty"`
+}
+
type PartitionVariables struct {
ProductDirectory string `json:",omitempty"`
PartitionQualifiedVariables map[string]PartitionQualifiedVariablesType
@@ -589,12 +609,25 @@ type PartitionVariables struct {
ProductUseDynamicPartitionSize bool `json:",omitempty"`
CopyImagesForTargetFilesZip bool `json:",omitempty"`
- BoardAvbEnable bool `json:",omitempty"`
+ BoardAvbEnable bool `json:",omitempty"`
+ BoardAvbAlgorithm string `json:",omitempty"`
+ BoardAvbKeyPath string `json:",omitempty"`
+ BoardAvbRollbackIndex string `json:",omitempty"`
+ BuildingVbmetaImage bool `json:",omitempty"`
+ ChainedVbmetaPartitions map[string]ChainedAvbPartitionProps `json:",omitempty"`
- ProductPackages []string `json:",omitempty"`
- ProductPackagesDebug []string `json:",omitempty"`
+ ProductPackages []string `json:",omitempty"`
+ ProductPackagesDebug []string `json:",omitempty"`
+ VendorLinkerConfigSrcs []string `json:",omitempty"`
+ ProductLinkerConfigSrcs []string `json:",omitempty"`
+
+ BoardInfoFiles []string `json:",omitempty"`
+ BootLoaderBoardName string `json:",omitempty"`
ProductCopyFiles map[string]string `json:",omitempty"`
+
+ BuildingSystemDlkmImage bool `json:",omitempty"`
+ SystemKernelModules []string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/android/vintf_data.go b/android/vintf_data.go
new file mode 100644
index 000000000..7823397e0
--- /dev/null
+++ b/android/vintf_data.go
@@ -0,0 +1,171 @@
+// 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 (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+const (
+ deviceCmType = "device_cm"
+ systemManifestType = "system_manifest"
+ productManifestType = "product_manifest"
+ systemExtManifestType = "system_ext_manifest"
+ vendorManifestType = "vendor_manifest"
+ odmManifestType = "odm_manifest"
+
+ defaultDcm = "system/libhidl/vintfdata/device_compatibility_matrix.default.xml"
+ defaultSystemManifest = "system/libhidl/vintfdata/manifest.xml"
+ defaultSystemExtManifest = "system/libhidl/vintfdata/system_ext_manifest.default.xml"
+)
+
+type vintfDataProperties struct {
+ // Optional name for the installed file. If unspecified it will be manifest.xml by default.
+ Filename *string
+
+ // Type of the vintf data type, the allowed type are device_compatibility_matrix, system_manifest,
+ // product_manifest, and system_ext_manifest.
+ Type *string
+}
+
+type vintfDataRule struct {
+ ModuleBase
+
+ properties vintfDataProperties
+
+ installDirPath InstallPath
+ outputFilePath OutputPath
+ noAction bool
+}
+
+func init() {
+ registerVintfDataComponents(InitRegistrationContext)
+}
+
+func registerVintfDataComponents(ctx RegistrationContext) {
+ ctx.RegisterModuleType("vintf_data", vintfDataFactory)
+}
+
+// vintf_fragment module processes vintf fragment file and installs under etc/vintf/manifest.
+func vintfDataFactory() Module {
+ m := &vintfDataRule{}
+ m.AddProperties(
+ &m.properties,
+ )
+ InitAndroidArchModule(m, DeviceSupported, MultilibFirst)
+
+ return m
+}
+
+func (m *vintfDataRule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ builder := NewRuleBuilder(pctx, ctx)
+ gensrc := PathForModuleOut(ctx, "manifest.xml")
+ assembleVintfEnvs := []string{}
+ inputPaths := make(Paths, 0)
+
+ switch proptools.String(m.properties.Type) {
+ case deviceCmType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().SystemSdkVersions(), " ")))
+
+ deviceMatrixs := PathsForSource(ctx, ctx.Config().DeviceMatrixFile())
+ if len(deviceMatrixs) > 0 {
+ inputPaths = append(inputPaths, deviceMatrixs...)
+ } else {
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultDcm))
+ }
+ case systemManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PLATFORM_SYSTEMSDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().PlatformSystemSdkVersions(), " ")))
+
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemManifest))
+ systemManifestFiles := PathsForSource(ctx, ctx.Config().SystemManifestFile())
+ if len(systemManifestFiles) > 0 {
+ inputPaths = append(inputPaths, systemManifestFiles...)
+ }
+ case productManifestType:
+ productManifestFiles := PathsForSource(ctx, ctx.Config().ProductManifestFiles())
+ // Only need to generate the manifest if PRODUCT_MANIFEST_FILES not defined.
+ if len(productManifestFiles) == 0 {
+ m.noAction = true
+ return
+ }
+
+ inputPaths = append(inputPaths, productManifestFiles...)
+ case systemExtManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PROVIDED_VNDK_VERSIONS=\"%s\"", strings.Join(ctx.DeviceConfig().ExtraVndkVersions(), " ")))
+
+ inputPaths = append(inputPaths, PathForSource(ctx, defaultSystemExtManifest))
+ systemExtManifestFiles := PathsForSource(ctx, ctx.Config().SystemExtManifestFiles())
+ if len(systemExtManifestFiles) > 0 {
+ inputPaths = append(inputPaths, systemExtManifestFiles...)
+ }
+ case vendorManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("BOARD_SEPOLICY_VERS=\"%s\"", ctx.DeviceConfig().BoardSepolicyVers()))
+ assembleVintfEnvs = append(assembleVintfEnvs, fmt.Sprintf("PRODUCT_ENFORCE_VINTF_MANIFEST=%t", *ctx.Config().productVariables.Enforce_vintf_manifest))
+ deviceManifestFiles := PathsForSource(ctx, ctx.Config().DeviceManifestFiles())
+ // Only need to generate the manifest if DEVICE_MANIFEST_FILE is defined.
+ if len(deviceManifestFiles) == 0 {
+ m.noAction = true
+ return
+ }
+
+ inputPaths = append(inputPaths, deviceManifestFiles...)
+ case odmManifestType:
+ assembleVintfEnvs = append(assembleVintfEnvs, "VINTF_IGNORE_TARGET_FCM_VERSION=true")
+ odmManifestFiles := PathsForSource(ctx, ctx.Config().OdmManifestFiles())
+ // Only need to generate the manifest if ODM_MANIFEST_FILES is defined.
+ if len(odmManifestFiles) == 0 {
+ m.noAction = true
+ return
+ }
+
+ inputPaths = append(inputPaths, odmManifestFiles...)
+ default:
+ panic(fmt.Errorf("For %s: The attribute 'type' value only allowed device_cm, system_manifest, product_manifest, system_ext_manifest!", ctx.Module().Name()))
+ }
+
+ // Process vintf fragment source file with assemble_vintf tool
+ builder.Command().
+ Flags(assembleVintfEnvs).
+ BuiltTool("assemble_vintf").
+ FlagWithArg("-i ", strings.Join(inputPaths.Strings(), ":")).
+ FlagWithOutput("-o ", gensrc)
+
+ builder.Build("assemble_vintf", "Process vintf data "+gensrc.String())
+
+ m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf")
+ m.outputFilePath = gensrc.OutputPath
+
+ installFileName := "manifest.xml"
+ if filename := proptools.String(m.properties.Filename); filename != "" {
+ installFileName = filename
+ }
+
+ ctx.InstallFile(m.installDirPath, installFileName, gensrc)
+}
+
+// Make this module visible to AndroidMK so it can be referenced from modules defined from Android.mk files
+func (m *vintfDataRule) AndroidMkEntries() []AndroidMkEntries {
+ if m.noAction {
+ return []AndroidMkEntries{}
+ }
+
+ return []AndroidMkEntries{{
+ Class: "ETC",
+ OutputFile: OptionalPathForPath(m.outputFilePath),
+ }}
+}