Compare commits
56 commits
c38f67a21e
...
876f0bb0d9
Author | SHA1 | Date | |
---|---|---|---|
|
876f0bb0d9 | ||
|
ac339f8e66 | ||
|
4c819d9401 | ||
|
3dccccee5e | ||
|
144754b153 | ||
|
2e6152ee86 | ||
|
f9b8137457 | ||
|
08cb1af507 | ||
|
3448cf213b | ||
|
2900689117 | ||
|
ec12b7dc1e | ||
|
831bbcdc38 | ||
|
e63689fec0 | ||
|
ce0cfaaf3f | ||
|
262fa746b8 | ||
|
fb75ec2011 | ||
|
f2ef1a3447 | ||
|
eebe034cc1 | ||
|
7a3899f93f | ||
|
3ea2ca1ede | ||
|
8cd40a7e3c | ||
|
feb21547f9 | ||
|
26e9a73798 | ||
|
4b2bb5e9ab | ||
|
24a3d377d8 | ||
|
a79bbf3bdb | ||
|
4427aab6e3 | ||
|
10ec15d67c | ||
|
989266aaff | ||
|
7889cf45fa | ||
|
3cc3ca4d62 | ||
|
bbf681deaf | ||
|
1d86a7f5e8 | ||
|
77b84c1f56 | ||
|
2dc6a269f1 | ||
|
4be39f9509 | ||
|
5b91c24c11 | ||
|
8b82c0d750 | ||
|
878adb61bf | ||
|
90d46b8e4b | ||
|
ba53cd2aba | ||
|
cd0f7bbd34 | ||
|
9d618bc55f | ||
|
d44bc5b281 | ||
|
243b54c46e | ||
|
d00a3c6c93 | ||
|
d0ee341157 | ||
|
87f74a3d2b | ||
|
17e9e9c0be | ||
|
f5c73b4700 | ||
|
34e34e8c1d | ||
|
277672eab4 | ||
|
7e2044fa35 | ||
|
a7671f2808 | ||
|
fee41a1895 | ||
|
c4ec0f2daa |
48 changed files with 1668 additions and 497 deletions
54
Android.bp
54
Android.bp
|
@ -121,18 +121,50 @@ dexpreopt_systemserver_check {
|
||||||
name: "dexpreopt_systemserver_check",
|
name: "dexpreopt_systemserver_check",
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildinfo.prop contains common properties for system/build.prop, like ro.build.version.*
|
|
||||||
buildinfo_prop {
|
|
||||||
name: "buildinfo.prop",
|
|
||||||
|
|
||||||
// not installable because this will be included to system/build.prop
|
|
||||||
installable: false,
|
|
||||||
|
|
||||||
// Currently, only microdroid can refer to buildinfo.prop
|
|
||||||
visibility: ["//packages/modules/Virtualization/microdroid"],
|
|
||||||
}
|
|
||||||
|
|
||||||
// container for apex_contributions selected using build flags
|
// container for apex_contributions selected using build flags
|
||||||
all_apex_contributions {
|
all_apex_contributions {
|
||||||
name: "all_apex_contributions",
|
name: "all_apex_contributions",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
product_config {
|
||||||
|
name: "product_config",
|
||||||
|
visibility: ["//device/google/cuttlefish/system_image"],
|
||||||
|
}
|
||||||
|
|
||||||
|
build_prop {
|
||||||
|
name: "system-build.prop",
|
||||||
|
stem: "build.prop",
|
||||||
|
product_config: ":product_config",
|
||||||
|
// Currently, only microdroid and cf system image can refer to system-build.prop
|
||||||
|
visibility: [
|
||||||
|
"//device/google/cuttlefish/system_image",
|
||||||
|
"//packages/modules/Virtualization/microdroid",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
build_prop {
|
||||||
|
name: "system_ext-build.prop",
|
||||||
|
stem: "build.prop",
|
||||||
|
system_ext_specific: true,
|
||||||
|
product_config: ":product_config",
|
||||||
|
relative_install_path: "etc", // system_ext/etc/build.prop
|
||||||
|
visibility: ["//visibility:private"],
|
||||||
|
}
|
||||||
|
|
||||||
|
build_prop {
|
||||||
|
name: "product-build.prop",
|
||||||
|
stem: "build.prop",
|
||||||
|
product_specific: true,
|
||||||
|
product_config: ":product_config",
|
||||||
|
relative_install_path: "etc", // product/etc/build.prop
|
||||||
|
visibility: ["//visibility:private"],
|
||||||
|
}
|
||||||
|
|
||||||
|
build_prop {
|
||||||
|
name: "odm-build.prop",
|
||||||
|
stem: "build.prop",
|
||||||
|
device_specific: true,
|
||||||
|
product_config: ":product_config",
|
||||||
|
relative_install_path: "etc", // odm/etc/build.prop
|
||||||
|
visibility: ["//visibility:private"],
|
||||||
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ bootstrap_go_package {
|
||||||
"arch_list.go",
|
"arch_list.go",
|
||||||
"arch_module_context.go",
|
"arch_module_context.go",
|
||||||
"base_module_context.go",
|
"base_module_context.go",
|
||||||
"buildinfo_prop.go",
|
"build_prop.go",
|
||||||
"config.go",
|
"config.go",
|
||||||
"test_config.go",
|
"test_config.go",
|
||||||
"configurable_properties.go",
|
"configurable_properties.go",
|
||||||
|
@ -83,6 +83,7 @@ bootstrap_go_package {
|
||||||
"plugin.go",
|
"plugin.go",
|
||||||
"prebuilt.go",
|
"prebuilt.go",
|
||||||
"prebuilt_build_tool.go",
|
"prebuilt_build_tool.go",
|
||||||
|
"product_config.go",
|
||||||
"proto.go",
|
"proto.go",
|
||||||
"provider.go",
|
"provider.go",
|
||||||
"raw_files.go",
|
"raw_files.go",
|
||||||
|
@ -110,6 +111,7 @@ bootstrap_go_package {
|
||||||
"androidmk_test.go",
|
"androidmk_test.go",
|
||||||
"apex_test.go",
|
"apex_test.go",
|
||||||
"arch_test.go",
|
"arch_test.go",
|
||||||
|
"blueprint_e2e_test.go",
|
||||||
"config_test.go",
|
"config_test.go",
|
||||||
"configured_jars_test.go",
|
"configured_jars_test.go",
|
||||||
"csuite_config_test.go",
|
"csuite_config_test.go",
|
||||||
|
|
|
@ -499,6 +499,7 @@ type fillInEntriesContext interface {
|
||||||
Config() Config
|
Config() Config
|
||||||
moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
|
moduleProvider(module blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
|
||||||
ModuleType(module blueprint.Module) string
|
ModuleType(module blueprint.Module) string
|
||||||
|
OtherModulePropertyErrorf(module Module, property string, fmt string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
|
func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
|
||||||
|
@ -514,7 +515,7 @@ func (a *AndroidMkEntries) fillInEntries(ctx fillInEntriesContext, mod blueprint
|
||||||
if a.Include == "" {
|
if a.Include == "" {
|
||||||
a.Include = "$(BUILD_PREBUILT)"
|
a.Include = "$(BUILD_PREBUILT)"
|
||||||
}
|
}
|
||||||
a.Required = append(a.Required, amod.RequiredModuleNames()...)
|
a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
|
||||||
a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
|
a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
|
||||||
a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
|
a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
|
||||||
|
|
||||||
|
|
105
android/blueprint_e2e_test.go
Normal file
105
android/blueprint_e2e_test.go
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testCases []struct {
|
||||||
|
name string
|
||||||
|
fs MockFS
|
||||||
|
expectedError string
|
||||||
|
} = []struct {
|
||||||
|
name string
|
||||||
|
fs MockFS
|
||||||
|
expectedError string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Can't reference variable before assignment",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
x = foo
|
||||||
|
foo = "hello"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "undefined variable foo",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Can't append to variable before assigned to",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
foo += "world"
|
||||||
|
foo = "hello"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "modified non-existent variable \"foo\" with \\+=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Can't reassign variable",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
foo = "hello"
|
||||||
|
foo = "world"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "variable already set, previous assignment:",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Can't reassign variable in inherited scope",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
foo = "hello"
|
||||||
|
`),
|
||||||
|
"foo/Android.bp": []byte(`
|
||||||
|
foo = "world"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "variable already set in inherited scope, previous assignment:",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Can't modify variable in inherited scope",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
foo = "hello"
|
||||||
|
`),
|
||||||
|
"foo/Android.bp": []byte(`
|
||||||
|
foo += "world"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "modified non-local variable \"foo\" with \\+=",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Can't modify variable after referencing",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
foo = "hello"
|
||||||
|
x = foo
|
||||||
|
foo += "world"
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
expectedError: "modified variable \"foo\" with \\+= after referencing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlueprintErrors(t *testing.T) {
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
fixtures := FixtureMergeMockFs(tc.fs)
|
||||||
|
fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
|
||||||
|
fixtures.RunTest(t)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
195
android/build_prop.go
Normal file
195
android/build_prop.go
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
// 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/proptools"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ctx := InitRegistrationContext
|
||||||
|
ctx.RegisterModuleType("build_prop", buildPropFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
type buildPropProperties struct {
|
||||||
|
// Output file name. Defaults to "build.prop"
|
||||||
|
Stem *string
|
||||||
|
|
||||||
|
// List of prop names to exclude. This affects not only common build properties but also
|
||||||
|
// properties in prop_files.
|
||||||
|
Block_list []string
|
||||||
|
|
||||||
|
// Files to be appended at the end of build.prop. These files are appended after
|
||||||
|
// post_process_props without any further checking.
|
||||||
|
Footer_files []string `android:"path"`
|
||||||
|
|
||||||
|
// Path to a JSON file containing product configs.
|
||||||
|
Product_config *string `android:"path"`
|
||||||
|
|
||||||
|
// Optional subdirectory under which this file is installed into
|
||||||
|
Relative_install_path *string
|
||||||
|
}
|
||||||
|
|
||||||
|
type buildPropModule struct {
|
||||||
|
ModuleBase
|
||||||
|
|
||||||
|
properties buildPropProperties
|
||||||
|
|
||||||
|
outputFilePath OutputPath
|
||||||
|
installPath InstallPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *buildPropModule) stem() string {
|
||||||
|
return proptools.StringDefault(p.properties.Stem, "build.prop")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *buildPropModule) propFiles(ctx ModuleContext) Paths {
|
||||||
|
partition := p.partition(ctx.DeviceConfig())
|
||||||
|
if partition == "system" {
|
||||||
|
return ctx.Config().SystemPropFiles(ctx)
|
||||||
|
} else if partition == "system_ext" {
|
||||||
|
return ctx.Config().SystemExtPropFiles(ctx)
|
||||||
|
} else if partition == "product" {
|
||||||
|
return ctx.Config().ProductPropFiles(ctx)
|
||||||
|
} else if partition == "odm" {
|
||||||
|
return ctx.Config().OdmPropFiles(ctx)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldAddBuildThumbprint(config Config) bool {
|
||||||
|
knownOemProperties := []string{
|
||||||
|
"ro.product.brand",
|
||||||
|
"ro.product.name",
|
||||||
|
"ro.product.device",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, knownProp := range knownOemProperties {
|
||||||
|
if InList(knownProp, config.OemProperties()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can't use PartitionTag() because PartitionTag() returns the partition this module is actually
|
||||||
|
// installed (e.g. odm module's partition tag can be either "odm" or "vendor")
|
||||||
|
func (p *buildPropModule) partition(config DeviceConfig) string {
|
||||||
|
if p.SocSpecific() {
|
||||||
|
return "vendor"
|
||||||
|
} else if p.DeviceSpecific() {
|
||||||
|
return "odm"
|
||||||
|
} else if p.ProductSpecific() {
|
||||||
|
return "product"
|
||||||
|
} else if p.SystemExtSpecific() {
|
||||||
|
return "system_ext"
|
||||||
|
}
|
||||||
|
return "system"
|
||||||
|
}
|
||||||
|
|
||||||
|
var validPartitions = []string{
|
||||||
|
"system",
|
||||||
|
"system_ext",
|
||||||
|
"product",
|
||||||
|
"odm",
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
partition := p.partition(ctx.DeviceConfig())
|
||||||
|
if !InList(partition, validPartitions) {
|
||||||
|
ctx.PropertyErrorf("partition", "unsupported partition %q: only %q are supported", partition, validPartitions)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rule := NewRuleBuilder(pctx, ctx)
|
||||||
|
|
||||||
|
config := ctx.Config()
|
||||||
|
|
||||||
|
cmd := rule.Command().BuiltTool("gen_build_prop")
|
||||||
|
|
||||||
|
cmd.FlagWithInput("--build-hostname-file=", config.BuildHostnameFile(ctx))
|
||||||
|
cmd.FlagWithInput("--build-number-file=", config.BuildNumberFile(ctx))
|
||||||
|
// shouldn't depend on BuildFingerprintFile and BuildThumbprintFile to prevent from rebuilding
|
||||||
|
// on every incremental build.
|
||||||
|
cmd.FlagWithArg("--build-fingerprint-file=", config.BuildFingerprintFile(ctx).String())
|
||||||
|
// Export build thumbprint only if the product has specified at least one oem fingerprint property
|
||||||
|
// b/17888863
|
||||||
|
if shouldAddBuildThumbprint(config) {
|
||||||
|
// In the previous make implementation, a dependency was not added on the thumbprint file
|
||||||
|
cmd.FlagWithArg("--build-thumbprint-file=", config.BuildThumbprintFile(ctx).String())
|
||||||
|
}
|
||||||
|
cmd.FlagWithArg("--build-username=", config.Getenv("BUILD_USERNAME"))
|
||||||
|
// shouldn't depend on BUILD_DATETIME_FILE to prevent from rebuilding on every incremental
|
||||||
|
// build.
|
||||||
|
cmd.FlagWithArg("--date-file=", ctx.Config().Getenv("BUILD_DATETIME_FILE"))
|
||||||
|
cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx))
|
||||||
|
cmd.FlagWithInput("--product-config=", PathForModuleSrc(ctx, proptools.String(p.properties.Product_config)))
|
||||||
|
cmd.FlagWithArg("--partition=", partition)
|
||||||
|
cmd.FlagForEachInput("--prop-files=", p.propFiles(ctx))
|
||||||
|
cmd.FlagWithOutput("--out=", p.outputFilePath)
|
||||||
|
|
||||||
|
postProcessCmd := rule.Command().BuiltTool("post_process_props")
|
||||||
|
if ctx.DeviceConfig().BuildBrokenDupSysprop() {
|
||||||
|
postProcessCmd.Flag("--allow-dup")
|
||||||
|
}
|
||||||
|
postProcessCmd.FlagWithArg("--sdk-version ", config.PlatformSdkVersion().String())
|
||||||
|
if ctx.Config().EnableUffdGc() == "default" {
|
||||||
|
postProcessCmd.FlagWithInput("--kernel-version-file-for-uffd-gc ", PathForOutput(ctx, "dexpreopt/kernel_version_for_uffd_gc.txt"))
|
||||||
|
} else {
|
||||||
|
// still need to pass an empty string to kernel-version-file-for-uffd-gc
|
||||||
|
postProcessCmd.FlagWithArg("--kernel-version-file-for-uffd-gc ", `""`)
|
||||||
|
}
|
||||||
|
postProcessCmd.Text(p.outputFilePath.String())
|
||||||
|
postProcessCmd.Flags(p.properties.Block_list)
|
||||||
|
|
||||||
|
rule.Command().Text("echo").Text(proptools.NinjaAndShellEscape("# end of file")).FlagWithArg(">> ", p.outputFilePath.String())
|
||||||
|
|
||||||
|
rule.Build(ctx.ModuleName(), "generating build.prop")
|
||||||
|
|
||||||
|
p.installPath = PathForModuleInstall(ctx, proptools.String(p.properties.Relative_install_path))
|
||||||
|
ctx.InstallFile(p.installPath, p.stem(), p.outputFilePath)
|
||||||
|
|
||||||
|
ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *buildPropModule) AndroidMkEntries() []AndroidMkEntries {
|
||||||
|
return []AndroidMkEntries{{
|
||||||
|
Class: "ETC",
|
||||||
|
OutputFile: OptionalPathForPath(p.outputFilePath),
|
||||||
|
ExtraEntries: []AndroidMkExtraEntriesFunc{
|
||||||
|
func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
|
||||||
|
entries.SetString("LOCAL_MODULE_PATH", p.installPath.String())
|
||||||
|
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build_prop module generates {partition}/build.prop file. At first common build properties are
|
||||||
|
// printed based on Soong config variables. And then prop_files are printed as-is. Finally,
|
||||||
|
// post_process_props tool is run to check if the result build.prop is valid or not.
|
||||||
|
func buildPropFactory() Module {
|
||||||
|
module := &buildPropModule{}
|
||||||
|
module.AddProperties(&module.properties)
|
||||||
|
InitAndroidArchModule(module, DeviceSupported, MultilibCommon)
|
||||||
|
return module
|
||||||
|
}
|
|
@ -1,195 +0,0 @@
|
||||||
// Copyright 2022 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"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
ctx := InitRegistrationContext
|
|
||||||
ctx.RegisterModuleType("buildinfo_prop", buildinfoPropFactory)
|
|
||||||
}
|
|
||||||
|
|
||||||
type buildinfoPropProperties struct {
|
|
||||||
// Whether this module is directly installable to one of the partitions. Default: true.
|
|
||||||
Installable *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type buildinfoPropModule struct {
|
|
||||||
ModuleBase
|
|
||||||
|
|
||||||
properties buildinfoPropProperties
|
|
||||||
|
|
||||||
outputFilePath OutputPath
|
|
||||||
installPath InstallPath
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ OutputFileProducer = (*buildinfoPropModule)(nil)
|
|
||||||
|
|
||||||
func (p *buildinfoPropModule) installable() bool {
|
|
||||||
return proptools.BoolDefault(p.properties.Installable, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OutputFileProducer
|
|
||||||
func (p *buildinfoPropModule) OutputFiles(tag string) (Paths, error) {
|
|
||||||
if tag != "" {
|
|
||||||
return nil, fmt.Errorf("unsupported tag %q", tag)
|
|
||||||
}
|
|
||||||
return Paths{p.outputFilePath}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBuildVariant(config Config) string {
|
|
||||||
if config.Eng() {
|
|
||||||
return "eng"
|
|
||||||
} else if config.Debuggable() {
|
|
||||||
return "userdebug"
|
|
||||||
} else {
|
|
||||||
return "user"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBuildFlavor(config Config) string {
|
|
||||||
buildFlavor := config.DeviceProduct() + "-" + getBuildVariant(config)
|
|
||||||
if InList("address", config.SanitizeDevice()) && !strings.Contains(buildFlavor, "_asan") {
|
|
||||||
buildFlavor += "_asan"
|
|
||||||
}
|
|
||||||
return buildFlavor
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldAddBuildThumbprint(config Config) bool {
|
|
||||||
knownOemProperties := []string{
|
|
||||||
"ro.product.brand",
|
|
||||||
"ro.product.name",
|
|
||||||
"ro.product.device",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, knownProp := range knownOemProperties {
|
|
||||||
if InList(knownProp, config.OemProperties()) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *buildinfoPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|
||||||
if ctx.ModuleName() != "buildinfo.prop" || ctx.ModuleDir() != "build/soong" {
|
|
||||||
ctx.ModuleErrorf("There can only be one buildinfo_prop module in build/soong")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.outputFilePath = PathForModuleOut(ctx, p.Name()).OutputPath
|
|
||||||
if !ctx.Config().KatiEnabled() {
|
|
||||||
WriteFileRule(ctx, p.outputFilePath, "# no buildinfo.prop if kati is disabled")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rule := NewRuleBuilder(pctx, ctx)
|
|
||||||
|
|
||||||
config := ctx.Config()
|
|
||||||
buildVariant := getBuildVariant(config)
|
|
||||||
buildFlavor := getBuildFlavor(config)
|
|
||||||
|
|
||||||
cmd := rule.Command().BuiltTool("buildinfo")
|
|
||||||
|
|
||||||
if config.BoardUseVbmetaDigestInFingerprint() {
|
|
||||||
cmd.Flag("--use-vbmeta-digest-in-fingerprint")
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.FlagWithArg("--build-flavor=", buildFlavor)
|
|
||||||
cmd.FlagWithInput("--build-hostname-file=", config.BuildHostnameFile(ctx))
|
|
||||||
cmd.FlagWithArg("--build-id=", config.BuildId())
|
|
||||||
cmd.FlagWithArg("--build-keys=", config.BuildKeys())
|
|
||||||
|
|
||||||
// Note: depending on BuildNumberFile will cause the build.prop file to be rebuilt
|
|
||||||
// every build, but that's intentional.
|
|
||||||
cmd.FlagWithInput("--build-number-file=", config.BuildNumberFile(ctx))
|
|
||||||
if shouldAddBuildThumbprint(config) {
|
|
||||||
// In the previous make implementation, a dependency was not added on the thumbprint file
|
|
||||||
cmd.FlagWithArg("--build-thumbprint-file=", config.BuildThumbprintFile(ctx).String())
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.FlagWithArg("--build-type=", config.BuildType())
|
|
||||||
cmd.FlagWithArg("--build-username=", config.Getenv("BUILD_USERNAME"))
|
|
||||||
cmd.FlagWithArg("--build-variant=", buildVariant)
|
|
||||||
cmd.FlagForEachArg("--cpu-abis=", config.DeviceAbi())
|
|
||||||
|
|
||||||
// Technically we should also have a dependency on BUILD_DATETIME_FILE,
|
|
||||||
// but it can be either an absolute or relative path, which is hard to turn into
|
|
||||||
// a Path object. So just rely on the BuildNumberFile always changing to cause
|
|
||||||
// us to rebuild.
|
|
||||||
cmd.FlagWithArg("--date-file=", ctx.Config().Getenv("BUILD_DATETIME_FILE"))
|
|
||||||
|
|
||||||
if len(config.ProductLocales()) > 0 {
|
|
||||||
cmd.FlagWithArg("--default-locale=", config.ProductLocales()[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.FlagForEachArg("--default-wifi-channels=", config.ProductDefaultWifiChannels())
|
|
||||||
cmd.FlagWithArg("--device=", config.DeviceName())
|
|
||||||
if config.DisplayBuildNumber() {
|
|
||||||
cmd.Flag("--display-build-number")
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.FlagWithArg("--platform-base-os=", config.PlatformBaseOS())
|
|
||||||
cmd.FlagWithArg("--platform-display-version=", config.PlatformDisplayVersionName())
|
|
||||||
cmd.FlagWithArg("--platform-min-supported-target-sdk-version=", config.PlatformMinSupportedTargetSdkVersion())
|
|
||||||
cmd.FlagWithInput("--platform-preview-sdk-fingerprint-file=", ApiFingerprintPath(ctx))
|
|
||||||
cmd.FlagWithArg("--platform-preview-sdk-version=", config.PlatformPreviewSdkVersion())
|
|
||||||
cmd.FlagWithArg("--platform-sdk-version=", config.PlatformSdkVersion().String())
|
|
||||||
cmd.FlagWithArg("--platform-security-patch=", config.PlatformSecurityPatch())
|
|
||||||
cmd.FlagWithArg("--platform-version=", config.PlatformVersionName())
|
|
||||||
cmd.FlagWithArg("--platform-version-codename=", config.PlatformSdkCodename())
|
|
||||||
cmd.FlagForEachArg("--platform-version-all-codenames=", config.PlatformVersionActiveCodenames())
|
|
||||||
cmd.FlagWithArg("--platform-version-known-codenames=", config.PlatformVersionKnownCodenames())
|
|
||||||
cmd.FlagWithArg("--platform-version-last-stable=", config.PlatformVersionLastStable())
|
|
||||||
cmd.FlagWithArg("--product=", config.DeviceProduct())
|
|
||||||
|
|
||||||
cmd.FlagWithOutput("--out=", p.outputFilePath)
|
|
||||||
|
|
||||||
rule.Build(ctx.ModuleName(), "generating buildinfo props")
|
|
||||||
|
|
||||||
if !p.installable() {
|
|
||||||
p.SkipInstall()
|
|
||||||
}
|
|
||||||
|
|
||||||
p.installPath = PathForModuleInstall(ctx)
|
|
||||||
ctx.InstallFile(p.installPath, p.Name(), p.outputFilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *buildinfoPropModule) AndroidMkEntries() []AndroidMkEntries {
|
|
||||||
return []AndroidMkEntries{{
|
|
||||||
Class: "ETC",
|
|
||||||
OutputFile: OptionalPathForPath(p.outputFilePath),
|
|
||||||
ExtraEntries: []AndroidMkExtraEntriesFunc{
|
|
||||||
func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
|
|
||||||
entries.SetString("LOCAL_MODULE_PATH", p.installPath.String())
|
|
||||||
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
|
|
||||||
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildinfo_prop module generates a build.prop file, which contains a set of common
|
|
||||||
// system/build.prop properties, such as ro.build.version.*. Not all properties are implemented;
|
|
||||||
// currently this module is only for microdroid.
|
|
||||||
func buildinfoPropFactory() Module {
|
|
||||||
module := &buildinfoPropModule{}
|
|
||||||
module.AddProperties(&module.properties)
|
|
||||||
InitAndroidModule(module)
|
|
||||||
return module
|
|
||||||
}
|
|
|
@ -784,6 +784,17 @@ func (c *config) DisplayBuildNumber() bool {
|
||||||
return Bool(c.productVariables.DisplayBuildNumber)
|
return Bool(c.productVariables.DisplayBuildNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildFingerprintFile returns the path to a text file containing metadata
|
||||||
|
// representing the current build's fingerprint.
|
||||||
|
//
|
||||||
|
// Rules that want to reference the build fingerprint should read from this file
|
||||||
|
// without depending on it. They will run whenever their other dependencies
|
||||||
|
// require them to run and get the current build fingerprint. This ensures they
|
||||||
|
// don't rebuild on every incremental build when the build number changes.
|
||||||
|
func (c *config) BuildFingerprintFile(ctx PathContext) Path {
|
||||||
|
return PathForArbitraryOutput(ctx, "target", "product", c.DeviceName(), String(c.productVariables.BuildFingerprintFile))
|
||||||
|
}
|
||||||
|
|
||||||
// BuildNumberFile returns the path to a text file containing metadata
|
// BuildNumberFile returns the path to a text file containing metadata
|
||||||
// representing the current build's number.
|
// representing the current build's number.
|
||||||
//
|
//
|
||||||
|
@ -1423,6 +1434,10 @@ func (c *deviceConfig) DeviceKernelHeaderDirs() []string {
|
||||||
return c.config.productVariables.DeviceKernelHeaders
|
return c.config.productVariables.DeviceKernelHeaders
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *deviceConfig) TargetSpecificHeaderPath() string {
|
||||||
|
return String(c.config.productVariables.TargetSpecificHeaderPath)
|
||||||
|
}
|
||||||
|
|
||||||
// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
|
// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for
|
||||||
// path. Coverage is enabled by default when the product variable
|
// path. Coverage is enabled by default when the product variable
|
||||||
// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
|
// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is
|
||||||
|
@ -1883,6 +1898,10 @@ func (c *deviceConfig) BuildBrokenDontCheckSystemSdk() bool {
|
||||||
return c.config.productVariables.BuildBrokenDontCheckSystemSdk
|
return c.config.productVariables.BuildBrokenDontCheckSystemSdk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *deviceConfig) BuildBrokenDupSysprop() bool {
|
||||||
|
return c.config.productVariables.BuildBrokenDupSysprop
|
||||||
|
}
|
||||||
|
|
||||||
func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string {
|
func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string {
|
||||||
return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist
|
return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist
|
||||||
}
|
}
|
||||||
|
@ -2078,3 +2097,31 @@ func (c *config) BoardUseVbmetaDigestInFingerprint() bool {
|
||||||
func (c *config) OemProperties() []string {
|
func (c *config) OemProperties() []string {
|
||||||
return c.productVariables.OemProperties
|
return c.productVariables.OemProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *config) UseDebugArt() bool {
|
||||||
|
if c.productVariables.ArtTargetIncludeDebugBuild != nil {
|
||||||
|
return Bool(c.productVariables.ArtTargetIncludeDebugBuild)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bool(c.productVariables.Eng)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) SystemPropFiles(ctx PathContext) Paths {
|
||||||
|
return PathsForSource(ctx, c.productVariables.SystemPropFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) SystemExtPropFiles(ctx PathContext) Paths {
|
||||||
|
return PathsForSource(ctx, c.productVariables.SystemExtPropFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) ProductPropFiles(ctx PathContext) Paths {
|
||||||
|
return PathsForSource(ctx, c.productVariables.ProductPropFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) OdmPropFiles(ctx PathContext) Paths {
|
||||||
|
return PathsForSource(ctx, c.productVariables.OdmPropFiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *config) EnableUffdGc() string {
|
||||||
|
return String(c.productVariables.EnableUffdGc)
|
||||||
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ type defaultsDependencyTag struct {
|
||||||
var DefaultsDepTag defaultsDependencyTag
|
var DefaultsDepTag defaultsDependencyTag
|
||||||
|
|
||||||
type defaultsProperties struct {
|
type defaultsProperties struct {
|
||||||
Defaults []string
|
Defaults proptools.Configurable[[]string]
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultableModuleBase struct {
|
type DefaultableModuleBase struct {
|
||||||
|
@ -278,13 +278,14 @@ func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
|
||||||
|
|
||||||
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
|
func defaultsDepsMutator(ctx BottomUpMutatorContext) {
|
||||||
if defaultable, ok := ctx.Module().(Defaultable); ok {
|
if defaultable, ok := ctx.Module().(Defaultable); ok {
|
||||||
ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
|
ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults.GetOrDefault(ctx, nil)...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultsMutator(ctx TopDownMutatorContext) {
|
func defaultsMutator(ctx TopDownMutatorContext) {
|
||||||
if defaultable, ok := ctx.Module().(Defaultable); ok {
|
if defaultable, ok := ctx.Module().(Defaultable); ok {
|
||||||
if len(defaultable.defaults().Defaults) > 0 {
|
defaults := defaultable.defaults().Defaults.GetOrDefault(ctx, nil)
|
||||||
|
if len(defaults) > 0 {
|
||||||
var defaultsList []Defaults
|
var defaultsList []Defaults
|
||||||
seen := make(map[Defaults]bool)
|
seen := make(map[Defaults]bool)
|
||||||
|
|
||||||
|
@ -294,7 +295,7 @@ func defaultsMutator(ctx TopDownMutatorContext) {
|
||||||
if !seen[defaults] {
|
if !seen[defaults] {
|
||||||
seen[defaults] = true
|
seen[defaults] = true
|
||||||
defaultsList = append(defaultsList, defaults)
|
defaultsList = append(defaultsList, defaults)
|
||||||
return len(defaults.defaults().Defaults) > 0
|
return len(defaults.defaults().Defaults.GetOrDefault(ctx, nil)) > 0
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
|
ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
|
||||||
|
|
|
@ -113,7 +113,7 @@ type Module interface {
|
||||||
// Get information about the properties that can contain visibility rules.
|
// Get information about the properties that can contain visibility rules.
|
||||||
visibilityProperties() []visibilityProperty
|
visibilityProperties() []visibilityProperty
|
||||||
|
|
||||||
RequiredModuleNames() []string
|
RequiredModuleNames(ctx ConfigAndErrorContext) []string
|
||||||
HostRequiredModuleNames() []string
|
HostRequiredModuleNames() []string
|
||||||
TargetRequiredModuleNames() []string
|
TargetRequiredModuleNames() []string
|
||||||
|
|
||||||
|
@ -419,10 +419,10 @@ type commonProperties struct {
|
||||||
Init_rc []string `android:"arch_variant,path"`
|
Init_rc []string `android:"arch_variant,path"`
|
||||||
|
|
||||||
// VINTF manifest fragments to be installed if this module is installed
|
// VINTF manifest fragments to be installed if this module is installed
|
||||||
Vintf_fragments []string `android:"path"`
|
Vintf_fragments proptools.Configurable[[]string] `android:"path"`
|
||||||
|
|
||||||
// names of other modules to install if this module is installed
|
// names of other modules to install if this module is installed
|
||||||
Required []string `android:"arch_variant"`
|
Required proptools.Configurable[[]string] `android:"arch_variant"`
|
||||||
|
|
||||||
// names of other modules to install on host if this module is installed
|
// names of other modules to install on host if this module is installed
|
||||||
Host_required []string `android:"arch_variant"`
|
Host_required []string `android:"arch_variant"`
|
||||||
|
@ -1101,7 +1101,7 @@ func addRequiredDeps(ctx BottomUpMutatorContext) {
|
||||||
hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
|
hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
|
||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
for _, depName := range ctx.Module().RequiredModuleNames() {
|
for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
|
||||||
for _, target := range deviceTargets {
|
for _, target := range deviceTargets {
|
||||||
addDep(target, depName)
|
addDep(target, depName)
|
||||||
}
|
}
|
||||||
|
@ -1114,7 +1114,7 @@ func addRequiredDeps(ctx BottomUpMutatorContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Host() {
|
if ctx.Host() {
|
||||||
for _, depName := range ctx.Module().RequiredModuleNames() {
|
for _, depName := range ctx.Module().RequiredModuleNames(ctx) {
|
||||||
for _, target := range hostTargets {
|
for _, target := range hostTargets {
|
||||||
// When a host module requires another host module, don't make a
|
// When a host module requires another host module, don't make a
|
||||||
// dependency if they have different OSes (i.e. hostcross).
|
// dependency if they have different OSes (i.e. hostcross).
|
||||||
|
@ -1619,8 +1619,8 @@ func (m *ModuleBase) InRecovery() bool {
|
||||||
return m.base().commonProperties.ImageVariation == RecoveryVariation
|
return m.base().commonProperties.ImageVariation == RecoveryVariation
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModuleBase) RequiredModuleNames() []string {
|
func (m *ModuleBase) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
|
||||||
return m.base().commonProperties.Required
|
return m.base().commonProperties.Required.GetOrDefault(m.ConfigurableEvaluator(ctx), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModuleBase) HostRequiredModuleNames() []string {
|
func (m *ModuleBase) HostRequiredModuleNames() []string {
|
||||||
|
@ -1881,7 +1881,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments)
|
m.vintfFragmentsPaths = PathsForModuleSrc(ctx, m.commonProperties.Vintf_fragments.GetOrDefault(ctx, nil))
|
||||||
vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
|
vintfDir := PathForModuleInstall(ctx, "etc", "vintf", "manifest")
|
||||||
for _, src := range m.vintfFragmentsPaths {
|
for _, src := range m.vintfFragmentsPaths {
|
||||||
installedVintfFragment := vintfDir.Join(ctx, src.Base())
|
installedVintfFragment := vintfDir.Join(ctx, src.Base())
|
||||||
|
@ -1992,7 +1992,7 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
||||||
TargetDependencies: targetRequired,
|
TargetDependencies: targetRequired,
|
||||||
HostDependencies: hostRequired,
|
HostDependencies: hostRequired,
|
||||||
Data: data,
|
Data: data,
|
||||||
Required: m.RequiredModuleNames(),
|
Required: m.RequiredModuleNames(ctx),
|
||||||
}
|
}
|
||||||
SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
|
SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
|
||||||
}
|
}
|
||||||
|
@ -2194,6 +2194,9 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu
|
||||||
switch variable {
|
switch variable {
|
||||||
case "debuggable":
|
case "debuggable":
|
||||||
return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
|
return proptools.ConfigurableValueBool(ctx.Config().Debuggable())
|
||||||
|
case "use_debug_art":
|
||||||
|
// TODO(b/234351700): Remove once ART does not have separated debug APEX
|
||||||
|
return proptools.ConfigurableValueBool(ctx.Config().UseDebugArt())
|
||||||
default:
|
default:
|
||||||
// TODO(b/323382414): Might add these on a case-by-case basis
|
// TODO(b/323382414): Might add these on a case-by-case basis
|
||||||
ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
|
ctx.OtherModulePropertyErrorf(m, property, fmt.Sprintf("TODO(b/323382414): Product variable %q is not yet supported in selects", variable))
|
||||||
|
@ -2208,7 +2211,20 @@ func (e configurationEvalutor) EvaluateConfiguration(condition proptools.Configu
|
||||||
variable := condition.Arg(1)
|
variable := condition.Arg(1)
|
||||||
if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
|
if n, ok := ctx.Config().productVariables.VendorVars[namespace]; ok {
|
||||||
if v, ok := n[variable]; ok {
|
if v, ok := n[variable]; ok {
|
||||||
return proptools.ConfigurableValueString(v)
|
ty := ""
|
||||||
|
if namespaces, ok := ctx.Config().productVariables.VendorVarTypes[namespace]; ok {
|
||||||
|
ty = namespaces[variable]
|
||||||
|
}
|
||||||
|
switch ty {
|
||||||
|
case "":
|
||||||
|
// strings are the default, we don't bother writing them to the soong variables json file
|
||||||
|
return proptools.ConfigurableValueString(v)
|
||||||
|
case "bool":
|
||||||
|
return proptools.ConfigurableValueBool(v == "true")
|
||||||
|
default:
|
||||||
|
panic("unhandled soong config variable type: " + ty)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return proptools.ConfigurableValueUndefined()
|
return proptools.ConfigurableValueUndefined()
|
||||||
|
|
|
@ -183,7 +183,7 @@ type ModuleContext interface {
|
||||||
InstallInVendor() bool
|
InstallInVendor() bool
|
||||||
InstallForceOS() (*OsType, *ArchType)
|
InstallForceOS() (*OsType, *ArchType)
|
||||||
|
|
||||||
RequiredModuleNames() []string
|
RequiredModuleNames(ctx ConfigAndErrorContext) []string
|
||||||
HostRequiredModuleNames() []string
|
HostRequiredModuleNames() []string
|
||||||
TargetRequiredModuleNames() []string
|
TargetRequiredModuleNames() []string
|
||||||
|
|
||||||
|
@ -755,8 +755,8 @@ func (m *moduleContext) ExpandOptionalSource(srcFile *string, _ string) Optional
|
||||||
return OptionalPath{}
|
return OptionalPath{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *moduleContext) RequiredModuleNames() []string {
|
func (m *moduleContext) RequiredModuleNames(ctx ConfigAndErrorContext) []string {
|
||||||
return m.module.RequiredModuleNames()
|
return m.module.RequiredModuleNames(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *moduleContext) HostRequiredModuleNames() []string {
|
func (m *moduleContext) HostRequiredModuleNames() []string {
|
||||||
|
|
|
@ -722,7 +722,6 @@ test {
|
||||||
propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
|
propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"},
|
||||||
propInfo{Name: "B", Type: "bool", Value: "true"},
|
propInfo{Name: "B", Type: "bool", Value: "true"},
|
||||||
propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
|
propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}},
|
||||||
propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}},
|
|
||||||
propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
|
propInfo{Name: "Embedded_prop", Type: "string", Value: "a"},
|
||||||
propInfo{Name: "Name", Type: "string", Value: "foo"},
|
propInfo{Name: "Name", Type: "string", Value: "foo"},
|
||||||
propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
|
propInfo{Name: "Nested.E", Type: "string", Value: "nested e"},
|
||||||
|
@ -746,7 +745,6 @@ test {
|
||||||
foo := result.ModuleForTests("foo", "").Module().base()
|
foo := result.ModuleForTests("foo", "").Module().base()
|
||||||
|
|
||||||
AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
|
AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues())
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2020,7 +2020,7 @@ func validatePathInternal(allowNinjaVariables bool, pathComponents ...string) (s
|
||||||
}
|
}
|
||||||
|
|
||||||
path := filepath.Clean(path)
|
path := filepath.Clean(path)
|
||||||
if path == ".." || strings.HasPrefix(path, "../") || strings.HasPrefix(path, "/") {
|
if path == ".." || strings.HasPrefix(path, "../") || i != initialEmpty && strings.HasPrefix(path, "/") {
|
||||||
return "", fmt.Errorf("Path is outside directory: %s", path)
|
return "", fmt.Errorf("Path is outside directory: %s", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
58
android/product_config.go
Normal file
58
android/product_config.go
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// 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/proptools"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
ctx := InitRegistrationContext
|
||||||
|
ctx.RegisterModuleType("product_config", productConfigFactory)
|
||||||
|
}
|
||||||
|
|
||||||
|
type productConfigModule struct {
|
||||||
|
ModuleBase
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *productConfigModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
|
if ctx.ModuleName() != "product_config" || ctx.ModuleDir() != "build/soong" {
|
||||||
|
ctx.ModuleErrorf("There can only be one product_config module in build/soong")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
outputFilePath := PathForModuleOut(ctx, p.Name()+".json").OutputPath
|
||||||
|
|
||||||
|
// DeviceProduct can be null so calling ctx.Config().DeviceProduct() may cause null dereference
|
||||||
|
targetProduct := proptools.String(ctx.Config().config.productVariables.DeviceProduct)
|
||||||
|
if targetProduct != "" {
|
||||||
|
targetProduct += "."
|
||||||
|
}
|
||||||
|
soongVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"variables")
|
||||||
|
extraVariablesPath := PathForOutput(ctx, "soong."+targetProduct+"extra.variables")
|
||||||
|
|
||||||
|
rule := NewRuleBuilder(pctx, ctx)
|
||||||
|
rule.Command().BuiltTool("merge_json").
|
||||||
|
Output(outputFilePath).
|
||||||
|
Input(soongVariablesPath).
|
||||||
|
Input(extraVariablesPath).
|
||||||
|
rule.Build("product_config.json", "building product_config.json")
|
||||||
|
|
||||||
|
ctx.SetOutputFiles(Paths{outputFilePath}, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// product_config module exports product variables and extra variables as a JSON file.
|
||||||
|
func productConfigFactory() Module {
|
||||||
|
module := &productConfigModule{}
|
||||||
|
InitAndroidModule(module)
|
||||||
|
return module
|
||||||
|
}
|
|
@ -25,12 +25,14 @@ import (
|
||||||
|
|
||||||
func TestSelects(t *testing.T) {
|
func TestSelects(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
bp string
|
bp string
|
||||||
provider selectsTestProvider
|
fs MockFS
|
||||||
providers map[string]selectsTestProvider
|
provider selectsTestProvider
|
||||||
vendorVars map[string]map[string]string
|
providers map[string]selectsTestProvider
|
||||||
expectedError string
|
vendorVars map[string]map[string]string
|
||||||
|
vendorVarTypes map[string]map[string]string
|
||||||
|
expectedError string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "basic string list",
|
name: "basic string list",
|
||||||
|
@ -96,6 +98,26 @@ func TestSelects(t *testing.T) {
|
||||||
my_paths: &[]string{"baz.txt"},
|
my_paths: &[]string{"baz.txt"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Expression in select",
|
||||||
|
bp: `
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
"a": "foo" + "bar",
|
||||||
|
default: "baz",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("foobar"),
|
||||||
|
},
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "a",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "paths with module references",
|
name: "paths with module references",
|
||||||
bp: `
|
bp: `
|
||||||
|
@ -110,20 +132,6 @@ func TestSelects(t *testing.T) {
|
||||||
`,
|
`,
|
||||||
expectedError: `"foo" depends on undefined module "c"`,
|
expectedError: `"foo" depends on undefined module "c"`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Differing types",
|
|
||||||
bp: `
|
|
||||||
my_module_type {
|
|
||||||
name: "foo",
|
|
||||||
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
|
||||||
"a": "a.cpp",
|
|
||||||
"b": true,
|
|
||||||
default: "c.cpp",
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
expectedError: `Android.bp:8:5: Found select statement with differing types "string" and "bool" in its cases`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Select type doesn't match property type",
|
name: "Select type doesn't match property type",
|
||||||
bp: `
|
bp: `
|
||||||
|
@ -136,7 +144,7 @@ func TestSelects(t *testing.T) {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
expectedError: `can't assign bool value to string property "my_string\[0\]"`,
|
expectedError: `can't assign bool value to string property`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "String list non-default",
|
name: "String list non-default",
|
||||||
|
@ -583,6 +591,31 @@ func TestSelects(t *testing.T) {
|
||||||
my_string: proptools.StringPtr("t"),
|
my_string: proptools.StringPtr("t"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Select on boolean soong config variable",
|
||||||
|
bp: `
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
true: "t",
|
||||||
|
false: "f",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vendorVarTypes: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "bool",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("t"),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Select on boolean false",
|
name: "Select on boolean false",
|
||||||
bp: `
|
bp: `
|
||||||
|
@ -799,10 +832,216 @@ func TestSelects(t *testing.T) {
|
||||||
my_string_list: &[]string{"a.cpp", "c.cpp", "foo.cpp"},
|
my_string_list: &[]string{"a.cpp", "c.cpp", "foo.cpp"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Arch variant bool",
|
||||||
|
bp: `
|
||||||
|
my_variable = ["b.cpp"]
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
arch_variant_configurable_bool: false,
|
||||||
|
target: {
|
||||||
|
bionic_arm64: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
arch_variant_configurable_bool: proptools.BoolPtr(false),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Simple string binding",
|
||||||
|
bp: `
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
any @ my_binding: "hello " + my_binding,
|
||||||
|
default: "goodbye",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "world!",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("hello world!"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Any branch with binding not taken",
|
||||||
|
bp: `
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
any @ my_binding: "hello " + my_binding,
|
||||||
|
default: "goodbye",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("goodbye"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Any branch without binding",
|
||||||
|
bp: `
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
any: "hello",
|
||||||
|
default: "goodbye",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "world!",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("hello"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Binding conflicts with file-level variable",
|
||||||
|
bp: `
|
||||||
|
my_binding = "asdf"
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
any @ my_binding: "hello",
|
||||||
|
default: "goodbye",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "world!",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: "variable already set in inherited scope, previous assignment",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Binding in combination with file-level variable",
|
||||||
|
bp: `
|
||||||
|
my_var = " there "
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "my_variable"), {
|
||||||
|
any @ my_binding: "hello" + my_var + my_binding,
|
||||||
|
default: "goodbye",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"my_variable": "world!",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("hello there world!"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Bindings in subdirectory inherits variable",
|
||||||
|
fs: map[string][]byte{
|
||||||
|
"Android.bp": []byte(`
|
||||||
|
my_var = "abcd"
|
||||||
|
`),
|
||||||
|
"directoryB/Android.bp": []byte(`
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
|
||||||
|
any @ my_binding: my_var + my_binding,
|
||||||
|
default: "",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
},
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"variable_a": "e",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string: proptools.StringPtr("abcde"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Cannot modify variable after referenced by select",
|
||||||
|
bp: `
|
||||||
|
my_var = "foo"
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
|
||||||
|
"a": my_var,
|
||||||
|
default: "",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
my_var += "bar"
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"variable_a": "b", // notably not the value that causes my_var to be referenced
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: `modified variable "my_var" with \+= after referencing`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Cannot shadow variable with binding",
|
||||||
|
bp: `
|
||||||
|
my_var = "foo"
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
my_string: select(soong_config_variable("my_namespace", "variable_a"), {
|
||||||
|
any @ my_var: my_var,
|
||||||
|
default: "",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
vendorVars: map[string]map[string]string{
|
||||||
|
"my_namespace": {
|
||||||
|
"variable_a": "a",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedError: `variable already set in inherited scope, previous assignment:`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Basic string list postprocessor",
|
||||||
|
bp: `
|
||||||
|
my_defaults {
|
||||||
|
name: "defaults_a",
|
||||||
|
my_string_list: ["a", "b", "c"],
|
||||||
|
string_list_postprocessor_add_to_elements: "1",
|
||||||
|
}
|
||||||
|
my_defaults {
|
||||||
|
name: "defaults_b",
|
||||||
|
my_string_list: ["d", "e", "f"],
|
||||||
|
string_list_postprocessor_add_to_elements: "2",
|
||||||
|
}
|
||||||
|
my_module_type {
|
||||||
|
name: "foo",
|
||||||
|
defaults: ["defaults_a", "defaults_b"],
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
provider: selectsTestProvider{
|
||||||
|
my_string_list: &[]string{"d2", "e2", "f2", "a1", "b1", "c1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
fs := tc.fs
|
||||||
|
if fs == nil {
|
||||||
|
fs = make(MockFS)
|
||||||
|
}
|
||||||
|
if tc.bp != "" {
|
||||||
|
fs["Android.bp"] = []byte(tc.bp)
|
||||||
|
}
|
||||||
fixtures := GroupFixturePreparers(
|
fixtures := GroupFixturePreparers(
|
||||||
PrepareForTestWithDefaults,
|
PrepareForTestWithDefaults,
|
||||||
PrepareForTestWithArchMutator,
|
PrepareForTestWithArchMutator,
|
||||||
|
@ -813,12 +1052,14 @@ func TestSelects(t *testing.T) {
|
||||||
}),
|
}),
|
||||||
FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
FixtureModifyProductVariables(func(variables FixtureProductVariables) {
|
||||||
variables.VendorVars = tc.vendorVars
|
variables.VendorVars = tc.vendorVars
|
||||||
|
variables.VendorVarTypes = tc.vendorVarTypes
|
||||||
}),
|
}),
|
||||||
|
FixtureMergeMockFs(fs),
|
||||||
)
|
)
|
||||||
if tc.expectedError != "" {
|
if tc.expectedError != "" {
|
||||||
fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
|
fixtures = fixtures.ExtendWithErrorHandler(FixtureExpectsOneErrorPattern(tc.expectedError))
|
||||||
}
|
}
|
||||||
result := fixtures.RunTestWithBp(t, tc.bp)
|
result := fixtures.RunTest(t)
|
||||||
|
|
||||||
if tc.expectedError == "" {
|
if tc.expectedError == "" {
|
||||||
if len(tc.providers) == 0 {
|
if len(tc.providers) == 0 {
|
||||||
|
@ -846,6 +1087,7 @@ type selectsTestProvider struct {
|
||||||
my_string_list *[]string
|
my_string_list *[]string
|
||||||
my_paths *[]string
|
my_paths *[]string
|
||||||
replacing_string_list *[]string
|
replacing_string_list *[]string
|
||||||
|
arch_variant_configurable_bool *bool
|
||||||
my_nonconfigurable_bool *bool
|
my_nonconfigurable_bool *bool
|
||||||
my_nonconfigurable_string *string
|
my_nonconfigurable_string *string
|
||||||
my_nonconfigurable_string_list []string
|
my_nonconfigurable_string_list []string
|
||||||
|
@ -870,6 +1112,7 @@ func (p *selectsTestProvider) String() string {
|
||||||
my_string_list: %s,
|
my_string_list: %s,
|
||||||
my_paths: %s,
|
my_paths: %s,
|
||||||
replacing_string_list %s,
|
replacing_string_list %s,
|
||||||
|
arch_variant_configurable_bool %v
|
||||||
my_nonconfigurable_bool: %v,
|
my_nonconfigurable_bool: %v,
|
||||||
my_nonconfigurable_string: %s,
|
my_nonconfigurable_string: %s,
|
||||||
my_nonconfigurable_string_list: %s,
|
my_nonconfigurable_string_list: %s,
|
||||||
|
@ -879,6 +1122,7 @@ func (p *selectsTestProvider) String() string {
|
||||||
p.my_string_list,
|
p.my_string_list,
|
||||||
p.my_paths,
|
p.my_paths,
|
||||||
p.replacing_string_list,
|
p.replacing_string_list,
|
||||||
|
p.arch_variant_configurable_bool,
|
||||||
p.my_nonconfigurable_bool,
|
p.my_nonconfigurable_bool,
|
||||||
myNonconfigurableStringStr,
|
myNonconfigurableStringStr,
|
||||||
p.my_nonconfigurable_string_list,
|
p.my_nonconfigurable_string_list,
|
||||||
|
@ -893,6 +1137,7 @@ type selectsMockModuleProperties struct {
|
||||||
My_string_list proptools.Configurable[[]string]
|
My_string_list proptools.Configurable[[]string]
|
||||||
My_paths proptools.Configurable[[]string] `android:"path"`
|
My_paths proptools.Configurable[[]string] `android:"path"`
|
||||||
Replacing_string_list proptools.Configurable[[]string] `android:"replace_instead_of_append,arch_variant"`
|
Replacing_string_list proptools.Configurable[[]string] `android:"replace_instead_of_append,arch_variant"`
|
||||||
|
Arch_variant_configurable_bool proptools.Configurable[bool] `android:"replace_instead_of_append,arch_variant"`
|
||||||
My_nonconfigurable_bool *bool
|
My_nonconfigurable_bool *bool
|
||||||
My_nonconfigurable_string *string
|
My_nonconfigurable_string *string
|
||||||
My_nonconfigurable_string_list []string
|
My_nonconfigurable_string_list []string
|
||||||
|
@ -923,6 +1168,7 @@ func (p *selectsMockModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
my_string_list: optionalToPtr(p.properties.My_string_list.Get(ctx)),
|
my_string_list: optionalToPtr(p.properties.My_string_list.Get(ctx)),
|
||||||
my_paths: optionalToPtr(p.properties.My_paths.Get(ctx)),
|
my_paths: optionalToPtr(p.properties.My_paths.Get(ctx)),
|
||||||
replacing_string_list: optionalToPtr(p.properties.Replacing_string_list.Get(ctx)),
|
replacing_string_list: optionalToPtr(p.properties.Replacing_string_list.Get(ctx)),
|
||||||
|
arch_variant_configurable_bool: optionalToPtr(p.properties.Arch_variant_configurable_bool.Get(ctx)),
|
||||||
my_nonconfigurable_bool: p.properties.My_nonconfigurable_bool,
|
my_nonconfigurable_bool: p.properties.My_nonconfigurable_bool,
|
||||||
my_nonconfigurable_string: p.properties.My_nonconfigurable_string,
|
my_nonconfigurable_string: p.properties.My_nonconfigurable_string,
|
||||||
my_nonconfigurable_string_list: p.properties.My_nonconfigurable_string_list,
|
my_nonconfigurable_string_list: p.properties.My_nonconfigurable_string_list,
|
||||||
|
@ -937,9 +1183,15 @@ func newSelectsMockModule() Module {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type selectsMockDefaultsProperties struct {
|
||||||
|
String_list_postprocessor_add_to_elements string
|
||||||
|
}
|
||||||
|
|
||||||
type selectsMockModuleDefaults struct {
|
type selectsMockModuleDefaults struct {
|
||||||
ModuleBase
|
ModuleBase
|
||||||
DefaultsModuleBase
|
DefaultsModuleBase
|
||||||
|
myProperties selectsMockModuleProperties
|
||||||
|
defaultsProperties selectsMockDefaultsProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
|
func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
|
@ -949,10 +1201,22 @@ func newSelectsMockModuleDefaults() Module {
|
||||||
module := &selectsMockModuleDefaults{}
|
module := &selectsMockModuleDefaults{}
|
||||||
|
|
||||||
module.AddProperties(
|
module.AddProperties(
|
||||||
&selectsMockModuleProperties{},
|
&module.myProperties,
|
||||||
|
&module.defaultsProperties,
|
||||||
)
|
)
|
||||||
|
|
||||||
InitDefaultsModule(module)
|
InitDefaultsModule(module)
|
||||||
|
|
||||||
|
AddLoadHook(module, func(lhc LoadHookContext) {
|
||||||
|
if module.defaultsProperties.String_list_postprocessor_add_to_elements != "" {
|
||||||
|
module.myProperties.My_string_list.AddPostProcessor(func(x []string) []string {
|
||||||
|
for i := range x {
|
||||||
|
x[i] = x[i] + module.defaultsProperties.String_list_postprocessor_add_to_elements
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return module
|
return module
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,11 +824,16 @@ func (s *listVariable) printfIntoPropertyRecursive(fieldName []string, propStruc
|
||||||
}
|
}
|
||||||
field.Set(newField)
|
field.Set(newField)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
if proptools.IsConfigurable(field.Type()) {
|
||||||
if err := s.printfIntoPropertyRecursive(fieldName, field, configValues); err != nil {
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
return err
|
return fmt.Errorf("soong_config_variables.%s.%s: list variables are not supported on configurable properties", s.variable, strings.Join(fieldName, "."))
|
||||||
|
} else {
|
||||||
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
|
if err := s.printfIntoPropertyRecursive(fieldName, field, configValues); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fieldName = fieldName[:len(fieldName)-1]
|
||||||
}
|
}
|
||||||
fieldName = fieldName[:len(fieldName)-1]
|
|
||||||
default:
|
default:
|
||||||
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
fieldName = append(fieldName, propStruct.Type().Field(i).Name)
|
||||||
return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)
|
return fmt.Errorf("soong_config_variables.%s.%s: unsupported property type %q", s.variable, strings.Join(fieldName, "."), kind)
|
||||||
|
|
|
@ -224,6 +224,10 @@ func (ctx *TestContext) OtherModuleProviderAdaptor() OtherModuleProviderContext
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctx *TestContext) OtherModulePropertyErrorf(module Module, property string, fmt_ string, args ...interface{}) {
|
||||||
|
panic(fmt.Sprintf(fmt_, args...))
|
||||||
|
}
|
||||||
|
|
||||||
// registeredComponentOrder defines the order in which a sortableComponent type is registered at
|
// registeredComponentOrder defines the order in which a sortableComponent type is registered at
|
||||||
// runtime and provides support for reordering the components registered for a test in the same
|
// runtime and provides support for reordering the components registered for a test in the same
|
||||||
// way.
|
// way.
|
||||||
|
|
|
@ -81,6 +81,16 @@ type variableProperties struct {
|
||||||
Header_libs []string `android:"arch_variant"`
|
Header_libs []string `android:"arch_variant"`
|
||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
|
|
||||||
|
Malloc_low_memory_libc32 struct {
|
||||||
|
Cflags []string `android:"arch_variant"`
|
||||||
|
Shared_libs []string `android:"arch_variant"`
|
||||||
|
Whole_static_libs []string `android:"arch_variant"`
|
||||||
|
Static_libs []string `android:"arch_variant"`
|
||||||
|
Exclude_static_libs []string `android:"arch_variant"`
|
||||||
|
Srcs []string `android:"arch_variant"`
|
||||||
|
Header_libs []string `android:"arch_variant"`
|
||||||
|
} `android:"arch_variant"`
|
||||||
|
|
||||||
Malloc_zero_contents struct {
|
Malloc_zero_contents struct {
|
||||||
Cflags []string `android:"arch_variant"`
|
Cflags []string `android:"arch_variant"`
|
||||||
} `android:"arch_variant"`
|
} `android:"arch_variant"`
|
||||||
|
@ -200,11 +210,12 @@ type ProductVariables struct {
|
||||||
// Suffix to add to generated Makefiles
|
// Suffix to add to generated Makefiles
|
||||||
Make_suffix *string `json:",omitempty"`
|
Make_suffix *string `json:",omitempty"`
|
||||||
|
|
||||||
BuildId *string `json:",omitempty"`
|
BuildId *string `json:",omitempty"`
|
||||||
BuildNumberFile *string `json:",omitempty"`
|
BuildFingerprintFile *string `json:",omitempty"`
|
||||||
BuildHostnameFile *string `json:",omitempty"`
|
BuildNumberFile *string `json:",omitempty"`
|
||||||
BuildThumbprintFile *string `json:",omitempty"`
|
BuildHostnameFile *string `json:",omitempty"`
|
||||||
DisplayBuildNumber *bool `json:",omitempty"`
|
BuildThumbprintFile *string `json:",omitempty"`
|
||||||
|
DisplayBuildNumber *bool `json:",omitempty"`
|
||||||
|
|
||||||
Platform_display_version_name *string `json:",omitempty"`
|
Platform_display_version_name *string `json:",omitempty"`
|
||||||
Platform_version_name *string `json:",omitempty"`
|
Platform_version_name *string `json:",omitempty"`
|
||||||
|
@ -286,6 +297,7 @@ type ProductVariables struct {
|
||||||
Always_use_prebuilt_sdks *bool `json:",omitempty"`
|
Always_use_prebuilt_sdks *bool `json:",omitempty"`
|
||||||
Skip_boot_jars_check *bool `json:",omitempty"`
|
Skip_boot_jars_check *bool `json:",omitempty"`
|
||||||
Malloc_low_memory *bool `json:",omitempty"`
|
Malloc_low_memory *bool `json:",omitempty"`
|
||||||
|
Malloc_low_memory_libc32 *bool `json:",omitempty"`
|
||||||
Malloc_zero_contents *bool `json:",omitempty"`
|
Malloc_zero_contents *bool `json:",omitempty"`
|
||||||
Malloc_pattern_fill_contents *bool `json:",omitempty"`
|
Malloc_pattern_fill_contents *bool `json:",omitempty"`
|
||||||
Safestack *bool `json:",omitempty"`
|
Safestack *bool `json:",omitempty"`
|
||||||
|
@ -363,6 +375,8 @@ type ProductVariables struct {
|
||||||
|
|
||||||
DeviceKernelHeaders []string `json:",omitempty"`
|
DeviceKernelHeaders []string `json:",omitempty"`
|
||||||
|
|
||||||
|
TargetSpecificHeaderPath *string `json:",omitempty"`
|
||||||
|
|
||||||
ExtraVndkVersions []string `json:",omitempty"`
|
ExtraVndkVersions []string `json:",omitempty"`
|
||||||
|
|
||||||
NamespacesToExport []string `json:",omitempty"`
|
NamespacesToExport []string `json:",omitempty"`
|
||||||
|
@ -399,7 +413,8 @@ type ProductVariables struct {
|
||||||
|
|
||||||
PlatformSepolicyCompatVersions []string `json:",omitempty"`
|
PlatformSepolicyCompatVersions []string `json:",omitempty"`
|
||||||
|
|
||||||
VendorVars map[string]map[string]string `json:",omitempty"`
|
VendorVars map[string]map[string]string `json:",omitempty"`
|
||||||
|
VendorVarTypes map[string]map[string]string `json:",omitempty"`
|
||||||
|
|
||||||
Ndk_abis *bool `json:",omitempty"`
|
Ndk_abis *bool `json:",omitempty"`
|
||||||
|
|
||||||
|
@ -459,6 +474,7 @@ type ProductVariables struct {
|
||||||
BuildBrokenIncorrectPartitionImages bool `json:",omitempty"`
|
BuildBrokenIncorrectPartitionImages bool `json:",omitempty"`
|
||||||
BuildBrokenInputDirModules []string `json:",omitempty"`
|
BuildBrokenInputDirModules []string `json:",omitempty"`
|
||||||
BuildBrokenDontCheckSystemSdk bool `json:",omitempty"`
|
BuildBrokenDontCheckSystemSdk bool `json:",omitempty"`
|
||||||
|
BuildBrokenDupSysprop bool `json:",omitempty"`
|
||||||
|
|
||||||
BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
|
BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
|
||||||
|
|
||||||
|
@ -514,6 +530,15 @@ type ProductVariables struct {
|
||||||
BoardUseVbmetaDigestInFingerprint *bool `json:",omitempty"`
|
BoardUseVbmetaDigestInFingerprint *bool `json:",omitempty"`
|
||||||
|
|
||||||
OemProperties []string `json:",omitempty"`
|
OemProperties []string `json:",omitempty"`
|
||||||
|
|
||||||
|
ArtTargetIncludeDebugBuild *bool `json:",omitempty"`
|
||||||
|
|
||||||
|
SystemPropFiles []string `json:",omitempty"`
|
||||||
|
SystemExtPropFiles []string `json:",omitempty"`
|
||||||
|
ProductPropFiles []string `json:",omitempty"`
|
||||||
|
OdmPropFiles []string `json:",omitempty"`
|
||||||
|
|
||||||
|
EnableUffdGc *string `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PartitionQualifiedVariablesType struct {
|
type PartitionQualifiedVariablesType struct {
|
||||||
|
@ -618,6 +643,7 @@ func (v *ProductVariables) SetDefaultConfig() {
|
||||||
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
|
AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
|
||||||
|
|
||||||
Malloc_low_memory: boolPtr(false),
|
Malloc_low_memory: boolPtr(false),
|
||||||
|
Malloc_low_memory_libc32: boolPtr(false),
|
||||||
Malloc_zero_contents: boolPtr(true),
|
Malloc_zero_contents: boolPtr(true),
|
||||||
Malloc_pattern_fill_contents: boolPtr(false),
|
Malloc_pattern_fill_contents: boolPtr(false),
|
||||||
Safestack: boolPtr(false),
|
Safestack: boolPtr(false),
|
||||||
|
|
|
@ -341,9 +341,6 @@ func classifyLocalOrGlobalPath(value bpparser.Expression) (string, bpparser.Expr
|
||||||
|
|
||||||
firstOperand := v.Args[0]
|
firstOperand := v.Args[0]
|
||||||
secondOperand := v.Args[1]
|
secondOperand := v.Args[1]
|
||||||
if firstOperand.Type() != bpparser.StringType {
|
|
||||||
return "global", value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := firstOperand.(*bpparser.Operator); ok {
|
if _, ok := firstOperand.(*bpparser.Operator); ok {
|
||||||
return "global", value, nil
|
return "global", value, nil
|
||||||
|
|
|
@ -493,7 +493,6 @@ func setVariable(file *bpFile, plusequals bool, prefix, name string, value bppar
|
||||||
Name: name,
|
Name: name,
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Value: value,
|
Value: value,
|
||||||
OrigValue: value,
|
|
||||||
EqualsPos: pos,
|
EqualsPos: pos,
|
||||||
Assigner: "+=",
|
Assigner: "+=",
|
||||||
}
|
}
|
||||||
|
@ -506,7 +505,6 @@ func setVariable(file *bpFile, plusequals bool, prefix, name string, value bppar
|
||||||
Name: name,
|
Name: name,
|
||||||
NamePos: pos,
|
NamePos: pos,
|
||||||
Value: value,
|
Value: value,
|
||||||
OrigValue: value,
|
|
||||||
EqualsPos: pos,
|
EqualsPos: pos,
|
||||||
Assigner: "=",
|
Assigner: "=",
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ func makeToStringExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Exp
|
||||||
}
|
}
|
||||||
tmp := &bpparser.Variable{
|
tmp := &bpparser.Variable{
|
||||||
Name: name,
|
Name: name,
|
||||||
Value: &bpparser.String{},
|
Type_: bpparser.StringType,
|
||||||
}
|
}
|
||||||
|
|
||||||
if tmp.Name == "TOP" {
|
if tmp.Name == "TOP" {
|
||||||
|
@ -150,7 +150,7 @@ func makeToListExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expre
|
||||||
}
|
}
|
||||||
listOfListValues = append(listOfListValues, &bpparser.Variable{
|
listOfListValues = append(listOfListValues, &bpparser.Variable{
|
||||||
Name: name,
|
Name: name,
|
||||||
Value: &bpparser.List{},
|
Type_: bpparser.ListType,
|
||||||
})
|
})
|
||||||
listValue = &bpparser.List{}
|
listValue = &bpparser.List{}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ func makeToBoolExpression(ms *mkparser.MakeString, file *bpFile) (bpparser.Expre
|
||||||
}
|
}
|
||||||
return &bpparser.Variable{
|
return &bpparser.Variable{
|
||||||
Name: name,
|
Name: name,
|
||||||
Value: &bpparser.Bool{},
|
Type_: bpparser.BoolType,
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())
|
return nil, fmt.Errorf("non-const bool expression %s", ms.Dump())
|
||||||
|
|
|
@ -218,7 +218,7 @@ func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) {
|
||||||
var required []string
|
var required []string
|
||||||
var targetRequired []string
|
var targetRequired []string
|
||||||
var hostRequired []string
|
var hostRequired []string
|
||||||
required = append(required, a.RequiredModuleNames()...)
|
required = append(required, a.required...)
|
||||||
targetRequired = append(targetRequired, a.TargetRequiredModuleNames()...)
|
targetRequired = append(targetRequired, a.TargetRequiredModuleNames()...)
|
||||||
hostRequired = append(hostRequired, a.HostRequiredModuleNames()...)
|
hostRequired = append(hostRequired, a.HostRequiredModuleNames()...)
|
||||||
for _, fi := range a.filesInfo {
|
for _, fi := range a.filesInfo {
|
||||||
|
|
72
apex/apex.go
72
apex/apex.go
|
@ -86,7 +86,7 @@ type apexBundleProperties struct {
|
||||||
|
|
||||||
// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
|
// AndroidManifest.xml file used for the zip container of this APEX bundle. If unspecified,
|
||||||
// a default one is automatically generated.
|
// a default one is automatically generated.
|
||||||
AndroidManifest *string `android:"path"`
|
AndroidManifest proptools.Configurable[string] `android:"path,replace_instead_of_append"`
|
||||||
|
|
||||||
// Determines the file contexts file for setting the security contexts to files in this APEX
|
// Determines the file contexts file for setting the security contexts to files in this APEX
|
||||||
// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
|
// bundle. For platform APEXes, this should points to a file under /system/sepolicy Default:
|
||||||
|
@ -104,7 +104,7 @@ type apexBundleProperties struct {
|
||||||
// path_or_glob is a path or glob pattern for a file or set of files,
|
// path_or_glob is a path or glob pattern for a file or set of files,
|
||||||
// uid/gid are numerial values of user ID and group ID, mode is octal value
|
// uid/gid are numerial values of user ID and group ID, mode is octal value
|
||||||
// for the file mode, and cap is hexadecimal value for the capability.
|
// for the file mode, and cap is hexadecimal value for the capability.
|
||||||
Canned_fs_config *string `android:"path"`
|
Canned_fs_config proptools.Configurable[string] `android:"path,replace_instead_of_append"`
|
||||||
|
|
||||||
ApexNativeDependencies
|
ApexNativeDependencies
|
||||||
|
|
||||||
|
@ -117,7 +117,8 @@ type apexBundleProperties struct {
|
||||||
Bootclasspath_fragments []string
|
Bootclasspath_fragments []string
|
||||||
|
|
||||||
// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
|
// List of systemserverclasspath fragments that are embedded inside this APEX bundle.
|
||||||
Systemserverclasspath_fragments []string
|
Systemserverclasspath_fragments proptools.Configurable[[]string]
|
||||||
|
ResolvedSystemserverclasspathFragments []string `blueprint:"mutated"`
|
||||||
|
|
||||||
// List of java libraries that are embedded inside this APEX bundle.
|
// List of java libraries that are embedded inside this APEX bundle.
|
||||||
Java_libs []string
|
Java_libs []string
|
||||||
|
@ -222,7 +223,8 @@ type ApexNativeDependencies struct {
|
||||||
Rust_dyn_libs []string
|
Rust_dyn_libs []string
|
||||||
|
|
||||||
// List of native executables that are embedded inside this APEX.
|
// List of native executables that are embedded inside this APEX.
|
||||||
Binaries []string
|
Binaries proptools.Configurable[[]string]
|
||||||
|
ResolvedBinaries []string `blueprint:"mutated"`
|
||||||
|
|
||||||
// List of native tests that are embedded inside this APEX.
|
// List of native tests that are embedded inside this APEX.
|
||||||
Tests []string
|
Tests []string
|
||||||
|
@ -231,7 +233,8 @@ type ApexNativeDependencies struct {
|
||||||
Filesystems []string
|
Filesystems []string
|
||||||
|
|
||||||
// List of prebuilt_etcs that are embedded inside this APEX bundle.
|
// List of prebuilt_etcs that are embedded inside this APEX bundle.
|
||||||
Prebuilts []string
|
Prebuilts proptools.Configurable[[]string]
|
||||||
|
ResolvedPrebuilts []string `blueprint:"mutated"`
|
||||||
|
|
||||||
// List of native libraries to exclude from this APEX.
|
// List of native libraries to exclude from this APEX.
|
||||||
Exclude_native_shared_libs []string
|
Exclude_native_shared_libs []string
|
||||||
|
@ -256,14 +259,14 @@ type ApexNativeDependencies struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge combines another ApexNativeDependencies into this one
|
// Merge combines another ApexNativeDependencies into this one
|
||||||
func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
|
func (a *ApexNativeDependencies) Merge(ctx android.BaseMutatorContext, b ApexNativeDependencies) {
|
||||||
a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
|
a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
|
||||||
a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
|
a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
|
||||||
a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
|
a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
|
||||||
a.Binaries = append(a.Binaries, b.Binaries...)
|
a.ResolvedBinaries = append(a.ResolvedBinaries, b.Binaries.GetOrDefault(ctx, nil)...)
|
||||||
a.Tests = append(a.Tests, b.Tests...)
|
a.Tests = append(a.Tests, b.Tests...)
|
||||||
a.Filesystems = append(a.Filesystems, b.Filesystems...)
|
a.Filesystems = append(a.Filesystems, b.Filesystems...)
|
||||||
a.Prebuilts = append(a.Prebuilts, b.Prebuilts...)
|
a.ResolvedPrebuilts = append(a.ResolvedPrebuilts, b.Prebuilts.GetOrDefault(ctx, nil)...)
|
||||||
|
|
||||||
a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
|
a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
|
||||||
a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
|
a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
|
||||||
|
@ -339,10 +342,10 @@ type apexArchBundleProperties struct {
|
||||||
// base apex.
|
// base apex.
|
||||||
type overridableProperties struct {
|
type overridableProperties struct {
|
||||||
// List of APKs that are embedded inside this APEX.
|
// List of APKs that are embedded inside this APEX.
|
||||||
Apps []string
|
Apps proptools.Configurable[[]string]
|
||||||
|
|
||||||
// List of prebuilt files that are embedded inside this APEX bundle.
|
// List of prebuilt files that are embedded inside this APEX bundle.
|
||||||
Prebuilts []string
|
Prebuilts proptools.Configurable[[]string]
|
||||||
|
|
||||||
// List of BPF programs inside this APEX bundle.
|
// List of BPF programs inside this APEX bundle.
|
||||||
Bpfs []string
|
Bpfs []string
|
||||||
|
@ -489,6 +492,9 @@ type apexBundle struct {
|
||||||
javaApisUsedByModuleFile android.ModuleOutPath
|
javaApisUsedByModuleFile android.ModuleOutPath
|
||||||
|
|
||||||
aconfigFiles []android.Path
|
aconfigFiles []android.Path
|
||||||
|
|
||||||
|
// Required modules, filled out during GenerateAndroidBuildActions and used in AndroidMk
|
||||||
|
required []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// apexFileClass represents a type of file that can be included in APEX.
|
// apexFileClass represents a type of file that can be included in APEX.
|
||||||
|
@ -567,7 +573,7 @@ func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidM
|
||||||
if module != nil {
|
if module != nil {
|
||||||
ret.moduleDir = ctx.OtherModuleDir(module)
|
ret.moduleDir = ctx.OtherModuleDir(module)
|
||||||
ret.partition = module.PartitionTag(ctx.DeviceConfig())
|
ret.partition = module.PartitionTag(ctx.DeviceConfig())
|
||||||
ret.requiredModuleNames = module.RequiredModuleNames()
|
ret.requiredModuleNames = module.RequiredModuleNames(ctx)
|
||||||
ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
|
ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
|
||||||
ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
|
ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
|
||||||
ret.multilib = module.Target().Arch.ArchType.Multilib
|
ret.multilib = module.Target().Arch.ArchType.Multilib
|
||||||
|
@ -714,7 +720,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
|
||||||
// this module. This is required since arch variant of an APEX bundle is 'common' but it is
|
// this module. This is required since arch variant of an APEX bundle is 'common' but it is
|
||||||
// 'arm' or 'arm64' for native shared libs.
|
// 'arm' or 'arm64' for native shared libs.
|
||||||
ctx.AddFarVariationDependencies(binVariations, executableTag,
|
ctx.AddFarVariationDependencies(binVariations, executableTag,
|
||||||
android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
|
android.RemoveListFromList(nativeModules.ResolvedBinaries, nativeModules.Exclude_binaries)...)
|
||||||
ctx.AddFarVariationDependencies(binVariations, testTag,
|
ctx.AddFarVariationDependencies(binVariations, testTag,
|
||||||
android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
|
android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
|
||||||
ctx.AddFarVariationDependencies(libVariations, jniLibTag,
|
ctx.AddFarVariationDependencies(libVariations, jniLibTag,
|
||||||
|
@ -726,7 +732,7 @@ func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, nativeM
|
||||||
ctx.AddFarVariationDependencies(target.Variations(), fsTag,
|
ctx.AddFarVariationDependencies(target.Variations(), fsTag,
|
||||||
android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
|
android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
|
||||||
ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
|
ctx.AddFarVariationDependencies(target.Variations(), prebuiltTag,
|
||||||
android.RemoveListFromList(nativeModules.Prebuilts, nativeModules.Exclude_prebuilts)...)
|
android.RemoveListFromList(nativeModules.ResolvedPrebuilts, nativeModules.Exclude_prebuilts)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
|
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
|
||||||
|
@ -781,20 +787,19 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
|
|
||||||
// Add native modules targeting both ABIs. When multilib.* is omitted for
|
// Add native modules targeting both ABIs. When multilib.* is omitted for
|
||||||
// native_shared_libs/jni_libs/tests, it implies multilib.both
|
// native_shared_libs/jni_libs/tests, it implies multilib.both
|
||||||
deps.Merge(a.properties.Multilib.Both)
|
deps.Merge(ctx, a.properties.Multilib.Both)
|
||||||
deps.Merge(ApexNativeDependencies{
|
deps.Merge(ctx, ApexNativeDependencies{
|
||||||
Native_shared_libs: a.properties.Native_shared_libs,
|
Native_shared_libs: a.properties.Native_shared_libs,
|
||||||
Tests: a.properties.Tests,
|
Tests: a.properties.Tests,
|
||||||
Jni_libs: a.properties.Jni_libs,
|
Jni_libs: a.properties.Jni_libs,
|
||||||
Binaries: nil,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Add native modules targeting the first ABI When multilib.* is omitted for
|
// Add native modules targeting the first ABI When multilib.* is omitted for
|
||||||
// binaries, it implies multilib.first
|
// binaries, it implies multilib.first
|
||||||
isPrimaryAbi := i == 0
|
isPrimaryAbi := i == 0
|
||||||
if isPrimaryAbi {
|
if isPrimaryAbi {
|
||||||
deps.Merge(a.properties.Multilib.First)
|
deps.Merge(ctx, a.properties.Multilib.First)
|
||||||
deps.Merge(ApexNativeDependencies{
|
deps.Merge(ctx, ApexNativeDependencies{
|
||||||
Native_shared_libs: nil,
|
Native_shared_libs: nil,
|
||||||
Tests: nil,
|
Tests: nil,
|
||||||
Jni_libs: nil,
|
Jni_libs: nil,
|
||||||
|
@ -805,27 +810,27 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
// Add native modules targeting either 32-bit or 64-bit ABI
|
// Add native modules targeting either 32-bit or 64-bit ABI
|
||||||
switch target.Arch.ArchType.Multilib {
|
switch target.Arch.ArchType.Multilib {
|
||||||
case "lib32":
|
case "lib32":
|
||||||
deps.Merge(a.properties.Multilib.Lib32)
|
deps.Merge(ctx, a.properties.Multilib.Lib32)
|
||||||
deps.Merge(a.properties.Multilib.Prefer32)
|
deps.Merge(ctx, a.properties.Multilib.Prefer32)
|
||||||
case "lib64":
|
case "lib64":
|
||||||
deps.Merge(a.properties.Multilib.Lib64)
|
deps.Merge(ctx, a.properties.Multilib.Lib64)
|
||||||
if !has32BitTarget {
|
if !has32BitTarget {
|
||||||
deps.Merge(a.properties.Multilib.Prefer32)
|
deps.Merge(ctx, a.properties.Multilib.Prefer32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add native modules targeting a specific arch variant
|
// Add native modules targeting a specific arch variant
|
||||||
switch target.Arch.ArchType {
|
switch target.Arch.ArchType {
|
||||||
case android.Arm:
|
case android.Arm:
|
||||||
deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
|
deps.Merge(ctx, a.archProperties.Arch.Arm.ApexNativeDependencies)
|
||||||
case android.Arm64:
|
case android.Arm64:
|
||||||
deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
|
deps.Merge(ctx, a.archProperties.Arch.Arm64.ApexNativeDependencies)
|
||||||
case android.Riscv64:
|
case android.Riscv64:
|
||||||
deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
|
deps.Merge(ctx, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
|
||||||
case android.X86:
|
case android.X86:
|
||||||
deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
|
deps.Merge(ctx, a.archProperties.Arch.X86.ApexNativeDependencies)
|
||||||
case android.X86_64:
|
case android.X86_64:
|
||||||
deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
|
deps.Merge(ctx, a.archProperties.Arch.X86_64.ApexNativeDependencies)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
|
panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
|
||||||
}
|
}
|
||||||
|
@ -839,11 +844,13 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.properties.ResolvedSystemserverclasspathFragments = a.properties.Systemserverclasspath_fragments.GetOrDefault(ctx, nil)
|
||||||
|
|
||||||
// Common-arch dependencies come next
|
// Common-arch dependencies come next
|
||||||
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
||||||
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
|
ctx.AddFarVariationDependencies(commonVariation, rroTag, a.properties.Rros...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
|
ctx.AddFarVariationDependencies(commonVariation, bcpfTag, a.properties.Bootclasspath_fragments...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.Systemserverclasspath_fragments...)
|
ctx.AddFarVariationDependencies(commonVariation, sscpfTag, a.properties.ResolvedSystemserverclasspathFragments...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
|
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
|
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
|
ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...)
|
||||||
|
@ -856,9 +863,9 @@ func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato
|
||||||
}
|
}
|
||||||
|
|
||||||
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
||||||
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps...)
|
ctx.AddFarVariationDependencies(commonVariation, androidAppTag, a.overridableProperties.Apps.GetOrDefault(ctx, nil)...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
|
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.overridableProperties.Bpfs...)
|
||||||
if prebuilts := a.overridableProperties.Prebuilts; len(prebuilts) > 0 {
|
if prebuilts := a.overridableProperties.Prebuilts.GetOrDefault(ctx, nil); len(prebuilts) > 0 {
|
||||||
// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
|
// For prebuilt_etc, use the first variant (64 on 64/32bit device, 32 on 32bit device)
|
||||||
// regardless of the TARGET_PREFER_* setting. See b/144532908
|
// regardless of the TARGET_PREFER_* setting. See b/144532908
|
||||||
arches := ctx.DeviceConfig().Arches()
|
arches := ctx.DeviceConfig().Arches()
|
||||||
|
@ -1530,7 +1537,6 @@ func (a *apexBundle) AddSanitizerDependencies(ctx android.BottomUpMutatorContext
|
||||||
Native_shared_libs: []string{"libclang_rt.hwasan"},
|
Native_shared_libs: []string{"libclang_rt.hwasan"},
|
||||||
Tests: nil,
|
Tests: nil,
|
||||||
Jni_libs: nil,
|
Jni_libs: nil,
|
||||||
Binaries: nil,
|
|
||||||
}, target, imageVariation)
|
}, target, imageVariation)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -2426,6 +2432,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
a.provideApexExportsInfo(ctx)
|
a.provideApexExportsInfo(ctx)
|
||||||
|
|
||||||
a.providePrebuiltInfo(ctx)
|
a.providePrebuiltInfo(ctx)
|
||||||
|
|
||||||
|
a.required = a.RequiredModuleNames(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
|
// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file
|
||||||
|
@ -2851,7 +2859,7 @@ func isStaticExecutableAllowed(apex string, exec string) bool {
|
||||||
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
|
func (a *apexBundle) IDEInfo(dpInfo *android.IdeInfo) {
|
||||||
dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
|
dpInfo.Deps = append(dpInfo.Deps, a.properties.Java_libs...)
|
||||||
dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
|
dpInfo.Deps = append(dpInfo.Deps, a.properties.Bootclasspath_fragments...)
|
||||||
dpInfo.Deps = append(dpInfo.Deps, a.properties.Systemserverclasspath_fragments...)
|
dpInfo.Deps = append(dpInfo.Deps, a.properties.ResolvedSystemserverclasspathFragments...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -704,8 +704,9 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
|
||||||
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
|
optFlags = append(optFlags, "--override_apk_package_name "+manifestPackageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.properties.AndroidManifest != nil {
|
androidManifest := a.properties.AndroidManifest.GetOrDefault(ctx, "")
|
||||||
androidManifestFile := android.PathForModuleSrc(ctx, proptools.String(a.properties.AndroidManifest))
|
if androidManifest != "" {
|
||||||
|
androidManifestFile := android.PathForModuleSrc(ctx, androidManifest)
|
||||||
|
|
||||||
if a.testApex {
|
if a.testApex {
|
||||||
androidManifestFile = markManifestTestOnly(ctx, androidManifestFile)
|
androidManifestFile = markManifestTestOnly(ctx, androidManifestFile)
|
||||||
|
@ -1195,8 +1196,9 @@ func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadO
|
||||||
}
|
}
|
||||||
// Custom fs_config is "appended" to the last so that entries from the file are preferred
|
// Custom fs_config is "appended" to the last so that entries from the file are preferred
|
||||||
// over default ones set above.
|
// over default ones set above.
|
||||||
if a.properties.Canned_fs_config != nil {
|
customFsConfig := a.properties.Canned_fs_config.GetOrDefault(ctx, "")
|
||||||
cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config))
|
if customFsConfig != "" {
|
||||||
|
cmd.Text("cat").Input(android.PathForModuleSrc(ctx, customFsConfig))
|
||||||
}
|
}
|
||||||
cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
|
cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
|
||||||
builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))
|
builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))
|
||||||
|
|
|
@ -286,7 +286,7 @@ func (f *Fixer) reparse() ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parse(name string, r io.Reader) (*parser.File, error) {
|
func parse(name string, r io.Reader) (*parser.File, error) {
|
||||||
tree, errs := parser.Parse(name, r, parser.NewScope(nil))
|
tree, errs := parser.Parse(name, r)
|
||||||
if errs != nil {
|
if errs != nil {
|
||||||
s := "parse error: "
|
s := "parse error: "
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
|
|
|
@ -46,7 +46,7 @@ func buildTree(local_include_dirs []string, export_include_dirs []string) (file
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
printListOfStrings(local_include_dirs), printListOfStrings(export_include_dirs))
|
printListOfStrings(local_include_dirs), printListOfStrings(export_include_dirs))
|
||||||
tree, errs := parser.Parse("", strings.NewReader(input), parser.NewScope(nil))
|
tree, errs := parser.Parse("", strings.NewReader(input))
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
errs = append([]error{fmt.Errorf("failed to parse:\n%s", input)}, errs...)
|
errs = append([]error{fmt.Errorf("failed to parse:\n%s", input)}, errs...)
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ func preProcessIn(in string) (fixer *Fixer, err error) {
|
||||||
return fixer, err
|
return fixer, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tree, errs := parser.Parse("<testcase>", bytes.NewBufferString(in), parser.NewScope(nil))
|
tree, errs := parser.Parse("<testcase>", bytes.NewBufferString(in))
|
||||||
if errs != nil {
|
if errs != nil {
|
||||||
return fixer, err
|
return fixer, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ func processFile(filename string, in io.Reader, out io.Writer, fixRequest bpfix.
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r := bytes.NewBuffer(append([]byte(nil), src...))
|
r := bytes.NewBuffer(append([]byte(nil), src...))
|
||||||
file, errs := parser.Parse(filename, r, parser.NewScope(nil))
|
file, errs := parser.Parse(filename, r)
|
||||||
if len(errs) > 0 {
|
if len(errs) > 0 {
|
||||||
for _, err := range errs {
|
for _, err := range errs {
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
|
4
cc/cc.go
4
cc/cc.go
|
@ -981,8 +981,8 @@ func (c *Module) HiddenFromMake() bool {
|
||||||
return c.Properties.HideFromMake
|
return c.Properties.HideFromMake
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) RequiredModuleNames() []string {
|
func (c *Module) RequiredModuleNames(ctx android.ConfigAndErrorContext) []string {
|
||||||
required := android.CopyOf(c.ModuleBase.RequiredModuleNames())
|
required := android.CopyOf(c.ModuleBase.RequiredModuleNames(ctx))
|
||||||
if c.ImageVariation().Variation == android.CoreVariation {
|
if c.ImageVariation().Variation == android.CoreVariation {
|
||||||
required = append(required, c.Properties.Target.Platform.Required...)
|
required = append(required, c.Properties.Target.Platform.Required...)
|
||||||
required = removeListFromList(required, c.Properties.Target.Platform.Exclude_required)
|
required = removeListFromList(required, c.Properties.Target.Platform.Exclude_required)
|
||||||
|
|
|
@ -53,7 +53,7 @@ type BaseCompilerProperties struct {
|
||||||
Cflags proptools.Configurable[[]string] `android:"arch_variant"`
|
Cflags proptools.Configurable[[]string] `android:"arch_variant"`
|
||||||
|
|
||||||
// list of module-specific flags that will be used for C++ compiles
|
// list of module-specific flags that will be used for C++ compiles
|
||||||
Cppflags []string `android:"arch_variant"`
|
Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
|
||||||
|
|
||||||
// list of module-specific flags that will be used for C compiles
|
// list of module-specific flags that will be used for C compiles
|
||||||
Conlyflags []string `android:"arch_variant"`
|
Conlyflags []string `android:"arch_variant"`
|
||||||
|
@ -363,12 +363,23 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
|
||||||
tc := ctx.toolchain()
|
tc := ctx.toolchain()
|
||||||
modulePath := ctx.ModuleDir()
|
modulePath := ctx.ModuleDir()
|
||||||
|
|
||||||
|
additionalIncludeDirs := ctx.DeviceConfig().TargetSpecificHeaderPath()
|
||||||
|
if len(additionalIncludeDirs) > 0 {
|
||||||
|
// devices can have multiple paths in TARGET_SPECIFIC_HEADER_PATH
|
||||||
|
// add -I in front of all of them
|
||||||
|
if (strings.Contains(additionalIncludeDirs, " ")) {
|
||||||
|
additionalIncludeDirs = strings.ReplaceAll(additionalIncludeDirs, " ", " -I")
|
||||||
|
}
|
||||||
|
flags.Local.CommonFlags = append(flags.Local.CommonFlags, "-I" + additionalIncludeDirs)
|
||||||
|
}
|
||||||
|
|
||||||
compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
|
compiler.srcsBeforeGen = android.PathsForModuleSrcExcludes(ctx, compiler.Properties.Srcs, compiler.Properties.Exclude_srcs)
|
||||||
compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
|
compiler.srcsBeforeGen = append(compiler.srcsBeforeGen, deps.GeneratedSources...)
|
||||||
|
|
||||||
cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
|
cflags := compiler.Properties.Cflags.GetOrDefault(ctx, nil)
|
||||||
|
cppflags := compiler.Properties.Cppflags.GetOrDefault(ctx, nil)
|
||||||
CheckBadCompilerFlags(ctx, "cflags", cflags)
|
CheckBadCompilerFlags(ctx, "cflags", cflags)
|
||||||
CheckBadCompilerFlags(ctx, "cppflags", compiler.Properties.Cppflags)
|
CheckBadCompilerFlags(ctx, "cppflags", cppflags)
|
||||||
CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
|
CheckBadCompilerFlags(ctx, "conlyflags", compiler.Properties.Conlyflags)
|
||||||
CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
|
CheckBadCompilerFlags(ctx, "asflags", compiler.Properties.Asflags)
|
||||||
CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
|
CheckBadCompilerFlags(ctx, "vendor.cflags", compiler.Properties.Target.Vendor.Cflags)
|
||||||
|
@ -381,7 +392,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
|
||||||
esc := proptools.NinjaAndShellEscapeList
|
esc := proptools.NinjaAndShellEscapeList
|
||||||
|
|
||||||
flags.Local.CFlags = append(flags.Local.CFlags, esc(cflags)...)
|
flags.Local.CFlags = append(flags.Local.CFlags, esc(cflags)...)
|
||||||
flags.Local.CppFlags = append(flags.Local.CppFlags, esc(compiler.Properties.Cppflags)...)
|
flags.Local.CppFlags = append(flags.Local.CppFlags, esc(cppflags)...)
|
||||||
flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
|
flags.Local.ConlyFlags = append(flags.Local.ConlyFlags, esc(compiler.Properties.Conlyflags)...)
|
||||||
flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
|
flags.Local.AsFlags = append(flags.Local.AsFlags, esc(compiler.Properties.Asflags)...)
|
||||||
flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
|
flags.Local.YasmFlags = append(flags.Local.YasmFlags, esc(compiler.Properties.Asflags)...)
|
||||||
|
@ -813,7 +824,7 @@ type RustBindgenClangProperties struct {
|
||||||
|
|
||||||
// list of c++ specific clang flags required to correctly interpret the headers.
|
// list of c++ specific clang flags required to correctly interpret the headers.
|
||||||
// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
|
// This is provided primarily to make sure cppflags defined in cc_defaults are pulled in.
|
||||||
Cppflags []string `android:"arch_variant"`
|
Cppflags proptools.Configurable[[]string] `android:"arch_variant"`
|
||||||
|
|
||||||
// C standard version to use. Can be a specific version (such as "gnu11"),
|
// C standard version to use. Can be a specific version (such as "gnu11"),
|
||||||
// "experimental" (which will use draft versions like C1x when available),
|
// "experimental" (which will use draft versions like C1x when available),
|
||||||
|
|
|
@ -59,7 +59,7 @@ type vbmetaProperties struct {
|
||||||
|
|
||||||
// List of filesystem modules that this vbmeta has descriptors for. The filesystem modules
|
// List of filesystem modules that this vbmeta has descriptors for. The filesystem modules
|
||||||
// have to be signed (use_avb: true).
|
// have to be signed (use_avb: true).
|
||||||
Partitions []string
|
Partitions proptools.Configurable[[]string]
|
||||||
|
|
||||||
// List of chained partitions that this vbmeta deletages the verification.
|
// List of chained partitions that this vbmeta deletages the verification.
|
||||||
Chained_partitions []chainedPartitionProperties
|
Chained_partitions []chainedPartitionProperties
|
||||||
|
@ -110,7 +110,7 @@ type vbmetaDep struct {
|
||||||
var vbmetaPartitionDep = vbmetaDep{kind: "partition"}
|
var vbmetaPartitionDep = vbmetaDep{kind: "partition"}
|
||||||
|
|
||||||
func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
|
func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions...)
|
ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions.GetOrDefault(ctx, nil)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *vbmeta) installFileName() string {
|
func (v *vbmeta) installFileName() string {
|
||||||
|
|
|
@ -139,7 +139,8 @@ type generatorProperties struct {
|
||||||
Export_include_dirs []string
|
Export_include_dirs []string
|
||||||
|
|
||||||
// list of input files
|
// list of input files
|
||||||
Srcs []string `android:"path,arch_variant"`
|
Srcs proptools.Configurable[[]string] `android:"path,arch_variant"`
|
||||||
|
ResolvedSrcs []string `blueprint:"mutated"`
|
||||||
|
|
||||||
// input files to exclude
|
// input files to exclude
|
||||||
Exclude_srcs []string `android:"path,arch_variant"`
|
Exclude_srcs []string `android:"path,arch_variant"`
|
||||||
|
@ -396,7 +397,8 @@ func (g *Module) generateCommonBuildActions(ctx android.ModuleContext) {
|
||||||
}
|
}
|
||||||
return srcFiles
|
return srcFiles
|
||||||
}
|
}
|
||||||
srcFiles := addLabelsForInputs("srcs", g.properties.Srcs, g.properties.Exclude_srcs)
|
g.properties.ResolvedSrcs = g.properties.Srcs.GetOrDefault(ctx, nil)
|
||||||
|
srcFiles := addLabelsForInputs("srcs", g.properties.ResolvedSrcs, g.properties.Exclude_srcs)
|
||||||
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
|
android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcFiles.Strings()})
|
||||||
|
|
||||||
var copyFrom android.Paths
|
var copyFrom android.Paths
|
||||||
|
@ -590,7 +592,7 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
// Collect information for opening IDE project files in java/jdeps.go.
|
// Collect information for opening IDE project files in java/jdeps.go.
|
||||||
func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
|
func (g *Module) IDEInfo(dpInfo *android.IdeInfo) {
|
||||||
dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
|
dpInfo.Srcs = append(dpInfo.Srcs, g.Srcs().Strings()...)
|
||||||
for _, src := range g.properties.Srcs {
|
for _, src := range g.properties.ResolvedSrcs {
|
||||||
if strings.HasPrefix(src, ":") {
|
if strings.HasPrefix(src, ":") {
|
||||||
src = strings.Trim(src, ":")
|
src = strings.Trim(src, ":")
|
||||||
dpInfo.Deps = append(dpInfo.Deps, src)
|
dpInfo.Deps = append(dpInfo.Deps, src)
|
||||||
|
|
|
@ -694,7 +694,7 @@ func TestGenruleDefaults(t *testing.T) {
|
||||||
android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
|
android.AssertStringEquals(t, "cmd", expectedCmd, gen.rawCommands[0])
|
||||||
|
|
||||||
expectedSrcs := []string{"in1"}
|
expectedSrcs := []string{"in1"}
|
||||||
android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.Srcs)
|
android.AssertDeepEquals(t, "srcs", expectedSrcs, gen.properties.ResolvedSrcs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenruleAllowMissingDependencies(t *testing.T) {
|
func TestGenruleAllowMissingDependencies(t *testing.T) {
|
||||||
|
|
|
@ -1501,7 +1501,7 @@ func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
InstalledFiles: j.data,
|
InstalledFiles: j.data,
|
||||||
OutputFile: j.outputFile,
|
OutputFile: j.outputFile,
|
||||||
TestConfig: j.testConfig,
|
TestConfig: j.testConfig,
|
||||||
RequiredModuleNames: j.RequiredModuleNames(),
|
RequiredModuleNames: j.RequiredModuleNames(ctx),
|
||||||
TestSuites: j.testProperties.Test_suites,
|
TestSuites: j.testProperties.Test_suites,
|
||||||
IsHost: true,
|
IsHost: true,
|
||||||
LocalSdkVersion: j.sdkVersion.String(),
|
LocalSdkVersion: j.sdkVersion.String(),
|
||||||
|
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -49,7 +51,7 @@ func PhonyFactory() android.Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *phony) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (p *phony) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
p.requiredModuleNames = ctx.RequiredModuleNames()
|
p.requiredModuleNames = ctx.RequiredModuleNames(ctx)
|
||||||
p.hostRequiredModuleNames = ctx.HostRequiredModuleNames()
|
p.hostRequiredModuleNames = ctx.HostRequiredModuleNames()
|
||||||
p.targetRequiredModuleNames = ctx.TargetRequiredModuleNames()
|
p.targetRequiredModuleNames = ctx.TargetRequiredModuleNames()
|
||||||
}
|
}
|
||||||
|
@ -88,14 +90,15 @@ type PhonyRule struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
android.DefaultableModuleBase
|
android.DefaultableModuleBase
|
||||||
|
|
||||||
properties PhonyProperties
|
phonyDepsModuleNames []string
|
||||||
|
properties PhonyProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhonyProperties struct {
|
type PhonyProperties struct {
|
||||||
// The Phony_deps is the set of all dependencies for this target,
|
// The Phony_deps is the set of all dependencies for this target,
|
||||||
// and it can function similarly to .PHONY in a makefile.
|
// and it can function similarly to .PHONY in a makefile.
|
||||||
// Additionally, dependencies within it can even include genrule.
|
// Additionally, dependencies within it can even include genrule.
|
||||||
Phony_deps []string
|
Phony_deps proptools.Configurable[[]string]
|
||||||
}
|
}
|
||||||
|
|
||||||
// The phony_rule provides functionality similar to the .PHONY in a makefile.
|
// The phony_rule provides functionality similar to the .PHONY in a makefile.
|
||||||
|
@ -109,13 +112,14 @@ func PhonyRuleFactory() android.Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PhonyRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
func (p *PhonyRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
|
p.phonyDepsModuleNames = p.properties.Phony_deps.GetOrDefault(ctx, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PhonyRule) AndroidMk() android.AndroidMkData {
|
func (p *PhonyRule) AndroidMk() android.AndroidMkData {
|
||||||
return android.AndroidMkData{
|
return android.AndroidMkData{
|
||||||
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
|
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
|
||||||
if len(p.properties.Phony_deps) > 0 {
|
if len(p.phonyDepsModuleNames) > 0 {
|
||||||
depModulesStr := strings.Join(p.properties.Phony_deps, " ")
|
depModulesStr := strings.Join(p.phonyDepsModuleNames, " ")
|
||||||
fmt.Fprintln(w, ".PHONY:", name)
|
fmt.Fprintln(w, ".PHONY:", name)
|
||||||
fmt.Fprintln(w, name, ":", depModulesStr)
|
fmt.Fprintln(w, name, ":", depModulesStr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,7 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr
|
||||||
if isCpp {
|
if isCpp {
|
||||||
cflags = append(cflags, "-x c++")
|
cflags = append(cflags, "-x c++")
|
||||||
// Add any C++ only flags.
|
// Add any C++ only flags.
|
||||||
cflags = append(cflags, esc(b.ClangProperties.Cppflags)...)
|
cflags = append(cflags, esc(b.ClangProperties.Cppflags.GetOrDefault(ctx, nil))...)
|
||||||
} else {
|
} else {
|
||||||
cflags = append(cflags, "-x c")
|
cflags = append(cflags, "-x c")
|
||||||
}
|
}
|
||||||
|
|
|
@ -292,9 +292,17 @@ python_binary_host {
|
||||||
}
|
}
|
||||||
|
|
||||||
python_binary_host {
|
python_binary_host {
|
||||||
name: "buildinfo",
|
name: "merge_json",
|
||||||
main: "buildinfo.py",
|
main: "merge_json.py",
|
||||||
srcs: ["buildinfo.py"],
|
srcs: [
|
||||||
|
"merge_json.py",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
python_binary_host {
|
||||||
|
name: "gen_build_prop",
|
||||||
|
main: "gen_build_prop.py",
|
||||||
|
srcs: ["gen_build_prop.py"],
|
||||||
}
|
}
|
||||||
|
|
||||||
python_binary_host {
|
python_binary_host {
|
||||||
|
|
|
@ -1,156 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
#
|
|
||||||
# Copyright (C) 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.
|
|
||||||
#
|
|
||||||
"""A tool for generating buildinfo.prop"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import contextlib
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
"""Parse commandline arguments."""
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('--use-vbmeta-digest-in-fingerprint', action='store_true')
|
|
||||||
parser.add_argument('--build-flavor', required=True)
|
|
||||||
parser.add_argument('--build-hostname-file', required=True, type=argparse.FileType('r')),
|
|
||||||
parser.add_argument('--build-id', required=True)
|
|
||||||
parser.add_argument('--build-keys', required=True)
|
|
||||||
parser.add_argument('--build-number-file', required=True, type=argparse.FileType('r'))
|
|
||||||
parser.add_argument('--build-thumbprint-file', type=argparse.FileType('r'))
|
|
||||||
parser.add_argument('--build-type', required=True)
|
|
||||||
parser.add_argument('--build-username', required=True)
|
|
||||||
parser.add_argument('--build-variant', required=True)
|
|
||||||
parser.add_argument('--cpu-abis', action='append', required=True)
|
|
||||||
parser.add_argument('--date-file', required=True, type=argparse.FileType('r'))
|
|
||||||
parser.add_argument('--default-locale')
|
|
||||||
parser.add_argument('--default-wifi-channels', action='append', default=[])
|
|
||||||
parser.add_argument('--device', required=True)
|
|
||||||
parser.add_argument("--display-build-number", action='store_true')
|
|
||||||
parser.add_argument('--platform-base-os', required=True)
|
|
||||||
parser.add_argument('--platform-display-version', required=True)
|
|
||||||
parser.add_argument('--platform-min-supported-target-sdk-version', required=True)
|
|
||||||
parser.add_argument('--platform-preview-sdk-fingerprint-file',
|
|
||||||
required=True,
|
|
||||||
type=argparse.FileType('r'))
|
|
||||||
parser.add_argument('--platform-preview-sdk-version', required=True)
|
|
||||||
parser.add_argument('--platform-sdk-version', required=True)
|
|
||||||
parser.add_argument('--platform-security-patch', required=True)
|
|
||||||
parser.add_argument('--platform-version', required=True)
|
|
||||||
parser.add_argument('--platform-version-codename',required=True)
|
|
||||||
parser.add_argument('--platform-version-all-codenames', action='append', required=True)
|
|
||||||
parser.add_argument('--platform-version-known-codenames', required=True)
|
|
||||||
parser.add_argument('--platform-version-last-stable', required=True)
|
|
||||||
parser.add_argument('--product', required=True)
|
|
||||||
|
|
||||||
parser.add_argument('--out', required=True, type=argparse.FileType('w'))
|
|
||||||
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
def main():
|
|
||||||
option = parse_args()
|
|
||||||
|
|
||||||
build_hostname = option.build_hostname_file.read().strip()
|
|
||||||
build_number = option.build_number_file.read().strip()
|
|
||||||
build_version_tags = option.build_keys
|
|
||||||
if option.build_type == "debug":
|
|
||||||
build_version_tags = "debug," + build_version_tags
|
|
||||||
|
|
||||||
raw_date = option.date_file.read().strip()
|
|
||||||
date = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
|
|
||||||
date_utc = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()
|
|
||||||
|
|
||||||
# build_desc is human readable strings that describe this build. This has the same info as the
|
|
||||||
# build fingerprint.
|
|
||||||
# e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
|
|
||||||
build_desc = f"{option.product}-{option.build_variant} {option.platform_version} " \
|
|
||||||
f"{option.build_id} {build_number} {build_version_tags}"
|
|
||||||
|
|
||||||
platform_preview_sdk_fingerprint = option.platform_preview_sdk_fingerprint_file.read().strip()
|
|
||||||
|
|
||||||
with contextlib.redirect_stdout(option.out):
|
|
||||||
print("# begin build properties")
|
|
||||||
print("# autogenerated by buildinfo.py")
|
|
||||||
|
|
||||||
# The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
|
|
||||||
if option.use_vbmeta_digest_in_fingerprint:
|
|
||||||
print(f"ro.build.legacy.id={option.build_id}")
|
|
||||||
else:
|
|
||||||
print(f"ro.build.id?={option.build_id}")
|
|
||||||
|
|
||||||
# ro.build.display.id is shown under Settings -> About Phone
|
|
||||||
if option.build_variant == "user":
|
|
||||||
# User builds should show:
|
|
||||||
# release build number or branch.buld_number non-release builds
|
|
||||||
|
|
||||||
# Dev. branches should have DISPLAY_BUILD_NUMBER set
|
|
||||||
if option.display_build_number:
|
|
||||||
print(f"ro.build.display.id?={option.build_id}.{build_number} {option.build_keys}")
|
|
||||||
else:
|
|
||||||
print(f"ro.build.display.id?={option.build_id} {option.build_keys}")
|
|
||||||
else:
|
|
||||||
# Non-user builds should show detailed build information (See build desc above)
|
|
||||||
print(f"ro.build.display.id?={build_desc}")
|
|
||||||
print(f"ro.build.version.incremental={build_number}")
|
|
||||||
print(f"ro.build.version.sdk={option.platform_sdk_version}")
|
|
||||||
print(f"ro.build.version.preview_sdk={option.platform_preview_sdk_version}")
|
|
||||||
print(f"ro.build.version.preview_sdk_fingerprint={platform_preview_sdk_fingerprint}")
|
|
||||||
print(f"ro.build.version.codename={option.platform_version_codename}")
|
|
||||||
print(f"ro.build.version.all_codenames={','.join(option.platform_version_all_codenames)}")
|
|
||||||
print(f"ro.build.version.known_codenames={option.platform_version_known_codenames}")
|
|
||||||
print(f"ro.build.version.release={option.platform_version_last_stable}")
|
|
||||||
print(f"ro.build.version.release_or_codename={option.platform_version}")
|
|
||||||
print(f"ro.build.version.release_or_preview_display={option.platform_display_version}")
|
|
||||||
print(f"ro.build.version.security_patch={option.platform_security_patch}")
|
|
||||||
print(f"ro.build.version.base_os={option.platform_base_os}")
|
|
||||||
print(f"ro.build.version.min_supported_target_sdk={option.platform_min_supported_target_sdk_version}")
|
|
||||||
print(f"ro.build.date={date}")
|
|
||||||
print(f"ro.build.date.utc={date_utc}")
|
|
||||||
print(f"ro.build.type={option.build_variant}")
|
|
||||||
print(f"ro.build.user={option.build_username}")
|
|
||||||
print(f"ro.build.host={build_hostname}")
|
|
||||||
# TODO: Remove any tag-related optional property declarations once the goals
|
|
||||||
# from go/arc-android-sigprop-changes have been achieved.
|
|
||||||
print(f"ro.build.tags?={build_version_tags}")
|
|
||||||
# ro.build.flavor are used only by the test harness to distinguish builds.
|
|
||||||
# Only add _asan for a sanitized build if it isn't already a part of the
|
|
||||||
# flavor (via a dedicated lunch config for example).
|
|
||||||
print(f"ro.build.flavor={option.build_flavor}")
|
|
||||||
|
|
||||||
# These values are deprecated, use "ro.product.cpu.abilist"
|
|
||||||
# instead (see below).
|
|
||||||
print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
|
|
||||||
print(f"# use ro.product.cpu.abilist instead.")
|
|
||||||
print(f"ro.product.cpu.abi={option.cpu_abis[0]}")
|
|
||||||
if len(option.cpu_abis) > 1:
|
|
||||||
print(f"ro.product.cpu.abi2={option.cpu_abis[1]}")
|
|
||||||
|
|
||||||
if option.default_locale:
|
|
||||||
print(f"ro.product.locale={option.default_locale}")
|
|
||||||
print(f"ro.wifi.channels={' '.join(option.default_wifi_channels)}")
|
|
||||||
|
|
||||||
print(f"# ro.build.product is obsolete; use ro.product.device")
|
|
||||||
print(f"ro.build.product={option.device}")
|
|
||||||
|
|
||||||
print(f"# Do not try to parse description or thumbprint")
|
|
||||||
print(f"ro.build.description?={build_desc}")
|
|
||||||
if option.build_thumbprint_file:
|
|
||||||
build_thumbprint = option.build_thumbprint_file.read().strip()
|
|
||||||
print(f"ro.build.thumbprint={build_thumbprint}")
|
|
||||||
|
|
||||||
print(f"# end build properties")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
|
@ -259,6 +259,9 @@ com\.google\.i18n\.phonenumbers
|
||||||
org\.chromium\.arc
|
org\.chromium\.arc
|
||||||
org\.chromium\.arc\..*
|
org\.chromium\.arc\..*
|
||||||
|
|
||||||
|
# OPLUS adds
|
||||||
|
com\.oplus\..*
|
||||||
|
|
||||||
# QC adds
|
# QC adds
|
||||||
com.qualcomm.qti
|
com.qualcomm.qti
|
||||||
com.quicinc.tcmiface
|
com.quicinc.tcmiface
|
||||||
|
@ -267,3 +270,7 @@ com.qualcomm.wfd.service
|
||||||
org.codeaurora.ims
|
org.codeaurora.ims
|
||||||
org.codeaurora.internal
|
org.codeaurora.internal
|
||||||
qcom.fmradio
|
qcom.fmradio
|
||||||
|
|
||||||
|
###################################################
|
||||||
|
# IFAA Manager used for Alipay and/or WeChat payment
|
||||||
|
org\.ifaa\.android\.manager.*
|
||||||
|
|
645
scripts/gen_build_prop.py
Normal file
645
scripts/gen_build_prop.py
Normal file
|
@ -0,0 +1,645 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Copyright (C) 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.
|
||||||
|
#
|
||||||
|
"""A tool for generating {partition}/build.prop"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import contextlib
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
TEST_KEY_DIR = "build/make/target/product/security"
|
||||||
|
|
||||||
|
def get_build_variant(product_config):
|
||||||
|
if product_config["Eng"]:
|
||||||
|
return "eng"
|
||||||
|
elif product_config["Debuggable"]:
|
||||||
|
return "userdebug"
|
||||||
|
else:
|
||||||
|
return "user"
|
||||||
|
|
||||||
|
def get_build_flavor(product_config):
|
||||||
|
build_flavor = product_config["DeviceProduct"] + "-" + get_build_variant(product_config)
|
||||||
|
if "address" in product_config.get("SanitizeDevice", []) and "_asan" not in build_flavor:
|
||||||
|
build_flavor += "_asan"
|
||||||
|
return build_flavor
|
||||||
|
|
||||||
|
def get_build_keys(product_config):
|
||||||
|
default_cert = product_config.get("DefaultAppCertificate", "")
|
||||||
|
if default_cert == "" or default_cert == os.path.join(TEST_KEY_DIR, "testKey"):
|
||||||
|
return "test-keys"
|
||||||
|
return "dev-keys"
|
||||||
|
|
||||||
|
def override_config(config):
|
||||||
|
if "PRODUCT_BUILD_PROP_OVERRIDES" in config:
|
||||||
|
current_key = None
|
||||||
|
props_overrides = {}
|
||||||
|
|
||||||
|
for var in config["PRODUCT_BUILD_PROP_OVERRIDES"]:
|
||||||
|
if "=" in var:
|
||||||
|
current_key, value = var.split("=")
|
||||||
|
props_overrides[current_key] = value
|
||||||
|
else:
|
||||||
|
props_overrides[current_key] += f" {var}"
|
||||||
|
|
||||||
|
for key, value in props_overrides.items():
|
||||||
|
if key not in config:
|
||||||
|
print(f"Key \"{key}\" isn't a valid prop override", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
config[key] = value
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
"""Parse commandline arguments."""
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--build-fingerprint-file", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--build-hostname-file", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--build-number-file", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--build-thumbprint-file", type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--build-username", required=True)
|
||||||
|
parser.add_argument("--date-file", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--platform-preview-sdk-fingerprint-file", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--prop-files", action="append", type=argparse.FileType("r"), default=[])
|
||||||
|
parser.add_argument("--product-config", required=True, type=argparse.FileType("r"))
|
||||||
|
parser.add_argument("--partition", required=True)
|
||||||
|
parser.add_argument("--build-broken-dup-sysprop", action="store_true", default=False)
|
||||||
|
|
||||||
|
parser.add_argument("--out", required=True, type=argparse.FileType("w"))
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# post process parse_args requiring manual handling
|
||||||
|
args.config = json.load(args.product_config)
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
config["BuildFlavor"] = get_build_flavor(config)
|
||||||
|
config["BuildKeys"] = get_build_keys(config)
|
||||||
|
config["BuildVariant"] = get_build_variant(config)
|
||||||
|
|
||||||
|
config["BuildFingerprint"] = args.build_fingerprint_file.read().strip()
|
||||||
|
config["BuildHostname"] = args.build_hostname_file.read().strip()
|
||||||
|
config["BuildNumber"] = args.build_number_file.read().strip()
|
||||||
|
config["BuildUsername"] = args.build_username
|
||||||
|
|
||||||
|
build_version_tags_list = config["BuildVersionTags"]
|
||||||
|
if config["BuildType"] == "debug":
|
||||||
|
build_version_tags_list.append("debug")
|
||||||
|
build_version_tags_list.append(config["BuildKeys"])
|
||||||
|
build_version_tags = ",".join(sorted(set(build_version_tags_list)))
|
||||||
|
config["BuildVersionTags"] = build_version_tags
|
||||||
|
|
||||||
|
raw_date = args.date_file.read().strip()
|
||||||
|
config["Date"] = subprocess.check_output(["date", "-d", f"@{raw_date}"], text=True).strip()
|
||||||
|
config["DateUtc"] = subprocess.check_output(["date", "-d", f"@{raw_date}", "+%s"], text=True).strip()
|
||||||
|
|
||||||
|
# build_desc is human readable strings that describe this build. This has the same info as the
|
||||||
|
# build fingerprint.
|
||||||
|
# e.g. "aosp_cf_x86_64_phone-userdebug VanillaIceCream MAIN eng.20240319.143939 test-keys"
|
||||||
|
config["BuildDesc"] = f"{config['DeviceProduct']}-{config['BuildVariant']} " \
|
||||||
|
f"{config['Platform_version_name']} {config['BuildId']} " \
|
||||||
|
f"{config['BuildNumber']} {config['BuildVersionTags']}"
|
||||||
|
|
||||||
|
config["PlatformPreviewSdkFingerprint"] = args.platform_preview_sdk_fingerprint_file.read().strip()
|
||||||
|
|
||||||
|
if args.build_thumbprint_file:
|
||||||
|
config["BuildThumbprint"] = args.build_thumbprint_file.read().strip()
|
||||||
|
|
||||||
|
config["tequilaDesc"] = config["BuildDesc"]
|
||||||
|
config["tequilaDevice"] = config["DeviceName"]
|
||||||
|
|
||||||
|
override_config(config)
|
||||||
|
|
||||||
|
append_additional_system_props(args)
|
||||||
|
append_additional_vendor_props(args)
|
||||||
|
append_additional_product_props(args)
|
||||||
|
|
||||||
|
return args
|
||||||
|
|
||||||
|
def generate_common_build_props(args):
|
||||||
|
print("####################################")
|
||||||
|
print("# from generate_common_build_props")
|
||||||
|
print("# These properties identify this partition image.")
|
||||||
|
print("####################################")
|
||||||
|
|
||||||
|
config = args.config
|
||||||
|
partition = args.partition
|
||||||
|
|
||||||
|
if partition == "system":
|
||||||
|
print(f"ro.product.{partition}.brand={config['SystemBrand']}")
|
||||||
|
print(f"ro.product.{partition}.device={config['SystemDevice']}")
|
||||||
|
print(f"ro.product.{partition}.manufacturer={config['SystemManufacturer']}")
|
||||||
|
print(f"ro.product.{partition}.model={config['SystemModel']}")
|
||||||
|
print(f"ro.product.{partition}.name={config['SystemName']}")
|
||||||
|
else:
|
||||||
|
print(f"ro.product.{partition}.brand={config['ProductBrand']}")
|
||||||
|
print(f"ro.product.{partition}.device={config['DeviceName']}")
|
||||||
|
print(f"ro.product.{partition}.manufacturer={config['ProductManufacturer']}")
|
||||||
|
print(f"ro.product.{partition}.model={config['ProductModel']}")
|
||||||
|
print(f"ro.product.{partition}.name={config['DeviceProduct']}")
|
||||||
|
|
||||||
|
if partition != "system":
|
||||||
|
if config["ProductModelForAttestation"]:
|
||||||
|
print(f"ro.product.model_for_attestation={config['ProductModelForAttestation']}")
|
||||||
|
if config["ProductBrandForAttestation"]:
|
||||||
|
print(f"ro.product.brand_for_attestation={config['ProductBrandForAttestation']}")
|
||||||
|
if config["ProductNameForAttestation"]:
|
||||||
|
print(f"ro.product.name_for_attestation={config['ProductNameForAttestation']}")
|
||||||
|
if config["ProductDeviceForAttestation"]:
|
||||||
|
print(f"ro.product.device_for_attestation={config['ProductDeviceForAttestation']}")
|
||||||
|
if config["ProductManufacturerForAttestation"]:
|
||||||
|
print(f"ro.product.manufacturer_for_attestation={config['ProductManufacturerForAttestation']}")
|
||||||
|
|
||||||
|
if config["ZygoteForce64"]:
|
||||||
|
if partition == "vendor":
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList64']}")
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist32=")
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
|
||||||
|
else:
|
||||||
|
if partition == "system" or partition == "vendor" or partition == "odm":
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist={config['DeviceAbiList']}")
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist32={config['DeviceAbiList32']}")
|
||||||
|
print(f"ro.{partition}.product.cpu.abilist64={config['DeviceAbiList64']}")
|
||||||
|
|
||||||
|
print(f"ro.{partition}.build.date={config['Date']}")
|
||||||
|
print(f"ro.{partition}.build.date.utc={config['DateUtc']}")
|
||||||
|
# Allow optional assignments for ARC forward-declarations (b/249168657)
|
||||||
|
# TODO: Remove any tag-related inconsistencies once the goals from
|
||||||
|
# go/arc-android-sigprop-changes have been achieved.
|
||||||
|
print(f"ro.{partition}.build.fingerprint?={config['BuildFingerprint']}")
|
||||||
|
print(f"ro.{partition}.build.id?={config['BuildId']}")
|
||||||
|
print(f"ro.{partition}.build.tags?={config['BuildVersionTags']}")
|
||||||
|
print(f"ro.{partition}.build.type={config['BuildVariant']}")
|
||||||
|
print(f"ro.{partition}.build.version.incremental={config['BuildNumber']}")
|
||||||
|
print(f"ro.{partition}.build.version.release={config['Platform_version_last_stable']}")
|
||||||
|
print(f"ro.{partition}.build.version.release_or_codename={config['Platform_version_name']}")
|
||||||
|
print(f"ro.{partition}.build.version.sdk={config['Platform_sdk_version']}")
|
||||||
|
|
||||||
|
def generate_build_info(args):
|
||||||
|
print()
|
||||||
|
print("####################################")
|
||||||
|
print("# from gen_build_prop.py:generate_build_info")
|
||||||
|
print("####################################")
|
||||||
|
print("# begin build properties")
|
||||||
|
|
||||||
|
config = args.config
|
||||||
|
build_flags = config["BuildFlags"]
|
||||||
|
|
||||||
|
print(f"ro.build.fingerprint?={config['BuildFingerprint']}")
|
||||||
|
|
||||||
|
# The ro.build.id will be set dynamically by init, by appending the unique vbmeta digest.
|
||||||
|
if config["BoardUseVbmetaDigestInFingerprint"]:
|
||||||
|
print(f"ro.build.legacy.id={config['BuildId']}")
|
||||||
|
else:
|
||||||
|
print(f"ro.build.id?={config['BuildId']}")
|
||||||
|
|
||||||
|
# ro.build.display.id is shown under Settings -> About Phone
|
||||||
|
if config["BuildVariant"] == "user":
|
||||||
|
# User builds should show:
|
||||||
|
# release build number or branch.buld_number non-release builds
|
||||||
|
|
||||||
|
# Dev. branches should have DISPLAY_BUILD_NUMBER set
|
||||||
|
if config["DisplayBuildNumber"]:
|
||||||
|
print(f"ro.build.display.id?={config['BuildId']}.{config['BuildNumber']} {config['BuildKeys']}")
|
||||||
|
else:
|
||||||
|
print(f"ro.build.display.id?={config['BuildId']} {config['BuildKeys']}")
|
||||||
|
else:
|
||||||
|
# Non-user builds should show detailed build information (See build desc above)
|
||||||
|
print(f"ro.build.display.id?={config['tequilaDesc']}")
|
||||||
|
print(f"ro.build.version.incremental={config['BuildNumber']}")
|
||||||
|
print(f"ro.build.version.sdk={config['Platform_sdk_version']}")
|
||||||
|
print(f"ro.build.version.preview_sdk={config['Platform_preview_sdk_version']}")
|
||||||
|
print(f"ro.build.version.preview_sdk_fingerprint={config['PlatformPreviewSdkFingerprint']}")
|
||||||
|
print(f"ro.build.version.codename={config['Platform_sdk_codename']}")
|
||||||
|
print(f"ro.build.version.all_codenames={','.join(config['Platform_version_active_codenames'])}")
|
||||||
|
print(f"ro.build.version.known_codenames={config['Platform_version_known_codenames']}")
|
||||||
|
print(f"ro.build.version.release={config['Platform_version_last_stable']}")
|
||||||
|
print(f"ro.build.version.release_or_codename={config['Platform_version_name']}")
|
||||||
|
print(f"ro.build.version.release_or_preview_display={config['Platform_display_version_name']}")
|
||||||
|
print(f"ro.build.version.security_patch={config['Platform_security_patch']}")
|
||||||
|
print(f"ro.build.version.base_os={config['Platform_base_os']}")
|
||||||
|
print(f"ro.build.version.min_supported_target_sdk={build_flags['RELEASE_PLATFORM_MIN_SUPPORTED_TARGET_SDK_VERSION']}")
|
||||||
|
print(f"ro.build.date={config['Date']}")
|
||||||
|
print(f"ro.build.date.utc={config['DateUtc']}")
|
||||||
|
print(f"ro.build.type={config['BuildVariant']}")
|
||||||
|
print(f"ro.build.user={config['BuildUsername']}")
|
||||||
|
print(f"ro.build.host={config['BuildHostname']}")
|
||||||
|
# TODO: Remove any tag-related optional property declarations once the goals
|
||||||
|
# from go/arc-android-sigprop-changes have been achieved.
|
||||||
|
print(f"ro.build.tags?={config['BuildVersionTags']}")
|
||||||
|
# ro.build.flavor are used only by the test harness to distinguish builds.
|
||||||
|
# Only add _asan for a sanitized build if it isn't already a part of the
|
||||||
|
# flavor (via a dedicated lunch config for example).
|
||||||
|
print(f"ro.build.flavor={config['BuildFlavor']}")
|
||||||
|
|
||||||
|
print(f"ro.tequila.device={config['tequilaDevice']}")
|
||||||
|
|
||||||
|
# These values are deprecated, use "ro.product.cpu.abilist"
|
||||||
|
# instead (see below).
|
||||||
|
print(f"# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
|
||||||
|
print(f"# use ro.product.cpu.abilist instead.")
|
||||||
|
print(f"ro.product.cpu.abi={config['DeviceAbi'][0]}")
|
||||||
|
if len(config["DeviceAbi"]) > 1:
|
||||||
|
print(f"ro.product.cpu.abi2={config['DeviceAbi'][1]}")
|
||||||
|
|
||||||
|
if config["ProductLocales"]:
|
||||||
|
print(f"ro.product.locale={config['ProductLocales'][0]}")
|
||||||
|
print(f"ro.wifi.channels={' '.join(config['ProductDefaultWifiChannels'])}")
|
||||||
|
|
||||||
|
print(f"# ro.build.product is obsolete; use ro.product.device")
|
||||||
|
print(f"ro.build.product={config['DeviceName']}")
|
||||||
|
|
||||||
|
print(f"# Do not try to parse description or thumbprint")
|
||||||
|
print(f"ro.build.description?={config['BuildDesc']}")
|
||||||
|
if "BuildThumbprint" in config:
|
||||||
|
print(f"ro.build.thumbprint={config['BuildThumbprint']}")
|
||||||
|
|
||||||
|
print(f"# end build properties")
|
||||||
|
|
||||||
|
def write_properties_from_file(file):
|
||||||
|
print()
|
||||||
|
print("####################################")
|
||||||
|
print(f"# from {file.name}")
|
||||||
|
print("####################################")
|
||||||
|
print(file.read(), end="")
|
||||||
|
|
||||||
|
def write_properties_from_variable(name, props, build_broken_dup_sysprop):
|
||||||
|
print()
|
||||||
|
print("####################################")
|
||||||
|
print(f"# from variable {name}")
|
||||||
|
print("####################################")
|
||||||
|
|
||||||
|
# Implement the legacy behavior when BUILD_BROKEN_DUP_SYSPROP is on.
|
||||||
|
# Optional assignments are all converted to normal assignments and
|
||||||
|
# when their duplicates the first one wins.
|
||||||
|
if build_broken_dup_sysprop:
|
||||||
|
processed_props = []
|
||||||
|
seen_props = set()
|
||||||
|
for line in props:
|
||||||
|
line = line.replace("?=", "=")
|
||||||
|
key, value = line.split("=", 1)
|
||||||
|
if key in seen_props:
|
||||||
|
continue
|
||||||
|
seen_props.add(key)
|
||||||
|
processed_props.append(line)
|
||||||
|
props = processed_props
|
||||||
|
|
||||||
|
for line in props:
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
def append_additional_system_props(args):
|
||||||
|
props = []
|
||||||
|
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Add the product-defined properties to the build properties.
|
||||||
|
if not config["PropertySplitEnabled"] or not config["VendorImageFileSystemType"]:
|
||||||
|
if "PRODUCT_PROPERTY_OVERRIDES" in config:
|
||||||
|
props += config["PRODUCT_PROPERTY_OVERRIDES"]
|
||||||
|
|
||||||
|
props.append(f"ro.treble.enabled={'true' if config['FullTreble'] else 'false'}")
|
||||||
|
# Set ro.llndk.api_level to show the maximum vendor API level that the LLNDK
|
||||||
|
# in the system partition supports.
|
||||||
|
if config["VendorApiLevel"]:
|
||||||
|
props.append(f"ro.llndk.api_level={config['VendorApiLevel']}")
|
||||||
|
|
||||||
|
# Sets ro.actionable_compatible_property.enabled to know on runtime whether
|
||||||
|
# the allowed list of actionable compatible properties is enabled or not.
|
||||||
|
props.append("ro.actionable_compatible_property.enabled=true")
|
||||||
|
|
||||||
|
# Enable core platform API violation warnings on userdebug and eng builds.
|
||||||
|
if config["BuildVariant"] != "user":
|
||||||
|
props.append("persist.debug.dalvik.vm.core_platform_api_policy=just-warn")
|
||||||
|
|
||||||
|
# Define ro.sanitize.<name> properties for all global sanitizers.
|
||||||
|
for sanitize_target in config["SanitizeDevice"]:
|
||||||
|
props.append(f"ro.sanitize.{sanitize_target}=true")
|
||||||
|
|
||||||
|
# Sets the default value of ro.postinstall.fstab.prefix to /system.
|
||||||
|
# Device board config should override the value to /product when needed by:
|
||||||
|
#
|
||||||
|
# PRODUCT_PRODUCT_PROPERTIES += ro.postinstall.fstab.prefix=/product
|
||||||
|
#
|
||||||
|
# It then uses ${ro.postinstall.fstab.prefix}/etc/fstab.postinstall to
|
||||||
|
# mount system_other partition.
|
||||||
|
props.append("ro.postinstall.fstab.prefix=/system")
|
||||||
|
|
||||||
|
enable_target_debugging = True
|
||||||
|
enable_dalvik_lock_contention_logging = True
|
||||||
|
if config["BuildVariant"] == "user" or config["BuildVariant"] == "userdebug":
|
||||||
|
# Target is secure in user builds.
|
||||||
|
props.append("ro.secure=1")
|
||||||
|
props.append("security.perf_harden=1")
|
||||||
|
|
||||||
|
if config["BuildVariant"] == "user":
|
||||||
|
# Disable debugging in plain user builds.
|
||||||
|
props.append("ro.adb.secure=1")
|
||||||
|
enable_target_debugging = False
|
||||||
|
enable_dalvik_lock_contention_logging = False
|
||||||
|
else:
|
||||||
|
# Disable debugging in userdebug builds if PRODUCT_NOT_DEBUGGABLE_IN_USERDEBUG
|
||||||
|
# is set.
|
||||||
|
if config["ProductNotDebuggableInUserdebug"]:
|
||||||
|
enable_target_debugging = False
|
||||||
|
|
||||||
|
# Disallow mock locations by default for user builds
|
||||||
|
props.append("ro.allow.mock.location=0")
|
||||||
|
else:
|
||||||
|
# Turn on checkjni for non-user builds.
|
||||||
|
props.append("ro.kernel.android.checkjni=1")
|
||||||
|
# Set device insecure for non-user builds.
|
||||||
|
props.append("ro.secure=0")
|
||||||
|
# Allow mock locations by default for non user builds
|
||||||
|
props.append("ro.allow.mock.location=1")
|
||||||
|
|
||||||
|
if enable_dalvik_lock_contention_logging:
|
||||||
|
# Enable Dalvik lock contention logging.
|
||||||
|
props.append("dalvik.vm.lockprof.threshold=500")
|
||||||
|
|
||||||
|
if enable_target_debugging:
|
||||||
|
# Target is more debuggable and adbd is on by default
|
||||||
|
props.append("ro.debuggable=1")
|
||||||
|
else:
|
||||||
|
# Target is less debuggable and adbd is off by default
|
||||||
|
props.append("ro.debuggable=0")
|
||||||
|
|
||||||
|
if config["BuildVariant"] == "eng":
|
||||||
|
if "ro.setupwizard.mode=ENABLED" in props:
|
||||||
|
# Don't require the setup wizard on eng builds
|
||||||
|
props = list(filter(lambda x: not x.startswith("ro.setupwizard.mode="), props))
|
||||||
|
props.append("ro.setupwizard.mode=OPTIONAL")
|
||||||
|
|
||||||
|
if not config["SdkBuild"]:
|
||||||
|
# To speedup startup of non-preopted builds, don't verify or compile the boot image.
|
||||||
|
props.append("dalvik.vm.image-dex2oat-filter=extract")
|
||||||
|
# b/323566535
|
||||||
|
props.append("init.svc_debug.no_fatal.zygote=true")
|
||||||
|
|
||||||
|
if config["SdkBuild"]:
|
||||||
|
props.append("xmpp.auto-presence=true")
|
||||||
|
props.append("ro.config.nocheckin=yes")
|
||||||
|
|
||||||
|
props.append("net.bt.name=Android")
|
||||||
|
|
||||||
|
# This property is set by flashing debug boot image, so default to false.
|
||||||
|
props.append("ro.force.debuggable=0")
|
||||||
|
|
||||||
|
config["ADDITIONAL_SYSTEM_PROPERTIES"] = props
|
||||||
|
|
||||||
|
def append_additional_vendor_props(args):
|
||||||
|
props = []
|
||||||
|
|
||||||
|
config = args.config
|
||||||
|
build_flags = config["BuildFlags"]
|
||||||
|
|
||||||
|
# Add cpu properties for bionic and ART.
|
||||||
|
props.append(f"ro.bionic.arch={config['DeviceArch']}")
|
||||||
|
props.append(f"ro.bionic.cpu_variant={config['DeviceCpuVariantRuntime']}")
|
||||||
|
props.append(f"ro.bionic.2nd_arch={config['DeviceSecondaryArch']}")
|
||||||
|
props.append(f"ro.bionic.2nd_cpu_variant={config['DeviceSecondaryCpuVariantRuntime']}")
|
||||||
|
|
||||||
|
props.append(f"persist.sys.dalvik.vm.lib.2=libart.so")
|
||||||
|
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.variant={config['Dex2oatTargetCpuVariantRuntime']}")
|
||||||
|
if config["Dex2oatTargetInstructionSetFeatures"]:
|
||||||
|
props.append(f"dalvik.vm.isa.{config['DeviceArch']}.features={config['Dex2oatTargetInstructionSetFeatures']}")
|
||||||
|
|
||||||
|
if config["DeviceSecondaryArch"]:
|
||||||
|
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.variant={config['SecondaryDex2oatCpuVariantRuntime']}")
|
||||||
|
if config["SecondaryDex2oatInstructionSetFeatures"]:
|
||||||
|
props.append(f"dalvik.vm.isa.{config['DeviceSecondaryArch']}.features={config['SecondaryDex2oatInstructionSetFeatures']}")
|
||||||
|
|
||||||
|
# Although these variables are prefixed with TARGET_RECOVERY_, they are also needed under charger
|
||||||
|
# mode (via libminui).
|
||||||
|
if config["RecoveryDefaultRotation"]:
|
||||||
|
props.append(f"ro.minui.default_rotation={config['RecoveryDefaultRotation']}")
|
||||||
|
|
||||||
|
if config["RecoveryDefaultTouchRotation"]:
|
||||||
|
props.append(f"ro.minui.default_touch_rotation={config['RecoveryDefaultTouchRotation']}")
|
||||||
|
|
||||||
|
if config["RecoveryOverscanPercent"]:
|
||||||
|
props.append(f"ro.minui.overscan_percent={config['RecoveryOverscanPercent']}")
|
||||||
|
|
||||||
|
if config["RecoveryPixelFormat"]:
|
||||||
|
props.append(f"ro.minui.pixel_format={config['RecoveryPixelFormat']}")
|
||||||
|
|
||||||
|
if "UseDynamicPartitions" in config:
|
||||||
|
props.append(f"ro.boot.dynamic_partitions={'true' if config['UseDynamicPartitions'] else 'false'}")
|
||||||
|
|
||||||
|
if "RetrofitDynamicPartitions" in config:
|
||||||
|
props.append(f"ro.boot.dynamic_partitions_retrofit={'true' if config['RetrofitDynamicPartitions'] else 'false'}")
|
||||||
|
|
||||||
|
if config["ShippingApiLevel"]:
|
||||||
|
props.append(f"ro.product.first_api_level={config['ShippingApiLevel']}")
|
||||||
|
|
||||||
|
if config["ShippingVendorApiLevel"]:
|
||||||
|
props.append(f"ro.vendor.api_level={config['ShippingVendorApiLevel']}")
|
||||||
|
|
||||||
|
if config["BuildVariant"] != "user" and config["BuildDebugfsRestrictionsEnabled"]:
|
||||||
|
props.append(f"ro.product.debugfs_restrictions.enabled=true")
|
||||||
|
|
||||||
|
# Vendors with GRF must define BOARD_SHIPPING_API_LEVEL for the vendor API level.
|
||||||
|
# This must not be defined for the non-GRF devices.
|
||||||
|
# The values of the GRF properties will be verified by post_process_props.py
|
||||||
|
if config["BoardShippingApiLevel"]:
|
||||||
|
props.append(f"ro.board.first_api_level={config['BoardShippingApiLevel']}")
|
||||||
|
|
||||||
|
# Build system set BOARD_API_LEVEL to show the api level of the vendor API surface.
|
||||||
|
# This must not be altered outside of build system.
|
||||||
|
if config["VendorApiLevel"]:
|
||||||
|
props.append(f"ro.board.api_level={config['VendorApiLevel']}")
|
||||||
|
|
||||||
|
# RELEASE_BOARD_API_LEVEL_FROZEN is true when the vendor API surface is frozen.
|
||||||
|
if build_flags["RELEASE_BOARD_API_LEVEL_FROZEN"]:
|
||||||
|
props.append(f"ro.board.api_frozen=true")
|
||||||
|
|
||||||
|
# Set build prop. This prop is read by ota_from_target_files when generating OTA,
|
||||||
|
# to decide if VABC should be disabled.
|
||||||
|
if config["DontUseVabcOta"]:
|
||||||
|
props.append(f"ro.vendor.build.dont_use_vabc=true")
|
||||||
|
|
||||||
|
# Set the flag in vendor. So VTS would know if the new fingerprint format is in use when
|
||||||
|
# the system images are replaced by GSI.
|
||||||
|
if config["BoardUseVbmetaDigestInFingerprint"]:
|
||||||
|
props.append(f"ro.vendor.build.fingerprint_has_digest=1")
|
||||||
|
|
||||||
|
props.append(f"ro.vendor.build.security_patch={config['VendorSecurityPatch']}")
|
||||||
|
props.append(f"ro.product.board={config['BootloaderBoardName']}")
|
||||||
|
props.append(f"ro.board.platform={config['BoardPlatform']}")
|
||||||
|
props.append(f"ro.hwui.use_vulkan={'true' if config['UsesVulkan'] else 'false'}")
|
||||||
|
|
||||||
|
if config["ScreenDensity"]:
|
||||||
|
props.append(f"ro.sf.lcd_density={config['ScreenDensity']}")
|
||||||
|
|
||||||
|
if "AbOtaUpdater" in config:
|
||||||
|
props.append(f"ro.build.ab_update={'true' if config['AbOtaUpdater'] else 'false'}")
|
||||||
|
if config["AbOtaUpdater"]:
|
||||||
|
props.append(f"ro.vendor.build.ab_ota_partitions={config['AbOtaPartitions']}")
|
||||||
|
|
||||||
|
config["ADDITIONAL_VENDOR_PROPERTIES"] = props
|
||||||
|
|
||||||
|
def append_additional_product_props(args):
|
||||||
|
props = []
|
||||||
|
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Add the system server compiler filter if they are specified for the product.
|
||||||
|
if config["SystemServerCompilerFilter"]:
|
||||||
|
props.append(f"dalvik.vm.systemservercompilerfilter={config['SystemServerCompilerFilter']}")
|
||||||
|
|
||||||
|
# Add the 16K developer args if it is defined for the product.
|
||||||
|
props.append(f"ro.product.build.16k_page.enabled={'true' if config['Product16KDeveloperOption'] else 'false'}")
|
||||||
|
|
||||||
|
props.append(f"ro.product.page_size={16384 if config['TargetBoots16K'] else 4096}")
|
||||||
|
|
||||||
|
props.append(f"ro.build.characteristics={config['AAPTCharacteristics']}")
|
||||||
|
|
||||||
|
if "AbOtaUpdater" in config and config["AbOtaUpdater"]:
|
||||||
|
props.append(f"ro.product.ab_ota_partitions={config['AbOtaPartitions']}")
|
||||||
|
|
||||||
|
# Set this property for VTS to skip large page size tests on unsupported devices.
|
||||||
|
props.append(f"ro.product.cpu.pagesize.max={config['DeviceMaxPageSizeSupported']}")
|
||||||
|
|
||||||
|
if config["NoBionicPageSizeMacro"]:
|
||||||
|
props.append(f"ro.product.build.no_bionic_page_size_macro=true")
|
||||||
|
|
||||||
|
# This is a temporary system property that controls the ART module. The plan is
|
||||||
|
# to remove it by Aug 2025, at which time Mainline updates of the ART module
|
||||||
|
# will ignore it as well.
|
||||||
|
# If the value is "default", it will be mangled by post_process_props.py.
|
||||||
|
props.append(f"ro.dalvik.vm.enable_uffd_gc={config['EnableUffdGc']}")
|
||||||
|
|
||||||
|
config["ADDITIONAL_PRODUCT_PROPERTIES"] = props
|
||||||
|
|
||||||
|
def build_system_prop(args):
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Order matters here. When there are duplicates, the last one wins.
|
||||||
|
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
|
||||||
|
variables = [
|
||||||
|
"ADDITIONAL_SYSTEM_PROPERTIES",
|
||||||
|
"PRODUCT_SYSTEM_PROPERTIES",
|
||||||
|
# TODO(b/117892318): deprecate this
|
||||||
|
"PRODUCT_SYSTEM_DEFAULT_PROPERTIES",
|
||||||
|
]
|
||||||
|
|
||||||
|
if not config["PropertySplitEnabled"]:
|
||||||
|
variables += [
|
||||||
|
"ADDITIONAL_VENDOR_PROPERTIES",
|
||||||
|
"PRODUCT_VENDOR_PROPERTIES",
|
||||||
|
]
|
||||||
|
|
||||||
|
build_prop(args, gen_build_info=True, gen_common_build_props=True, variables=variables)
|
||||||
|
|
||||||
|
def build_system_ext_prop(args):
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Order matters here. When there are duplicates, the last one wins.
|
||||||
|
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
|
||||||
|
variables = ["PRODUCT_SYSTEM_EXT_PROPERTIES"]
|
||||||
|
|
||||||
|
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
|
||||||
|
|
||||||
|
'''
|
||||||
|
def build_vendor_prop(args):
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Order matters here. When there are duplicates, the last one wins.
|
||||||
|
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
|
||||||
|
variables = []
|
||||||
|
if config["PropertySplitEnabled"]:
|
||||||
|
variables += [
|
||||||
|
"ADDITIONAL_VENDOR_PROPERTIES",
|
||||||
|
"PRODUCT_VENDOR_PROPERTIES",
|
||||||
|
# TODO(b/117892318): deprecate this
|
||||||
|
"PRODUCT_DEFAULT_PROPERTY_OVERRIDES",
|
||||||
|
"PRODUCT_PROPERTY_OVERRIDES",
|
||||||
|
]
|
||||||
|
|
||||||
|
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
|
||||||
|
'''
|
||||||
|
|
||||||
|
def build_product_prop(args):
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
# Order matters here. When there are duplicates, the last one wins.
|
||||||
|
# TODO(b/117892318): don't allow duplicates so that the ordering doesn't matter
|
||||||
|
variables = [
|
||||||
|
"ADDITIONAL_PRODUCT_PROPERTIES",
|
||||||
|
"PRODUCT_PRODUCT_PROPERTIES",
|
||||||
|
]
|
||||||
|
|
||||||
|
gen_common_build_props = True
|
||||||
|
|
||||||
|
# Skip common /product properties generation if device released before R and
|
||||||
|
# has no product partition. This is the first part of the check.
|
||||||
|
if config["Shipping_api_level"] and int(config["Shipping_api_level"]) < 30:
|
||||||
|
gen_common_build_props = False
|
||||||
|
|
||||||
|
# The second part of the check - always generate common properties for the
|
||||||
|
# devices with product partition regardless of shipping level.
|
||||||
|
if config["UsesProductImage"]:
|
||||||
|
gen_common_build_props = True
|
||||||
|
|
||||||
|
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
|
||||||
|
|
||||||
|
if config["OemProperties"]:
|
||||||
|
print("####################################")
|
||||||
|
print("# PRODUCT_OEM_PROPERTIES")
|
||||||
|
print("####################################")
|
||||||
|
|
||||||
|
for prop in config["OemProperties"]:
|
||||||
|
print(f"import /oem/oem.prop {prop}")
|
||||||
|
|
||||||
|
def build_odm_prop(args):
|
||||||
|
variables = ["ADDITIONAL_ODM_PROPERTIES", "PRODUCT_ODM_PROPERTIES"]
|
||||||
|
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=variables)
|
||||||
|
|
||||||
|
def build_prop(args, gen_build_info, gen_common_build_props, variables):
|
||||||
|
config = args.config
|
||||||
|
|
||||||
|
if gen_common_build_props:
|
||||||
|
generate_common_build_props(args)
|
||||||
|
|
||||||
|
if gen_build_info:
|
||||||
|
generate_build_info(args)
|
||||||
|
|
||||||
|
for prop_file in args.prop_files:
|
||||||
|
write_properties_from_file(prop_file)
|
||||||
|
|
||||||
|
for variable in variables:
|
||||||
|
if variable in config:
|
||||||
|
write_properties_from_variable(variable, config[variable], args.build_broken_dup_sysprop)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
|
||||||
|
with contextlib.redirect_stdout(args.out):
|
||||||
|
match args.partition:
|
||||||
|
case "system":
|
||||||
|
build_system_prop(args)
|
||||||
|
case "system_ext":
|
||||||
|
build_system_ext_prop(args)
|
||||||
|
case "odm":
|
||||||
|
build_odm_prop(args)
|
||||||
|
case "product":
|
||||||
|
build_product_prop(args)
|
||||||
|
# case "vendor": # NOT IMPLEMENTED
|
||||||
|
# build_vendor_prop(args)
|
||||||
|
case _:
|
||||||
|
sys.exit(f"not supported partition {args.partition}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
62
scripts/merge_json.py
Normal file
62
scripts/merge_json.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
"""A tool for merging two or more JSON files."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import logging
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
"""Parse commandline arguments."""
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("output", help="output JSON file", type=argparse.FileType("w"))
|
||||||
|
parser.add_argument("input", help="input JSON files", nargs="+", type=argparse.FileType("r"))
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Program entry point."""
|
||||||
|
args = parse_args()
|
||||||
|
merged_dict = {}
|
||||||
|
has_error = False
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
for json_file in args.input:
|
||||||
|
try:
|
||||||
|
data = json.load(json_file)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
logger.error(f"Error parsing JSON in file: {json_file.name}. Reason: {e}")
|
||||||
|
has_error = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
for key, value in data.items():
|
||||||
|
if key not in merged_dict:
|
||||||
|
merged_dict[key] = value
|
||||||
|
elif merged_dict[key] == value:
|
||||||
|
logger.warning(f"Duplicate key '{key}' with identical values found.")
|
||||||
|
else:
|
||||||
|
logger.error(f"Conflicting values for key '{key}': {merged_dict[key]} != {value}")
|
||||||
|
has_error = True
|
||||||
|
|
||||||
|
if has_error:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
json.dump(merged_dict, args.output)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
|
@ -129,12 +129,12 @@ func (c *hostFakeSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||||
if !seen[outFile] {
|
if !seen[outFile] {
|
||||||
seen[outFile] = true
|
seen[outFile] = true
|
||||||
outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
|
outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
|
||||||
jsonData = append(jsonData, hostSnapshotFakeJsonFlags{*hostJsonDesc(module), false})
|
jsonData = append(jsonData, hostSnapshotFakeJsonFlags{*hostJsonDesc(ctx, module), false})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Update any module prebuilt information
|
// Update any module prebuilt information
|
||||||
for idx, _ := range jsonData {
|
for idx := range jsonData {
|
||||||
if _, ok := prebuilts[jsonData[idx].ModuleName]; ok {
|
if _, ok := prebuilts[jsonData[idx].ModuleName]; ok {
|
||||||
// Prebuilt exists for this module
|
// Prebuilt exists for this module
|
||||||
jsonData[idx].Prebuilt = true
|
jsonData[idx].Prebuilt = true
|
||||||
|
|
|
@ -101,7 +101,7 @@ func (f *hostSnapshot) CreateMetaData(ctx android.ModuleContext, fileName string
|
||||||
|
|
||||||
// Create JSON file based on the direct dependencies
|
// Create JSON file based on the direct dependencies
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
desc := hostJsonDesc(dep)
|
desc := hostJsonDesc(ctx, dep)
|
||||||
if desc != nil {
|
if desc != nil {
|
||||||
jsonData = append(jsonData, *desc)
|
jsonData = append(jsonData, *desc)
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func hostRelativePathString(m android.Module) string {
|
||||||
|
|
||||||
// Create JSON description for given module, only create descriptions for binary modules
|
// Create JSON description for given module, only create descriptions for binary modules
|
||||||
// and rust_proc_macro modules which provide a valid HostToolPath
|
// and rust_proc_macro modules which provide a valid HostToolPath
|
||||||
func hostJsonDesc(m android.Module) *SnapshotJsonFlags {
|
func hostJsonDesc(ctx android.ConfigAndErrorContext, m android.Module) *SnapshotJsonFlags {
|
||||||
path := hostToolPath(m)
|
path := hostToolPath(m)
|
||||||
relPath := hostRelativePathString(m)
|
relPath := hostRelativePathString(m)
|
||||||
procMacro := false
|
procMacro := false
|
||||||
|
@ -226,7 +226,7 @@ func hostJsonDesc(m android.Module) *SnapshotJsonFlags {
|
||||||
props := &SnapshotJsonFlags{
|
props := &SnapshotJsonFlags{
|
||||||
ModuleStemName: moduleStem,
|
ModuleStemName: moduleStem,
|
||||||
Filename: path.String(),
|
Filename: path.String(),
|
||||||
Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames()...),
|
Required: append(m.HostRequiredModuleNames(), m.RequiredModuleNames(ctx)...),
|
||||||
RelativeInstallPath: relPath,
|
RelativeInstallPath: relPath,
|
||||||
RustProcMacro: procMacro,
|
RustProcMacro: procMacro,
|
||||||
CrateName: crateName,
|
CrateName: crateName,
|
||||||
|
|
|
@ -79,7 +79,7 @@ func SetupOutDir(ctx Context, config Config) {
|
||||||
if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
|
if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
|
||||||
ctx.Fatalln("Missing BUILD_USERNAME")
|
ctx.Fatalln("Missing BUILD_USERNAME")
|
||||||
}
|
}
|
||||||
buildNumber = fmt.Sprintf("eng.%.6s.00000000.000000", username)
|
buildNumber = fmt.Sprintf("eng.%.6s", username)
|
||||||
writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
|
writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
|
||||||
}
|
}
|
||||||
// Write the build number to a file so it can be read back in
|
// Write the build number to a file so it can be read back in
|
||||||
|
|
|
@ -125,11 +125,13 @@ func installClean(ctx Context, config Config) {
|
||||||
hostCommonOut("obj/PACKAGING"),
|
hostCommonOut("obj/PACKAGING"),
|
||||||
productOut("*.img"),
|
productOut("*.img"),
|
||||||
productOut("*.zip"),
|
productOut("*.zip"),
|
||||||
|
productOut("*.zip.sha256sum"),
|
||||||
productOut("android-info.txt"),
|
productOut("android-info.txt"),
|
||||||
productOut("misc_info.txt"),
|
productOut("misc_info.txt"),
|
||||||
productOut("apex"),
|
productOut("apex"),
|
||||||
productOut("kernel"),
|
productOut("kernel"),
|
||||||
productOut("kernel-*"),
|
productOut("kernel-*"),
|
||||||
|
productOut("recovery_kernel"),
|
||||||
productOut("data"),
|
productOut("data"),
|
||||||
productOut("skin"),
|
productOut("skin"),
|
||||||
productOut("obj/NOTICE_FILES"),
|
productOut("obj/NOTICE_FILES"),
|
||||||
|
@ -160,7 +162,8 @@ func installClean(ctx Context, config Config) {
|
||||||
productOut("odm_dlkm"),
|
productOut("odm_dlkm"),
|
||||||
productOut("sysloader"),
|
productOut("sysloader"),
|
||||||
productOut("testcases"),
|
productOut("testcases"),
|
||||||
productOut("symbols"))
|
productOut("symbols"),
|
||||||
|
productOut("install"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since products and build variants (unfortunately) shared the same
|
// Since products and build variants (unfortunately) shared the same
|
||||||
|
|
|
@ -1488,6 +1488,15 @@ func (c *configImpl) SoongVarsFile() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *configImpl) SoongExtraVarsFile() string {
|
||||||
|
targetProduct, err := c.TargetProductOrErr()
|
||||||
|
if err != nil {
|
||||||
|
return filepath.Join(c.SoongOutDir(), "soong.extra.variables")
|
||||||
|
} else {
|
||||||
|
return filepath.Join(c.SoongOutDir(), "soong."+targetProduct+".extra.variables")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *configImpl) SoongNinjaFile() string {
|
func (c *configImpl) SoongNinjaFile() string {
|
||||||
targetProduct, err := c.TargetProductOrErr()
|
targetProduct, err := c.TargetProductOrErr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -147,6 +147,7 @@ func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_
|
||||||
var BannerVars = []string{
|
var BannerVars = []string{
|
||||||
"PLATFORM_VERSION_CODENAME",
|
"PLATFORM_VERSION_CODENAME",
|
||||||
"PLATFORM_VERSION",
|
"PLATFORM_VERSION",
|
||||||
|
"TEQUILA_VERSION",
|
||||||
"PRODUCT_SOURCE_ROOT_DIRS",
|
"PRODUCT_SOURCE_ROOT_DIRS",
|
||||||
"TARGET_PRODUCT",
|
"TARGET_PRODUCT",
|
||||||
"TARGET_BUILD_VARIANT",
|
"TARGET_BUILD_VARIANT",
|
||||||
|
@ -164,6 +165,8 @@ var BannerVars = []string{
|
||||||
"BUILD_ID",
|
"BUILD_ID",
|
||||||
"OUT_DIR",
|
"OUT_DIR",
|
||||||
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
|
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
|
||||||
|
"GMS_MAKEFILE",
|
||||||
|
"PRODUCT_SOONG_NAMESPACES",
|
||||||
}
|
}
|
||||||
|
|
||||||
func Banner(make_vars map[string]string) string {
|
func Banner(make_vars map[string]string) string {
|
||||||
|
@ -242,7 +245,6 @@ func runMakeProductConfig(ctx Context, config Config) {
|
||||||
"HOST_CROSS_ARCH",
|
"HOST_CROSS_ARCH",
|
||||||
"HOST_CROSS_2ND_ARCH",
|
"HOST_CROSS_2ND_ARCH",
|
||||||
"HOST_BUILD_TYPE",
|
"HOST_BUILD_TYPE",
|
||||||
"PRODUCT_SOONG_NAMESPACES",
|
|
||||||
|
|
||||||
"DEFAULT_WARNING_BUILD_MODULE_TYPES",
|
"DEFAULT_WARNING_BUILD_MODULE_TYPES",
|
||||||
"DEFAULT_ERROR_BUILD_MODULE_TYPES",
|
"DEFAULT_ERROR_BUILD_MODULE_TYPES",
|
||||||
|
|
|
@ -228,6 +228,13 @@ func (c *Cmd) wrapSandbox() {
|
||||||
sandboxArgs = append(sandboxArgs, "-N")
|
sandboxArgs = append(sandboxArgs, "-N")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ccacheExec := os.Getenv("CCACHE_EXEC"); ccacheExec != "" {
|
||||||
|
bytes, err := exec.Command(ccacheExec, "-k", "cache_dir").Output()
|
||||||
|
if err == nil {
|
||||||
|
sandboxArgs = append(sandboxArgs, "-B", strings.TrimSpace(string(bytes)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stop nsjail from parsing arguments
|
// Stop nsjail from parsing arguments
|
||||||
sandboxArgs = append(sandboxArgs, "--")
|
sandboxArgs = append(sandboxArgs, "--")
|
||||||
|
|
||||||
|
|
|
@ -694,6 +694,7 @@ func runSoong(ctx Context, config Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
distFile(ctx, config, config.SoongVarsFile(), "soong")
|
distFile(ctx, config, config.SoongVarsFile(), "soong")
|
||||||
|
distFile(ctx, config, config.SoongExtraVarsFile(), "soong")
|
||||||
|
|
||||||
if !config.SkipKati() {
|
if !config.SkipKati() {
|
||||||
distGzipFile(ctx, config, config.SoongAndroidMk(), "soong")
|
distGzipFile(ctx, config, config.SoongAndroidMk(), "soong")
|
||||||
|
|
|
@ -64,7 +64,8 @@ func testForDanglingRules(ctx Context, config Config) {
|
||||||
outDir := config.OutDir()
|
outDir := config.OutDir()
|
||||||
modulePathsDir := filepath.Join(outDir, ".module_paths")
|
modulePathsDir := filepath.Join(outDir, ".module_paths")
|
||||||
rawFilesDir := filepath.Join(outDir, "soong", "raw")
|
rawFilesDir := filepath.Join(outDir, "soong", "raw")
|
||||||
variablesFilePath := filepath.Join(outDir, "soong", "soong.variables")
|
variablesFilePath := config.SoongVarsFile()
|
||||||
|
extraVariablesFilePath := config.SoongExtraVarsFile()
|
||||||
|
|
||||||
// dexpreopt.config is an input to the soong_docs action, which runs the
|
// dexpreopt.config is an input to the soong_docs action, which runs the
|
||||||
// soong_build primary builder. However, this file is created from $(shell)
|
// soong_build primary builder. However, this file is created from $(shell)
|
||||||
|
@ -95,6 +96,7 @@ func testForDanglingRules(ctx Context, config Config) {
|
||||||
if strings.HasPrefix(line, modulePathsDir) ||
|
if strings.HasPrefix(line, modulePathsDir) ||
|
||||||
strings.HasPrefix(line, rawFilesDir) ||
|
strings.HasPrefix(line, rawFilesDir) ||
|
||||||
line == variablesFilePath ||
|
line == variablesFilePath ||
|
||||||
|
line == extraVariablesFilePath ||
|
||||||
line == dexpreoptConfigFilePath ||
|
line == dexpreoptConfigFilePath ||
|
||||||
line == buildDatetimeFilePath ||
|
line == buildDatetimeFilePath ||
|
||||||
line == bpglob ||
|
line == bpglob ||
|
||||||
|
|
Loading…
Reference in a new issue