Add build_prop soong module
build_prop is a soong module generating {partition}/build.prop. It's ported from build/make/core/sysprop.mk and will replace sysprop.mk in the future. Currently used only by Android.bp cuttlefish system image. Bug: 322090587 Bug: 346214958 Test: compare system/build.prop and aosp_cf_x86_64_system-build.prop for eng / user / userdebug Change-Id: Iad76139fe86ec4f582218c185aa15baeacaa38dc
This commit is contained in:
parent
feb21547f9
commit
8cd40a7e3c
8 changed files with 716 additions and 6 deletions
|
@ -122,6 +122,7 @@ dexpreopt_systemserver_check {
|
|||
}
|
||||
|
||||
// buildinfo.prop contains common properties for system/build.prop, like ro.build.version.*
|
||||
// TODO(b/322090587): merge this to gen_build_prop.py script.
|
||||
buildinfo_prop {
|
||||
name: "buildinfo.prop",
|
||||
|
||||
|
@ -141,5 +142,5 @@ all_apex_contributions {
|
|||
|
||||
product_config {
|
||||
name: "product_config",
|
||||
visibility: ["//visibility:private"],
|
||||
visibility: ["//device/google/cuttlefish/system_image"],
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ bootstrap_go_package {
|
|||
"arch_list.go",
|
||||
"arch_module_context.go",
|
||||
"base_module_context.go",
|
||||
"build_prop.go",
|
||||
"buildinfo_prop.go",
|
||||
"config.go",
|
||||
"test_config.go",
|
||||
|
|
125
android/build_prop.go
Normal file
125
android/build_prop.go
Normal file
|
@ -0,0 +1,125 @@
|
|||
// 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
|
||||
|
||||
// Path to the input prop files. The contents of the files are directly
|
||||
// emitted to the output
|
||||
Prop_files []string `android:"path"`
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
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) 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")
|
||||
return
|
||||
}
|
||||
|
||||
partition := p.PartitionTag(ctx.DeviceConfig())
|
||||
if partition != "system" {
|
||||
ctx.PropertyErrorf("partition", "unsupported partition %q: only \"system\" is supported", partition)
|
||||
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.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())
|
||||
postProcessCmd.FlagWithInput("--kernel-version-file-for-uffd-gc ", PathForOutput(ctx, "dexpreopt/kernel_version_for_uffd_gc.txt"))
|
||||
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)
|
||||
ctx.InstallFile(p.installPath, p.stem(), p.outputFilePath)
|
||||
|
||||
ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -91,6 +91,8 @@ func (p *buildinfoPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
|
|||
// 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))
|
||||
// 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())
|
||||
|
|
|
@ -784,6 +784,17 @@ func (c *config) DisplayBuildNumber() bool {
|
|||
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
|
||||
// representing the current build's number.
|
||||
//
|
||||
|
@ -1887,6 +1898,10 @@ func (c *deviceConfig) BuildBrokenDontCheckSystemSdk() bool {
|
|||
return c.config.productVariables.BuildBrokenDontCheckSystemSdk
|
||||
}
|
||||
|
||||
func (c *deviceConfig) BuildBrokenDupSysprop() bool {
|
||||
return c.config.productVariables.BuildBrokenDupSysprop
|
||||
}
|
||||
|
||||
func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string {
|
||||
return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist
|
||||
}
|
||||
|
|
|
@ -210,11 +210,12 @@ type ProductVariables struct {
|
|||
// Suffix to add to generated Makefiles
|
||||
Make_suffix *string `json:",omitempty"`
|
||||
|
||||
BuildId *string `json:",omitempty"`
|
||||
BuildNumberFile *string `json:",omitempty"`
|
||||
BuildHostnameFile *string `json:",omitempty"`
|
||||
BuildThumbprintFile *string `json:",omitempty"`
|
||||
DisplayBuildNumber *bool `json:",omitempty"`
|
||||
BuildId *string `json:",omitempty"`
|
||||
BuildFingerprintFile *string `json:",omitempty"`
|
||||
BuildNumberFile *string `json:",omitempty"`
|
||||
BuildHostnameFile *string `json:",omitempty"`
|
||||
BuildThumbprintFile *string `json:",omitempty"`
|
||||
DisplayBuildNumber *bool `json:",omitempty"`
|
||||
|
||||
Platform_display_version_name *string `json:",omitempty"`
|
||||
Platform_version_name *string `json:",omitempty"`
|
||||
|
@ -473,6 +474,7 @@ type ProductVariables struct {
|
|||
BuildBrokenIncorrectPartitionImages bool `json:",omitempty"`
|
||||
BuildBrokenInputDirModules []string `json:",omitempty"`
|
||||
BuildBrokenDontCheckSystemSdk bool `json:",omitempty"`
|
||||
BuildBrokenDupSysprop bool `json:",omitempty"`
|
||||
|
||||
BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
|
||||
|
||||
|
|
|
@ -299,6 +299,12 @@ python_binary_host {
|
|||
],
|
||||
}
|
||||
|
||||
python_binary_host {
|
||||
name: "gen_build_prop",
|
||||
main: "gen_build_prop.py",
|
||||
srcs: ["gen_build_prop.py"],
|
||||
}
|
||||
|
||||
python_binary_host {
|
||||
name: "buildinfo",
|
||||
main: "buildinfo.py",
|
||||
|
|
558
scripts/gen_build_prop.py
Normal file
558
scripts/gen_build_prop.py
Normal file
|
@ -0,0 +1,558 @@
|
|||
#!/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 subprocess
|
||||
import sys
|
||||
|
||||
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 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
|
||||
config["BuildVersionTags"] = config["BuildKeys"]
|
||||
if config["BuildType"] == "debug":
|
||||
config["BuildVersionTags"] = "debug," + config["BuildVersionTags"]
|
||||
|
||||
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()
|
||||
|
||||
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["ModelForAttestation"]:
|
||||
print(f"ro.product.model_for_attestation={config['ModelForAttestation']}")
|
||||
if config["BrandForAttestation"]:
|
||||
print(f"ro.product.brand_for_attestation={config['BrandForAttestation']}")
|
||||
if config["NameForAttestation"]:
|
||||
print(f"ro.product.name_for_attestation={config['NameForAttestation']}")
|
||||
if config["DeviceForAttestation"]:
|
||||
print(f"ro.product.device_for_attestation={config['DeviceForAttestation']}")
|
||||
if config["ManufacturerForAttestation"]:
|
||||
print(f"ro.product.manufacturer_for_attestation={config['ManufacturerForAttestation']}")
|
||||
|
||||
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"]
|
||||
|
||||
# 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['BuildDesc']}")
|
||||
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']}")
|
||||
|
||||
# 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 "build_thumbprint" 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 config["PropertySplitEnabled"] or 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
|
||||
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
|
||||
|
||||
# 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_target_debugging:
|
||||
# Enable Dalvik lock contention logging.
|
||||
props.append("dalvik.vm.lockprof.threshold=500")
|
||||
|
||||
# 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["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['ProductShippingApiLevel']}")
|
||||
|
||||
# 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.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")
|
||||
|
||||
# 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_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",
|
||||
]
|
||||
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):
|
||||
if args.partition == "system":
|
||||
build_system_prop(args)
|
||||
'''
|
||||
elif args.partition == "vendor":
|
||||
build_vendor_prop(args)
|
||||
elif args.partition == "product":
|
||||
build_product_prop(args)
|
||||
'''
|
||||
else:
|
||||
sys.exit(f"not supported partition {args.partition}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in a new issue