Merge "Only coverage instrument device modules that are being compiled to dex" into main
diff --git a/Android.bp b/Android.bp
index 9763622..434ee9f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -172,6 +172,9 @@
name: "system-build.prop",
stem: "build.prop",
product_config: ":product_config",
+ footer_files: [
+ ":applied_backported_fixes",
+ ],
// Currently, only microdroid, Ravenwood, and cf system image can refer to system-build.prop
visibility: [
"//build/make/target/product/generic",
@@ -234,3 +237,12 @@
relative_install_path: "etc", // odm_dlkm/etc/build.prop
visibility: ["//visibility:private"],
}
+
+build_prop {
+ name: "ramdisk-build.prop",
+ stem: "build.prop",
+ ramdisk: true,
+ product_config: ":product_config",
+ relative_install_path: "etc/ramdisk", // ramdisk/system/etc/ramdisk/build.prop
+ visibility: ["//visibility:private"],
+}
diff --git a/aconfig/build_flags/build_flags.go b/aconfig/build_flags/build_flags.go
index e878b5a..94e1eb1 100644
--- a/aconfig/build_flags/build_flags.go
+++ b/aconfig/build_flags/build_flags.go
@@ -35,7 +35,7 @@
type buildFlags struct {
android.ModuleBase
- outputPath android.OutputPath
+ outputPath android.Path
}
func buildFlagsFactory() android.Module {
@@ -48,7 +48,7 @@
// Read the build_flags_<partition>.json file generated by soong
// 'release-config' command.
srcPath := android.PathForOutput(ctx, "release-config", fmt.Sprintf("build_flags_%s.json", m.PartitionTag(ctx.DeviceConfig())))
- m.outputPath = android.PathForModuleOut(ctx, outJsonFileName).OutputPath
+ outputPath := android.PathForModuleOut(ctx, outJsonFileName)
// The 'release-config' command is called for every build, and generates the
// build_flags_<partition>.json file.
@@ -56,11 +56,12 @@
ctx.Build(pctx, android.BuildParams{
Rule: android.CpIfChanged,
Input: srcPath,
- Output: m.outputPath,
+ Output: outputPath,
})
installPath := android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(installPath, outJsonFileName, m.outputPath)
+ ctx.InstallFile(installPath, outJsonFileName, outputPath)
+ m.outputPath = outputPath
}
func (m *buildFlags) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/android/apex.go b/android/apex.go
index d303183..1bfcf04 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -869,8 +869,8 @@
type DepNameToDepInfoMap map[string]ApexModuleDepInfo
type ApexBundleDepsInfo struct {
- flatListPath OutputPath
- fullListPath OutputPath
+ flatListPath Path
+ fullListPath Path
}
type ApexBundleDepsInfoIntf interface {
@@ -907,13 +907,15 @@
fmt.Fprintf(&flatContent, "%s\n", toName)
}
- d.fullListPath = PathForModuleOut(ctx, "depsinfo", "fulllist.txt").OutputPath
- WriteFileRule(ctx, d.fullListPath, fullContent.String())
+ fullListPath := PathForModuleOut(ctx, "depsinfo", "fulllist.txt")
+ WriteFileRule(ctx, fullListPath, fullContent.String())
+ d.fullListPath = fullListPath
- d.flatListPath = PathForModuleOut(ctx, "depsinfo", "flatlist.txt").OutputPath
- WriteFileRule(ctx, d.flatListPath, flatContent.String())
+ flatListPath := PathForModuleOut(ctx, "depsinfo", "flatlist.txt")
+ WriteFileRule(ctx, flatListPath, flatContent.String())
+ d.flatListPath = flatListPath
- ctx.Phony(fmt.Sprintf("%s-depsinfo", ctx.ModuleName()), d.fullListPath, d.flatListPath)
+ ctx.Phony(fmt.Sprintf("%s-depsinfo", ctx.ModuleName()), fullListPath, flatListPath)
}
// Function called while walking an APEX's payload dependencies.
diff --git a/android/base_module_context.go b/android/base_module_context.go
index ab28676..1f89dea 100644
--- a/android/base_module_context.go
+++ b/android/base_module_context.go
@@ -211,6 +211,12 @@
// data modified by the current mutator.
VisitAllModuleVariants(visit func(Module))
+ // VisitAllModuleVariantProxies calls visit for each variant of the current module. Variants of a module are always
+ // visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
+ // from all variants if the current module is the last one. Otherwise, care must be taken to not access any
+ // data modified by the current mutator.
+ VisitAllModuleVariantProxies(visit func(proxy ModuleProxy))
+
// GetTagPath is supposed to be called in visit function passed in WalkDeps()
// and returns a top-down dependency tags path from a start module to current child module.
// It has one less entry than GetWalkPath() as it contains the dependency tags that
@@ -382,7 +388,7 @@
return &aModule
}
- if !OtherModuleProviderOrDefault(b, module, CommonPropertiesProviderKey).Enabled {
+ if !OtherModuleProviderOrDefault(b, module, CommonModuleInfoKey).Enabled {
if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependencyProxy(b, aModule) {
if b.Config().AllowMissingDependencies() {
b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
@@ -594,6 +600,10 @@
})
}
+func (b *baseModuleContext) VisitAllModuleVariantProxies(visit func(ModuleProxy)) {
+ b.bp.VisitAllModuleVariantProxies(visitProxyAdaptor(visit))
+}
+
func (b *baseModuleContext) PrimaryModule() Module {
return b.bp.PrimaryModule().(Module)
}
diff --git a/android/build_prop.go b/android/build_prop.go
index 8389470..2f71bc0 100644
--- a/android/build_prop.go
+++ b/android/build_prop.go
@@ -15,6 +15,8 @@
package android
import (
+ "fmt"
+
"github.com/google/blueprint/proptools"
)
@@ -55,7 +57,7 @@
properties buildPropProperties
- outputFilePath OutputPath
+ outputFilePath Path
installPath InstallPath
}
@@ -115,33 +117,22 @@
return "vendor_dlkm"
} else if p.InstallInOdmDlkm() {
return "odm_dlkm"
+ } else if p.InstallInRamdisk() {
+ // From this hardcoding in make:
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/sysprop.mk;l=311;drc=274435657e4682e5cee3fffd11fb301ab32a828d
+ return "bootimage"
}
return "system"
}
-var validPartitions = []string{
- "system",
- "system_ext",
- "product",
- "odm",
- "vendor",
- "system_dlkm",
- "vendor_dlkm",
- "odm_dlkm",
-}
-
func (p *buildPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
if !p.SocSpecific() && p.properties.Android_info != nil {
ctx.ModuleErrorf("Android_info cannot be set if build.prop is not installed in vendor partition")
}
- p.outputFilePath = PathForModuleOut(ctx, "build.prop").OutputPath
+ outputFilePath := PathForModuleOut(ctx, "build.prop")
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)
@@ -168,7 +159,7 @@
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)
+ cmd.FlagWithOutput("--out=", outputFilePath)
postProcessCmd := rule.Command().BuiltTool("post_process_props")
if ctx.DeviceConfig().BuildBrokenDupSysprop() {
@@ -181,17 +172,35 @@
// 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.Text(outputFilePath.String())
postProcessCmd.Flags(p.properties.Block_list)
- rule.Command().Text("echo").Text(proptools.NinjaAndShellEscape("# end of file")).FlagWithArg(">> ", p.outputFilePath.String())
+ for _, footer := range p.properties.Footer_files {
+ path := PathForModuleSrc(ctx, footer)
+ rule.appendText(outputFilePath, "####################################")
+ rule.appendTextf(outputFilePath, "# Adding footer from %v", footer)
+ rule.appendTextf(outputFilePath, "# with path %v", path)
+ rule.appendText(outputFilePath, "####################################")
+ rule.Command().Text("cat").FlagWithInput("", path).FlagWithArg(">> ", outputFilePath.String())
+ }
+
+ rule.appendText(outputFilePath, "# end of file")
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.InstallFile(p.installPath, p.stem(), outputFilePath)
- ctx.SetOutputFiles(Paths{p.outputFilePath}, "")
+ ctx.SetOutputFiles(Paths{outputFilePath}, "")
+ p.outputFilePath = outputFilePath
+}
+
+func (r *RuleBuilder) appendText(path ModuleOutPath, text string) {
+ r.Command().Text("echo").Text(proptools.NinjaAndShellEscape(text)).FlagWithArg(">> ", path.String())
+}
+
+func (r *RuleBuilder) appendTextf(path ModuleOutPath, format string, a ...any) {
+ r.appendText(path, fmt.Sprintf(format, a...))
}
func (p *buildPropModule) AndroidMkEntries() []AndroidMkEntries {
diff --git a/android/csuite_config.go b/android/csuite_config.go
index 20bd035..26ad6e1 100644
--- a/android/csuite_config.go
+++ b/android/csuite_config.go
@@ -30,11 +30,11 @@
type CSuiteConfig struct {
ModuleBase
properties csuiteConfigProperties
- OutputFilePath OutputPath
+ OutputFilePath Path
}
func (me *CSuiteConfig) GenerateAndroidBuildActions(ctx ModuleContext) {
- me.OutputFilePath = PathForModuleOut(ctx, me.BaseModuleName()).OutputPath
+ me.OutputFilePath = PathForModuleOut(ctx, me.BaseModuleName())
}
func (me *CSuiteConfig) AndroidMkEntries() []AndroidMkEntries {
diff --git a/android/module.go b/android/module.go
index 4314357..ce995ad 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1643,25 +1643,27 @@
func (m *ModuleBase) generateModuleTarget(ctx *moduleContext) {
var allInstalledFiles InstallPaths
var allCheckbuildTargets Paths
- ctx.VisitAllModuleVariants(func(module Module) {
- a := module.base()
+ ctx.VisitAllModuleVariantProxies(func(module ModuleProxy) {
var checkbuildTarget Path
var uncheckedModule bool
- if a == m {
+ var skipAndroidMkProcessing bool
+ if ctx.EqualModules(m.module, module) {
allInstalledFiles = append(allInstalledFiles, ctx.installFiles...)
checkbuildTarget = ctx.checkbuildTarget
uncheckedModule = ctx.uncheckedModule
+ skipAndroidMkProcessing = shouldSkipAndroidMkProcessing(ctx, m)
} else {
info := OtherModuleProviderOrDefault(ctx, module, InstallFilesProvider)
allInstalledFiles = append(allInstalledFiles, info.InstallFiles...)
checkbuildTarget = info.CheckbuildTarget
uncheckedModule = info.UncheckedModule
+ skipAndroidMkProcessing = OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).SkipAndroidMkProcessing
}
// A module's -checkbuild phony targets should
// not be created if the module is not exported to make.
// Those could depend on the build target and fail to compile
// for the current build target.
- if (!ctx.Config().KatiEnabled() || !shouldSkipAndroidMkProcessing(ctx, a)) && !uncheckedModule && checkbuildTarget != nil {
+ if (!ctx.Config().KatiEnabled() || !skipAndroidMkProcessing) && !uncheckedModule && checkbuildTarget != nil {
allCheckbuildTargets = append(allCheckbuildTargets, checkbuildTarget)
}
})
@@ -1850,15 +1852,16 @@
var FinalModuleBuildTargetsProvider = blueprint.NewProvider[FinalModuleBuildTargetsInfo]()
-type CommonPropertiesProviderData struct {
+type CommonModuleInfo struct {
Enabled bool
// Whether the module has been replaced by a prebuilt
ReplacedByPrebuilt bool
// The Target of artifacts that this module variant is responsible for creating.
- CompileTarget Target
+ CompileTarget Target
+ SkipAndroidMkProcessing bool
}
-var CommonPropertiesProviderKey = blueprint.NewProvider[CommonPropertiesProviderData]()
+var CommonModuleInfoKey = blueprint.NewProvider[CommonModuleInfo]()
type PrebuiltModuleProviderData struct {
// Empty for now
@@ -2120,16 +2123,17 @@
}
buildComplianceMetadataProvider(ctx, m)
- commonData := CommonPropertiesProviderData{
- ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
- CompileTarget: m.commonProperties.CompileTarget,
+ commonData := CommonModuleInfo{
+ ReplacedByPrebuilt: m.commonProperties.ReplacedByPrebuilt,
+ CompileTarget: m.commonProperties.CompileTarget,
+ SkipAndroidMkProcessing: shouldSkipAndroidMkProcessing(ctx, m),
}
if m.commonProperties.ForcedDisabled {
commonData.Enabled = false
} else {
commonData.Enabled = m.commonProperties.Enabled.GetOrDefault(m.ConfigurableEvaluator(ctx), !m.Os().DefaultDisabled)
}
- SetProvider(ctx, CommonPropertiesProviderKey, commonData)
+ SetProvider(ctx, CommonModuleInfoKey, commonData)
if p, ok := m.module.(PrebuiltInterface); ok && p.Prebuilt() != nil {
SetProvider(ctx, PrebuiltModuleProviderKey, PrebuiltModuleProviderData{})
}
@@ -2138,7 +2142,7 @@
HostToolPath: h.HostToolPath()})
}
- if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !shouldSkipAndroidMkProcessing(ctx, m) {
+ if p, ok := m.module.(AndroidMkProviderInfoProducer); ok && !commonData.SkipAndroidMkProcessing {
SetProvider(ctx, AndroidMkInfoProvider, p.PrepareAndroidMKProviderInfo(ctx.Config()))
}
}
diff --git a/android/packaging.go b/android/packaging.go
index e71d983..dcd8844 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -410,9 +410,9 @@
return true
}
-// highPriorityDepTag provides default implementation of HighPriorityPackagingItem interface.
type highPriorityDepTag struct {
- blueprint.DependencyTag
+ blueprint.BaseDependencyTag
+ PackagingItemAlwaysDepTag
}
// See PackageModule.AddDeps
@@ -433,7 +433,7 @@
}
depTagToUse := depTag
if highPriority {
- depTagToUse = highPriorityDepTag{depTag}
+ depTagToUse = highPriorityDepTag{}
}
ctx.AddFarVariationDependencies(targetVariation, depTagToUse, dep)
diff --git a/android/paths.go b/android/paths.go
index 8f066cc..7ab1f22 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -675,7 +675,7 @@
if module == nil {
return nil, missingDependencyError{[]string{moduleName}}
}
- if !OtherModuleProviderOrDefault(ctx, *module, CommonPropertiesProviderKey).Enabled {
+ if !OtherModuleProviderOrDefault(ctx, *module, CommonModuleInfoKey).Enabled {
return nil, missingDependencyError{[]string{moduleName}}
}
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 51e72af..0ac67b3 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -381,7 +381,7 @@
// the right module. This function is only safe to call after all TransitionMutators
// have run, e.g. in GenerateAndroidBuildActions.
func PrebuiltGetPreferred(ctx BaseModuleContext, module Module) Module {
- if !OtherModuleProviderOrDefault(ctx, module, CommonPropertiesProviderKey).ReplacedByPrebuilt {
+ if !OtherModuleProviderOrDefault(ctx, module, CommonModuleInfoKey).ReplacedByPrebuilt {
return module
}
if _, ok := OtherModuleProvider(ctx, module, PrebuiltModuleProviderKey); ok {
diff --git a/android/product_config.go b/android/product_config.go
index ce3acc9..850f003 100644
--- a/android/product_config.go
+++ b/android/product_config.go
@@ -32,7 +32,7 @@
ctx.ModuleErrorf("There can only be one product_config module in build/soong")
return
}
- outputFilePath := PathForModuleOut(ctx, p.Name()+".json").OutputPath
+ outputFilePath := PathForModuleOut(ctx, p.Name()+".json")
// DeviceProduct can be null so calling ctx.Config().DeviceProduct() may cause null dereference
targetProduct := proptools.String(ctx.Config().config.productVariables.DeviceProduct)
diff --git a/android/vintf_data.go b/android/vintf_data.go
index 7823397..401f4d2 100644
--- a/android/vintf_data.go
+++ b/android/vintf_data.go
@@ -49,7 +49,7 @@
properties vintfDataProperties
installDirPath InstallPath
- outputFilePath OutputPath
+ outputFilePath Path
noAction bool
}
@@ -148,7 +148,7 @@
builder.Build("assemble_vintf", "Process vintf data "+gensrc.String())
m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf")
- m.outputFilePath = gensrc.OutputPath
+ m.outputFilePath = gensrc
installFileName := "manifest.xml"
if filename := proptools.String(m.properties.Filename); filename != "" {
diff --git a/android/vintf_fragment.go b/android/vintf_fragment.go
index 42eaaf0..a3343fd 100644
--- a/android/vintf_fragment.go
+++ b/android/vintf_fragment.go
@@ -25,7 +25,7 @@
properties vintfFragmentProperties
installDirPath InstallPath
- outputFilePath OutputPath
+ outputFilePath Path
}
func init() {
@@ -64,7 +64,7 @@
builder.Build("assemble_vintf", "Process vintf fragment "+processedVintfFragment.String())
m.installDirPath = PathForModuleInstall(ctx, "etc", "vintf", "manifest")
- m.outputFilePath = processedVintfFragment.OutputPath
+ m.outputFilePath = processedVintfFragment
ctx.InstallFile(m.installDirPath, processedVintfFragment.Base(), processedVintfFragment)
}
diff --git a/apex/apex.go b/apex/apex.go
index e0195d3..dc24df3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -511,7 +511,7 @@
// Text file having the list of individual files that are included in this APEX. Used for
// debugging purpose.
- installedFilesFile android.WritablePath
+ installedFilesFile android.Path
// List of module names that this APEX is including (to be shown via *-deps-info target).
// Used for debugging purpose.
diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go
index 00dd446..d46104e 100644
--- a/apex/apex_singleton.go
+++ b/apex/apex_singleton.go
@@ -64,12 +64,14 @@
if grep -v -h '^#' ${allowed_deps_list} | sort -u -f| diff -B -u - ${new_allowed_deps}; then
touch ${out};
else
- echo -e "\n******************************";
+ echo;
+ echo "******************************";
echo "ERROR: go/apex-allowed-deps-error contains more information";
echo "******************************";
echo "Detected changes to allowed dependencies in updatable modules.";
echo "To fix and update packages/modules/common/build/allowed_deps.txt, please run:";
- echo -e "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)\n";
+ echo "$$ (croot && packages/modules/common/build/update-apex-allowed-deps.sh)";
+ echo;
echo "When submitting the generated CL, you must include the following information";
echo "in the commit message if you are adding a new dependency:";
echo "Apex-Size-Increase: Expected binary size increase for affected APEXes (or the size of the .jar / .so file of the new library)";
@@ -78,7 +80,8 @@
echo "Test-Info: What’s the testing strategy for the new dependency? Does it have its own tests, and are you adding integration tests? How/when are the tests run?";
echo "You do not need OWNERS approval to submit the change, but mainline-modularization@";
echo "will periodically review additions and may require changes.";
- echo -e "******************************\n";
+ echo "******************************";
+ echo;
exit 1;
fi;
`,
diff --git a/apex/builder.go b/apex/builder.go
index b04a9d7..d0acc8d 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -196,7 +196,7 @@
Command: `diff --unchanged-group-format='' \` +
`--changed-group-format='%<' \` +
`${image_content_file} ${allowed_files_file} || (` +
- `echo -e "New unexpected files were added to ${apex_module_name}." ` +
+ `echo "New unexpected files were added to ${apex_module_name}." ` +
` "To fix the build run following command:" && ` +
`echo "system/apex/tools/update_allowed_list.sh ${allowed_files_file} ${image_content_file}" && ` +
`exit 1); touch ${out}`,
@@ -388,7 +388,7 @@
// file for this APEX which is either from /systme/sepolicy/apex/<apexname>-file_contexts or from
// the file_contexts property of this APEX. This is to make sure that the manifest file is correctly
// labeled as system_file or vendor_apex_metadata_file.
-func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.OutputPath {
+func (a *apexBundle) buildFileContexts(ctx android.ModuleContext) android.Path {
var fileContexts android.Path
var fileContextsDir string
isFileContextsModule := false
@@ -443,13 +443,13 @@
}
rule.Build("file_contexts."+a.Name(), "Generate file_contexts")
- return output.OutputPath
+ return output
}
// buildInstalledFilesFile creates a build rule for the installed-files.txt file where the list of
// files included in this APEX is shown. The text file is dist'ed so that people can see what's
// included in the APEX without actually downloading and extracting it.
-func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
+func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.Path {
output := android.PathForModuleOut(ctx, "installed-files.txt")
rule := android.NewRuleBuilder(pctx, ctx)
rule.Command().
@@ -459,12 +459,12 @@
Text(" | sort -nr > ").
Output(output)
rule.Build("installed-files."+a.Name(), "Installed files")
- return output.OutputPath
+ return output
}
// buildBundleConfig creates a build rule for the bundle config file that will control the bundle
// creation process.
-func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.OutputPath {
+func (a *apexBundle) buildBundleConfig(ctx android.ModuleContext) android.Path {
output := android.PathForModuleOut(ctx, "bundle_config.json")
type ApkConfig struct {
@@ -509,7 +509,7 @@
android.WriteFileRule(ctx, output, string(j))
- return output.OutputPath
+ return output
}
func markManifestTestOnly(ctx android.ModuleContext, androidManifestFile android.Path) android.Path {
@@ -922,17 +922,17 @@
args["outCommaList"] = signedOutputFile.String()
}
var validations android.Paths
- validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath))
+ validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile, imageDir))
// TODO(b/279688635) deapexer supports [ext4]
if !a.testApex && suffix == imageApexSuffix && ext4 == a.payloadFsType {
- validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath))
+ validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile))
}
if !a.testApex && len(a.properties.Unwanted_transitive_deps) > 0 {
validations = append(validations,
- runApexElfCheckerUnwanted(ctx, unsignedOutputFile.OutputPath, a.properties.Unwanted_transitive_deps))
+ runApexElfCheckerUnwanted(ctx, unsignedOutputFile, a.properties.Unwanted_transitive_deps))
}
if !a.testApex && android.InList(a.payloadFsType, []fsType{ext4, erofs}) {
- validations = append(validations, runApexHostVerifier(ctx, a, unsignedOutputFile.OutputPath))
+ validations = append(validations, runApexHostVerifier(ctx, a, unsignedOutputFile))
}
ctx.Build(pctx, android.BuildParams{
Rule: rule,
@@ -1135,7 +1135,7 @@
a.lintReports = java.BuildModuleLintReportZips(ctx, depSets, validations)
}
-func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
+func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.Path {
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
var appSetDirs []string
@@ -1199,10 +1199,10 @@
cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))
- return cannedFsConfig.OutputPath
+ return cannedFsConfig
}
-func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path {
+func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.Path, imageDir android.Path) android.Path {
timestamp := android.PathForModuleOut(ctx, "apex_linkerconfig_validation.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexLinkerconfigValidationRule,
@@ -1219,7 +1219,7 @@
//
// $ deapexer list -Z {apex_file} > {file_contexts}
// $ apex_sepolicy_tests -f {file_contexts}
-func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.OutputPath) android.Path {
+func runApexSepolicyTests(ctx android.ModuleContext, apexFile android.Path) android.Path {
timestamp := android.PathForModuleOut(ctx, "sepolicy_tests.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexSepolicyTestsRule,
@@ -1229,7 +1229,7 @@
return timestamp
}
-func runApexElfCheckerUnwanted(ctx android.ModuleContext, apexFile android.OutputPath, unwanted []string) android.Path {
+func runApexElfCheckerUnwanted(ctx android.ModuleContext, apexFile android.Path, unwanted []string) android.Path {
timestamp := android.PathForModuleOut(ctx, "apex_elf_unwanted.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexElfCheckerUnwantedRule,
@@ -1243,7 +1243,7 @@
return timestamp
}
-func runApexHostVerifier(ctx android.ModuleContext, a *apexBundle, apexFile android.OutputPath) android.Path {
+func runApexHostVerifier(ctx android.ModuleContext, a *apexBundle, apexFile android.Path) android.Path {
timestamp := android.PathForModuleOut(ctx, "host_apex_verifier.timestamp")
ctx.Build(pctx, android.BuildParams{
Rule: apexHostVerifierRule,
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 9cd5688..acf3b91 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -386,7 +386,7 @@
inputApex android.Path
- provenanceMetaDataFile android.OutputPath
+ provenanceMetaDataFile android.Path
}
type ApexFileProperties struct {
@@ -697,7 +697,7 @@
ctx.SetOutputFiles(android.Paths{p.outputApex}, "")
}
-func (p *Prebuilt) ProvenanceMetaDataFile() android.OutputPath {
+func (p *Prebuilt) ProvenanceMetaDataFile() android.Path {
return p.provenanceMetaDataFile
}
diff --git a/cc/cmake_snapshot.go b/cc/cmake_snapshot.go
index 790a865..f553f27 100644
--- a/cc/cmake_snapshot.go
+++ b/cc/cmake_snapshot.go
@@ -484,7 +484,7 @@
// Packaging all make files into the zip file
makefilesRspFile := android.PathForModuleObj(ctx, ctx.ModuleName()+"_makefiles.rsp")
zipCmd.
- FlagWithArg("-C ", android.PathForModuleGen(ctx).OutputPath.String()).
+ FlagWithArg("-C ", android.PathForModuleGen(ctx).String()).
FlagWithRspFileInputList("-r ", makefilesRspFile, makefilesList)
// Packaging all prebuilts into the zip file
diff --git a/cc/config/global.go b/cc/config/global.go
index 36690d6..6984ea4 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -290,8 +290,6 @@
"-Wno-error=deprecated", // in external/googletest/googletest
// Disabling until the warning is fixed in libc++abi header files b/366180429
"-Wno-deprecated-dynamic-exception-spec",
- // New warnings to be fixed after clang-r475365
- "-Wno-error=enum-constexpr-conversion", // http://b/243964282
// New warnings to be fixed after clang-r522817
"-Wno-error=invalid-offsetof",
"-Wno-error=thread-safety-reference-return",
diff --git a/cc/image.go b/cc/image.go
index ee40483..9766af3 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -179,9 +179,6 @@
// SnapshotVersion returns the snapshot version for this module.
SnapshotVersion(mctx android.ImageInterfaceContext) string
- // SdkVersion returns the SDK version for this module.
- SdkVersion() string
-
// ExtraVariants returns the list of extra variants this module requires.
ExtraVariants() []string
@@ -370,7 +367,7 @@
if m.HasProductVariant() {
productVariantNeeded = true
}
- } else if vendorSpecific && m.SdkVersion() == "" {
+ } else if vendorSpecific {
// This will be available in /vendor (or /odm) only
vendorVariantNeeded = true
} else {
@@ -380,7 +377,7 @@
coreVariantNeeded = true
}
- if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
+ if coreVariantNeeded && productSpecific {
// The module has "product_specific: true" that does not create core variant.
coreVariantNeeded = false
productVariantNeeded = true
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 124dda4..f0d7343 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1813,7 +1813,7 @@
type sanitizerLibrariesTxtModule struct {
android.ModuleBase
- outputFile android.OutputPath
+ outputFile android.Path
}
var _ etc.PrebuiltEtcModule = (*sanitizerLibrariesTxtModule)(nil)
@@ -1896,13 +1896,14 @@
func (txt *sanitizerLibrariesTxtModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
filename := txt.Name()
- txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath
- android.WriteFileRule(ctx, txt.outputFile, txt.getSanitizerLibs(ctx))
+ outputFile := android.PathForModuleOut(ctx, filename)
+ android.WriteFileRule(ctx, outputFile, txt.getSanitizerLibs(ctx))
installPath := android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(installPath, filename, txt.outputFile)
+ ctx.InstallFile(installPath, filename, outputFile)
- ctx.SetOutputFiles(android.Paths{txt.outputFile}, "")
+ ctx.SetOutputFiles(android.Paths{outputFile}, "")
+ txt.outputFile = outputFile
}
func (txt *sanitizerLibrariesTxtModule) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo {
diff --git a/cc/tidy.go b/cc/tidy.go
index 5cbf8f0..6481b95 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -220,7 +220,7 @@
// (1) Collect all obj/tidy files into OS-specific groups.
ctx.VisitAllModuleVariantProxies(module, func(variant android.ModuleProxy) {
- osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonPropertiesProviderKey).CompileTarget.Os.Name
+ osName := android.OtherModuleProviderOrDefault(ctx, variant, android.CommonModuleInfoKey).CompileTarget.Os.Name
info := android.OtherModuleProviderOrDefault(ctx, variant, CcObjectInfoProvider)
addToOSGroup(osName, info.objFiles, allObjFileGroups, subsetObjFileGroups)
addToOSGroup(osName, info.tidyFiles, allTidyFileGroups, subsetTidyFileGroups)
diff --git a/cmd/find_input_delta/find_input_delta/main.go b/cmd/find_input_delta/find_input_delta/main.go
index 6b657ea..a864584 100644
--- a/cmd/find_input_delta/find_input_delta/main.go
+++ b/cmd/find_input_delta/find_input_delta/main.go
@@ -85,4 +85,11 @@
if err = file_list.Format(os.Stdout, template); err != nil {
panic(err)
}
+
+ metrics_file := os.Getenv("SOONG_METRICS_AGGREGATION_FILE")
+ if metrics_file != "" {
+ if err = file_list.SendMetrics(metrics_file); err != nil {
+ panic(err)
+ }
+ }
}
diff --git a/cmd/find_input_delta/find_input_delta_lib/Android.bp b/cmd/find_input_delta/find_input_delta_lib/Android.bp
index 95bdba8..ef9c65b 100644
--- a/cmd/find_input_delta/find_input_delta_lib/Android.bp
+++ b/cmd/find_input_delta/find_input_delta_lib/Android.bp
@@ -25,6 +25,7 @@
"golang-protobuf-runtime-protoimpl",
"soong-cmd-find_input_delta-proto",
"soong-cmd-find_input_delta-proto_internal",
+ "android-archive-zip",
"blueprint-pathtools",
],
srcs: [
diff --git a/cmd/find_input_delta/find_input_delta_lib/file_list.go b/cmd/find_input_delta/find_input_delta_lib/file_list.go
index 23337ad..01242a0 100644
--- a/cmd/find_input_delta/find_input_delta_lib/file_list.go
+++ b/cmd/find_input_delta/find_input_delta_lib/file_list.go
@@ -15,10 +15,15 @@
package find_input_delta_lib
import (
+ "fmt"
"io"
+ "os"
+ "path/filepath"
+ "slices"
"text/template"
fid_exp "android/soong/cmd/find_input_delta/find_input_delta_proto"
+ "google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/proto"
)
@@ -47,28 +52,148 @@
// The modified files
Changes []FileList
+
+ // Map of file_extension:counts
+ ExtCountMap map[string]*FileCounts
+
+ // Total number of added/changed/deleted files.
+ TotalDelta uint32
}
-func (fl FileList) Marshal() (*fid_exp.FileList, error) {
+// The maximum number of files that will be recorded by name.
+var MaxFilesRecorded uint32 = 50
+
+type FileCounts struct {
+ Additions uint32
+ Deletions uint32
+ Changes uint32
+}
+
+func FileListFactory(name string) *FileList {
+ return &FileList{
+ Name: name,
+ ExtCountMap: make(map[string]*FileCounts),
+ }
+}
+
+func (fl *FileList) addFile(name string) {
+ fl.Additions = append(fl.Additions, name)
+ fl.TotalDelta += 1
+ ext := filepath.Ext(name)
+ if _, ok := fl.ExtCountMap[ext]; !ok {
+ fl.ExtCountMap[ext] = &FileCounts{}
+ }
+ fl.ExtCountMap[ext].Additions += 1
+}
+
+func (fl *FileList) deleteFile(name string) {
+ fl.Deletions = append(fl.Deletions, name)
+ fl.TotalDelta += 1
+ ext := filepath.Ext(name)
+ if _, ok := fl.ExtCountMap[ext]; !ok {
+ fl.ExtCountMap[ext] = &FileCounts{}
+ }
+ fl.ExtCountMap[ext].Deletions += 1
+}
+
+func (fl *FileList) changeFile(name string, ch *FileList) {
+ fl.Changes = append(fl.Changes, *ch)
+ fl.TotalDelta += 1
+ ext := filepath.Ext(name)
+ if _, ok := fl.ExtCountMap[ext]; !ok {
+ fl.ExtCountMap[ext] = &FileCounts{}
+ }
+ fl.ExtCountMap[ext].Changes += 1
+}
+
+func (fl FileList) ToProto() (*fid_exp.FileList, error) {
+ var count uint32
+ return fl.toProto(&count)
+}
+
+func (fl FileList) toProto(count *uint32) (*fid_exp.FileList, error) {
ret := &fid_exp.FileList{
Name: proto.String(fl.Name),
}
- if len(fl.Additions) > 0 {
- ret.Additions = fl.Additions
+ for _, a := range fl.Additions {
+ if *count >= MaxFilesRecorded {
+ break
+ }
+ ret.Additions = append(ret.Additions, a)
+ *count += 1
}
for _, ch := range fl.Changes {
- change, err := ch.Marshal()
- if err != nil {
- return nil, err
+ if *count >= MaxFilesRecorded {
+ break
+ } else {
+ // Pre-increment to limit what the call adds.
+ *count += 1
+ change, err := ch.toProto(count)
+ if err != nil {
+ return nil, err
+ }
+ ret.Changes = append(ret.Changes, change)
}
- ret.Changes = append(ret.Changes, change)
}
- if len(fl.Deletions) > 0 {
- ret.Deletions = fl.Deletions
+ for _, d := range fl.Deletions {
+ if *count >= MaxFilesRecorded {
+ break
+ }
+ ret.Deletions = append(ret.Deletions, d)
+ }
+ ret.TotalDelta = proto.Uint32(*count)
+ exts := []string{}
+ for k := range fl.ExtCountMap {
+ exts = append(exts, k)
+ }
+ slices.Sort(exts)
+ for _, k := range exts {
+ v := fl.ExtCountMap[k]
+ ret.Counts = append(ret.Counts, &fid_exp.FileCount{
+ Extension: proto.String(k),
+ Additions: proto.Uint32(v.Additions),
+ Deletions: proto.Uint32(v.Deletions),
+ Modifications: proto.Uint32(v.Changes),
+ })
}
return ret, nil
}
+func (fl FileList) SendMetrics(path string) error {
+ if path == "" {
+ return fmt.Errorf("No path given")
+ }
+ message, err := fl.ToProto()
+ if err != nil {
+ return err
+ }
+
+ // Marshal the message wrapped in SoongCombinedMetrics.
+ data := protowire.AppendVarint(
+ []byte{},
+ protowire.EncodeTag(
+ protowire.Number(fid_exp.FieldNumbers_FIELD_NUMBERS_FILE_LIST),
+ protowire.BytesType))
+ size := uint64(proto.Size(message))
+ data = protowire.AppendVarint(data, size)
+ data, err = proto.MarshalOptions{UseCachedSize: true}.MarshalAppend(data, message)
+ if err != nil {
+ return err
+ }
+
+ out, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ defer func() {
+ if err := out.Close(); err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to close %s: %v\n", path, err)
+ }
+ }()
+ _, err = out.Write(data)
+ return err
+}
+
func (fl FileList) Format(wr io.Writer, format string) error {
tmpl, err := template.New("filelist").Parse(format)
if err != nil {
diff --git a/cmd/find_input_delta/find_input_delta_lib/fs.go b/cmd/find_input_delta/find_input_delta_lib/fs.go
index 4a83ed7..09a8aa6 100644
--- a/cmd/find_input_delta/find_input_delta_lib/fs.go
+++ b/cmd/find_input_delta/find_input_delta_lib/fs.go
@@ -15,7 +15,6 @@
package find_input_delta_lib
import (
- "io"
"io/fs"
"os"
)
@@ -30,14 +29,6 @@
ReadFile(path string) ([]byte, error)
}
-type file interface {
- io.Closer
- io.Reader
- io.ReaderAt
- io.Seeker
- Stat() (os.FileInfo, error)
-}
-
// osFS implements fileSystem using the local disk.
type osFS struct{}
diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state.go b/cmd/find_input_delta/find_input_delta_lib/internal_state.go
index b2ff8c7..2b8c395 100644
--- a/cmd/find_input_delta/find_input_delta_lib/internal_state.go
+++ b/cmd/find_input_delta/find_input_delta_lib/internal_state.go
@@ -18,9 +18,11 @@
"errors"
"fmt"
"io/fs"
+ "regexp"
"slices"
fid_proto "android/soong/cmd/find_input_delta/find_input_delta_proto_internal"
+ "android/soong/third_party/zip"
"github.com/google/blueprint/pathtools"
"google.golang.org/protobuf/proto"
)
@@ -57,6 +59,7 @@
// If we ever have an easy hash, assign it here.
}
if inspect_contents {
+ // NOTE: When we find it useful, we can parallelize the file inspection for speed.
contents, err := InspectFileContents(input)
if err != nil {
return ret, err
@@ -70,14 +73,36 @@
return ret, nil
}
+// We ignore any suffix digit caused by sharding.
+var InspectExtsZipRegexp = regexp.MustCompile("\\.(jar|apex|apk)[0-9]*$")
+
// Inspect the file and extract the state of the elements in the archive.
// If this is not an archive of some sort, nil is returned.
func InspectFileContents(name string) ([]*fid_proto.PartialCompileInput, error) {
- // TODO: Actually inspect the contents.
- fmt.Printf("inspecting contents for %s\n", name)
+ if InspectExtsZipRegexp.Match([]byte(name)) {
+ return inspectZipFileContents(name)
+ }
return nil, nil
}
+func inspectZipFileContents(name string) ([]*fid_proto.PartialCompileInput, error) {
+ rc, err := zip.OpenReader(name)
+ if err != nil {
+ return nil, err
+ }
+ ret := []*fid_proto.PartialCompileInput{}
+ for _, v := range rc.File {
+ pci := &fid_proto.PartialCompileInput{
+ Name: proto.String(v.Name),
+ MtimeNsec: proto.Int64(v.ModTime().UnixNano()),
+ Hash: proto.String(fmt.Sprintf("%08x", v.CRC32)),
+ }
+ ret = append(ret, pci)
+ // We do not support nested inspection.
+ }
+ return ret, nil
+}
+
func WriteState(s *fid_proto.PartialCompileInputs, path string) error {
data, err := proto.Marshal(s)
if err != nil {
@@ -91,9 +116,7 @@
}
func CompareInputFiles(prior, other []*fid_proto.PartialCompileInput, name string) *FileList {
- fl := &FileList{
- Name: name,
- }
+ fl := FileListFactory(name)
PriorMap := make(map[string]*fid_proto.PartialCompileInput, len(prior))
// We know that the lists are properly sorted, so we can simply compare them.
for _, v := range prior {
@@ -105,17 +128,17 @@
otherMap[name] = v
if _, ok := PriorMap[name]; !ok {
// Added file
- fl.Additions = append(fl.Additions, name)
+ fl.addFile(name)
} else if !proto.Equal(PriorMap[name], v) {
// Changed file
- fl.Changes = append(fl.Changes, *CompareInputFiles(PriorMap[name].GetContents(), v.GetContents(), name))
+ fl.changeFile(name, CompareInputFiles(PriorMap[name].GetContents(), v.GetContents(), name))
}
}
for _, v := range prior {
name := v.GetName()
if _, ok := otherMap[name]; !ok {
// Deleted file
- fl.Deletions = append(fl.Deletions, name)
+ fl.deleteFile(name)
}
}
return fl
diff --git a/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go b/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go
index 20b8efa..c168d5a 100644
--- a/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go
+++ b/cmd/find_input_delta/find_input_delta_lib/internal_state_test.go
@@ -199,7 +199,7 @@
},
},
{
- Name: "one of each",
+ Name: "one each add modify delete",
Target: "foo",
Prior: &fid_proto.PartialCompileInputs{
InputFiles: []*fid_proto.PartialCompileInput{
@@ -222,11 +222,62 @@
Deletions: []string{"file2"},
},
},
+ {
+ Name: "interior one each add modify delete",
+ Target: "bar",
+ Prior: &fid_proto.PartialCompileInputs{
+ InputFiles: []*fid_proto.PartialCompileInput{
+ protoFile("file1", 405, "", []*fid_proto.PartialCompileInput{
+ protoFile("innerC", 400, "crc32:11111111", nil),
+ protoFile("innerD", 400, "crc32:44444444", nil),
+ }),
+ },
+ },
+ New: &fid_proto.PartialCompileInputs{
+ InputFiles: []*fid_proto.PartialCompileInput{
+ protoFile("file1", 505, "", []*fid_proto.PartialCompileInput{
+ protoFile("innerA", 400, "crc32:55555555", nil),
+ protoFile("innerC", 500, "crc32:66666666", nil),
+ }),
+ },
+ },
+ Expected: &FileList{
+ Name: "bar",
+ Changes: []FileList{FileList{
+ Name: "file1",
+ Additions: []string{"innerA"},
+ Changes: []FileList{FileList{Name: "innerC"}},
+ Deletions: []string{"innerD"},
+ }},
+ },
+ },
}
for _, tc := range testCases {
actual := CompareInternalState(tc.Prior, tc.New, tc.Target)
if !tc.Expected.Equal(actual) {
- t.Errorf("%s: expected %q, actual %q", tc.Name, tc.Expected, actual)
+ t.Errorf("%s: expected %v, actual %v", tc.Name, tc.Expected, actual)
+ }
+ }
+}
+
+func TestCompareInspectExtsZipRegexp(t *testing.T) {
+ testCases := []struct {
+ Name string
+ Expected bool
+ }{
+ {Name: ".jar", Expected: true},
+ {Name: ".jar5", Expected: true},
+ {Name: ".apex", Expected: true},
+ {Name: ".apex9", Expected: true},
+ {Name: ".apexx", Expected: false},
+ {Name: ".apk", Expected: true},
+ {Name: ".apk3", Expected: true},
+ {Name: ".go", Expected: false},
+ }
+ for _, tc := range testCases {
+ actual := InspectExtsZipRegexp.Match([]byte(tc.Name))
+ if tc.Expected != actual {
+ t.Errorf("%s: expected %v, actual %v", tc.Name, tc.Expected, actual)
}
}
}
diff --git a/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go b/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go
index 648ef22..745de2d 100644
--- a/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go
+++ b/cmd/find_input_delta/find_input_delta_proto/file_list.pb.go
@@ -19,7 +19,7 @@
// protoc v3.21.12
// source: file_list.proto
-package proto
+package find_input_delta_proto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -35,6 +35,62 @@
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
+type FieldNumbers int32
+
+const (
+ FieldNumbers_FIELD_NUMBERS_UNSPECIFIED FieldNumbers = 0
+ FieldNumbers_FIELD_NUMBERS_FILE_LIST FieldNumbers = 1
+)
+
+// Enum value maps for FieldNumbers.
+var (
+ FieldNumbers_name = map[int32]string{
+ 0: "FIELD_NUMBERS_UNSPECIFIED",
+ 1: "FIELD_NUMBERS_FILE_LIST",
+ }
+ FieldNumbers_value = map[string]int32{
+ "FIELD_NUMBERS_UNSPECIFIED": 0,
+ "FIELD_NUMBERS_FILE_LIST": 1,
+ }
+)
+
+func (x FieldNumbers) Enum() *FieldNumbers {
+ p := new(FieldNumbers)
+ *p = x
+ return p
+}
+
+func (x FieldNumbers) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (FieldNumbers) Descriptor() protoreflect.EnumDescriptor {
+ return file_file_list_proto_enumTypes[0].Descriptor()
+}
+
+func (FieldNumbers) Type() protoreflect.EnumType {
+ return &file_file_list_proto_enumTypes[0]
+}
+
+func (x FieldNumbers) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *FieldNumbers) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = FieldNumbers(num)
+ return nil
+}
+
+// Deprecated: Use FieldNumbers.Descriptor instead.
+func (FieldNumbers) EnumDescriptor() ([]byte, []int) {
+ return file_file_list_proto_rawDescGZIP(), []int{0}
+}
+
type FileList struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -46,10 +102,14 @@
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// The added files.
Additions []string `protobuf:"bytes,2,rep,name=additions" json:"additions,omitempty"`
- // The deleted files.
- Deletions []string `protobuf:"bytes,3,rep,name=deletions" json:"deletions,omitempty"`
// The changed files.
- Changes []*FileList `protobuf:"bytes,4,rep,name=changes" json:"changes,omitempty"`
+ Changes []*FileList `protobuf:"bytes,3,rep,name=changes" json:"changes,omitempty"`
+ // The deleted files.
+ Deletions []string `protobuf:"bytes,4,rep,name=deletions" json:"deletions,omitempty"`
+ // Count of files added/changed/deleted.
+ TotalDelta *uint32 `protobuf:"varint,5,opt,name=total_delta,json=totalDelta" json:"total_delta,omitempty"`
+ // Counts by extension.
+ Counts []*FileCount `protobuf:"bytes,6,rep,name=counts" json:"counts,omitempty"`
}
func (x *FileList) Reset() {
@@ -98,6 +158,13 @@
return nil
}
+func (x *FileList) GetChanges() []*FileList {
+ if x != nil {
+ return x.Changes
+ }
+ return nil
+}
+
func (x *FileList) GetDeletions() []string {
if x != nil {
return x.Deletions
@@ -105,32 +172,135 @@
return nil
}
-func (x *FileList) GetChanges() []*FileList {
+func (x *FileList) GetTotalDelta() uint32 {
+ if x != nil && x.TotalDelta != nil {
+ return *x.TotalDelta
+ }
+ return 0
+}
+
+func (x *FileList) GetCounts() []*FileCount {
if x != nil {
- return x.Changes
+ return x.Counts
}
return nil
}
+type FileCount struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The file extension
+ Extension *string `protobuf:"bytes,1,opt,name=extension" json:"extension,omitempty"`
+ // Number of added files with this extension.
+ Additions *uint32 `protobuf:"varint,2,opt,name=additions" json:"additions,omitempty"`
+ // Number of modified files with this extension.
+ Modifications *uint32 `protobuf:"varint,3,opt,name=modifications" json:"modifications,omitempty"`
+ // Number of deleted files with this extension.
+ Deletions *uint32 `protobuf:"varint,4,opt,name=deletions" json:"deletions,omitempty"`
+}
+
+func (x *FileCount) Reset() {
+ *x = FileCount{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_file_list_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *FileCount) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FileCount) ProtoMessage() {}
+
+func (x *FileCount) ProtoReflect() protoreflect.Message {
+ mi := &file_file_list_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use FileCount.ProtoReflect.Descriptor instead.
+func (*FileCount) Descriptor() ([]byte, []int) {
+ return file_file_list_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *FileCount) GetExtension() string {
+ if x != nil && x.Extension != nil {
+ return *x.Extension
+ }
+ return ""
+}
+
+func (x *FileCount) GetAdditions() uint32 {
+ if x != nil && x.Additions != nil {
+ return *x.Additions
+ }
+ return 0
+}
+
+func (x *FileCount) GetModifications() uint32 {
+ if x != nil && x.Modifications != nil {
+ return *x.Modifications
+ }
+ return 0
+}
+
+func (x *FileCount) GetDeletions() uint32 {
+ if x != nil && x.Deletions != nil {
+ return *x.Deletions
+ }
+ return 0
+}
+
var File_file_list_proto protoreflect.FileDescriptor
var file_file_list_proto_rawDesc = []byte{
0x0a, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x1e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f,
0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74,
- 0x6f, 0x22, 0x9e, 0x01, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12,
+ 0x6f, 0x22, 0x82, 0x02, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20,
- 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x42,
- 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69,
- 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
- 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67,
- 0x65, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f,
- 0x6f, 0x6e, 0x67, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64,
- 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x12, 0x42, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64,
+ 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x07, 0x63, 0x68, 0x61,
+ 0x6e, 0x67, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x65, 0x6c, 0x74,
+ 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x44, 0x65,
+ 0x6c, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x06, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69,
+ 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06,
+ 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x43,
+ 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,
+ 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,
+ 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x63,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x64, 0x65, 0x6c, 0x65, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x75, 0x6d,
+ 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55,
+ 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+ 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d,
+ 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x01,
+ 0x42, 0x3b, 0x5a, 0x39, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e,
+ 0x67, 0x2f, 0x63, 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74,
+ 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75,
+ 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
}
var (
@@ -145,17 +315,21 @@
return file_file_list_proto_rawDescData
}
-var file_file_list_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_file_list_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_file_list_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_file_list_proto_goTypes = []interface{}{
- (*FileList)(nil), // 0: android.find_input_delta_proto.FileList
+ (FieldNumbers)(0), // 0: android.find_input_delta_proto.FieldNumbers
+ (*FileList)(nil), // 1: android.find_input_delta_proto.FileList
+ (*FileCount)(nil), // 2: android.find_input_delta_proto.FileCount
}
var file_file_list_proto_depIdxs = []int32{
- 0, // 0: android.find_input_delta_proto.FileList.changes:type_name -> android.find_input_delta_proto.FileList
- 1, // [1:1] is the sub-list for method output_type
- 1, // [1:1] is the sub-list for method input_type
- 1, // [1:1] is the sub-list for extension type_name
- 1, // [1:1] is the sub-list for extension extendee
- 0, // [0:1] is the sub-list for field type_name
+ 1, // 0: android.find_input_delta_proto.FileList.changes:type_name -> android.find_input_delta_proto.FileList
+ 2, // 1: android.find_input_delta_proto.FileList.counts:type_name -> android.find_input_delta_proto.FileCount
+ 2, // [2:2] is the sub-list for method output_type
+ 2, // [2:2] is the sub-list for method input_type
+ 2, // [2:2] is the sub-list for extension type_name
+ 2, // [2:2] is the sub-list for extension extendee
+ 0, // [0:2] is the sub-list for field type_name
}
func init() { file_file_list_proto_init() }
@@ -176,19 +350,32 @@
return nil
}
}
+ file_file_list_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*FileCount); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_file_list_proto_rawDesc,
- NumEnums: 0,
- NumMessages: 1,
+ NumEnums: 1,
+ NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_file_list_proto_goTypes,
DependencyIndexes: file_file_list_proto_depIdxs,
+ EnumInfos: file_file_list_proto_enumTypes,
MessageInfos: file_file_list_proto_msgTypes,
}.Build()
File_file_list_proto = out.File
diff --git a/cmd/find_input_delta/find_input_delta_proto/file_list.proto b/cmd/find_input_delta/find_input_delta_proto/file_list.proto
index d7faca9..7180358 100644
--- a/cmd/find_input_delta/find_input_delta_proto/file_list.proto
+++ b/cmd/find_input_delta/find_input_delta_proto/file_list.proto
@@ -15,7 +15,12 @@
syntax = "proto2";
package android.find_input_delta_proto;
-option go_package = "android/soong/find_input_delta/proto";
+option go_package = "android/soong/cmd/find_input_delta/find_input_delta_proto";
+
+enum FieldNumbers {
+ FIELD_NUMBERS_UNSPECIFIED = 0;
+ FIELD_NUMBERS_FILE_LIST = 1;
+}
message FileList {
// The name of the file.
@@ -26,9 +31,29 @@
// The added files.
repeated string additions = 2;
- // The deleted files.
- repeated string deletions = 3;
-
// The changed files.
- repeated FileList changes = 4;
+ repeated FileList changes = 3;
+
+ // The deleted files.
+ repeated string deletions = 4;
+
+ // Count of files added/changed/deleted.
+ optional uint32 total_delta = 5;
+
+ // Counts by extension.
+ repeated FileCount counts = 6;
+}
+
+message FileCount {
+ // The file extension
+ optional string extension = 1;
+
+ // Number of added files with this extension.
+ optional uint32 additions = 2;
+
+ // Number of modified files with this extension.
+ optional uint32 modifications = 3;
+
+ // Number of deleted files with this extension.
+ optional uint32 deletions = 4;
}
diff --git a/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.pb.go b/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.pb.go
index 2229a32..c5b048b 100644
--- a/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.pb.go
+++ b/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.pb.go
@@ -19,7 +19,7 @@
// protoc v3.21.12
// source: internal_state.proto
-package proto
+package find_input_delta_proto_internal
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -94,7 +94,7 @@
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// The timestamp of the file in (Unix) nanoseconds.
MtimeNsec *int64 `protobuf:"varint,2,opt,name=mtime_nsec,json=mtimeNsec" json:"mtime_nsec,omitempty"`
- // The hash of the file, in the form ‘{HASHNAME}:{VALUE}’
+ // The hash of the file. For crc32 hashes, this will be 8 hex digits.
Hash *string `protobuf:"bytes,3,opt,name=hash" json:"hash,omitempty"`
// Contents of the file, if the file was inspected (such as jar files, etc).
Contents []*PartialCompileInput `protobuf:"bytes,4,rep,name=contents" json:"contents,omitempty"`
@@ -164,29 +164,33 @@
var file_internal_state_proto_rawDesc = []byte{
0x0a, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65,
- 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61,
- 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6c, 0x0a, 0x14, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61,
- 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x54,
- 0x0a, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20,
- 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69,
- 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70,
- 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x46,
- 0x69, 0x6c, 0x65, 0x73, 0x22, 0xad, 0x01, 0x0a, 0x13, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c,
- 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12, 0x0a, 0x04,
- 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
- 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x65, 0x63, 0x18, 0x02,
- 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x65, 0x63, 0x12,
- 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68,
- 0x61, 0x73, 0x68, 0x12, 0x4f, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18,
- 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
- 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61,
- 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f,
- 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74,
- 0x65, 0x6e, 0x74, 0x73, 0x42, 0x26, 0x5a, 0x24, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f,
- 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74,
- 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x22,
+ 0x75, 0x0a, 0x14, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c,
+ 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x73, 0x12, 0x5d, 0x0a, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74,
+ 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x61,
+ 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75,
+ 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x69, 0x6e,
+ 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f,
+ 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75,
+ 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x22, 0xb6, 0x01, 0x0a, 0x13, 0x50, 0x61, 0x72, 0x74, 0x69,
+ 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x12,
+ 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e, 0x73, 0x65, 0x63,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x4e, 0x73, 0x65,
+ 0x63, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x58, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
+ 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69,
+ 0x64, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c,
+ 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+ 0x49, 0x6e, 0x70, 0x75, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x42,
+ 0x40, 0x5a, 0x3e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67,
+ 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74,
+ 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c,
+ 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61,
+ 0x6c,
}
var (
@@ -203,12 +207,12 @@
var file_internal_state_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_internal_state_proto_goTypes = []interface{}{
- (*PartialCompileInputs)(nil), // 0: android.find_input_delta_proto.PartialCompileInputs
- (*PartialCompileInput)(nil), // 1: android.find_input_delta_proto.PartialCompileInput
+ (*PartialCompileInputs)(nil), // 0: android.find_input_delta_proto_internal.PartialCompileInputs
+ (*PartialCompileInput)(nil), // 1: android.find_input_delta_proto_internal.PartialCompileInput
}
var file_internal_state_proto_depIdxs = []int32{
- 1, // 0: android.find_input_delta_proto.PartialCompileInputs.input_files:type_name -> android.find_input_delta_proto.PartialCompileInput
- 1, // 1: android.find_input_delta_proto.PartialCompileInput.contents:type_name -> android.find_input_delta_proto.PartialCompileInput
+ 1, // 0: android.find_input_delta_proto_internal.PartialCompileInputs.input_files:type_name -> android.find_input_delta_proto_internal.PartialCompileInput
+ 1, // 1: android.find_input_delta_proto_internal.PartialCompileInput.contents:type_name -> android.find_input_delta_proto_internal.PartialCompileInput
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
diff --git a/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.proto b/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.proto
index 113fc64..54c90cc 100644
--- a/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.proto
+++ b/cmd/find_input_delta/find_input_delta_proto_internal/internal_state.proto
@@ -14,8 +14,8 @@
// limitations under the License.
syntax = "proto2";
-package android.find_input_delta_proto;
-option go_package = "android/soong/find_input_delta/proto";
+package android.find_input_delta_proto_internal;
+option go_package = "android/soong/find_input_delta/find_input_delta_proto_internal";
// The state of all inputs.
message PartialCompileInputs {
@@ -31,7 +31,7 @@
// The timestamp of the file in (Unix) nanoseconds.
optional int64 mtime_nsec = 2;
- // The hash of the file, in the form ‘{HASHNAME}:{VALUE}’
+ // The hash of the file. For crc32 hashes, this will be 8 hex digits.
optional string hash = 3;
// Contents of the file, if the file was inspected (such as jar files, etc).
diff --git a/cmd/release_config/build_flag/main.go b/cmd/release_config/build_flag/main.go
index 46efce7..5d103cc 100644
--- a/cmd/release_config/build_flag/main.go
+++ b/cmd/release_config/build_flag/main.go
@@ -90,6 +90,9 @@
if !ok {
return "", fmt.Errorf("%s not found in %s", name, config.Name)
}
+ if fa.Redacted {
+ return "==REDACTED==", nil
+ }
return rc_lib.MarshalValue(fa.Value), nil
}
diff --git a/cmd/release_config/release_config_lib/flag_artifact.go b/cmd/release_config/release_config_lib/flag_artifact.go
index bb321da..cb13fdc 100644
--- a/cmd/release_config/release_config_lib/flag_artifact.go
+++ b/cmd/release_config/release_config_lib/flag_artifact.go
@@ -84,8 +84,10 @@
func (fas *FlagArtifacts) SortedFlagNames() []string {
var names []string
- for k, _ := range *fas {
- names = append(names, k)
+ for k, v := range *fas {
+ if !v.Redacted {
+ names = append(names, k)
+ }
}
slices.Sort(names)
return names
@@ -183,15 +185,20 @@
// error: any error encountered
func (fa *FlagArtifact) UpdateValue(flagValue FlagValue) error {
name := *flagValue.proto.Name
- fa.Traces = append(fa.Traces, &rc_proto.Tracepoint{Source: proto.String(flagValue.path), Value: flagValue.proto.Value})
- if flagValue.proto.GetRedacted() {
- fa.Redacted = true
+ redacted := flagValue.proto.GetRedacted()
+ if redacted {
+ fa.Redact()
+ flagValue.proto.Value = fa.Value
fmt.Printf("Redacting flag %s in %s\n", name, flagValue.path)
- return nil
+ } else {
+ // If we are assigning a value, then the flag is no longer redacted.
+ fa.Redacted = false
}
+ fa.Traces = append(fa.Traces, &rc_proto.Tracepoint{Source: proto.String(flagValue.path), Value: flagValue.proto.Value})
if fa.Value.GetObsolete() {
return fmt.Errorf("Attempting to set obsolete flag %s. Trace=%v", name, fa.Traces)
}
+
var newValue *rc_proto.Value
switch val := flagValue.proto.Value.Val.(type) {
case *rc_proto.Value_StringValue:
@@ -213,6 +220,11 @@
return nil
}
+func (fa *FlagArtifact) Redact() {
+ fa.Redacted = true
+ fa.Value = &rc_proto.Value{Val: &rc_proto.Value_StringValue{StringValue: "*REDACTED*"}}
+}
+
// Marshal the FlagArtifact into a flag_artifact message.
func (fa *FlagArtifact) Marshal() (*rc_proto.FlagArtifact, error) {
if fa.Redacted {
diff --git a/cmd/release_config/release_config_lib/release_config.go b/cmd/release_config/release_config_lib/release_config.go
index ee71336..3c834cc 100644
--- a/cmd/release_config/release_config_lib/release_config.go
+++ b/cmd/release_config/release_config_lib/release_config.go
@@ -21,7 +21,6 @@
"path/filepath"
"regexp"
"slices"
- "sort"
"strings"
rc_proto "android/soong/cmd/release_config/release_config_proto"
@@ -107,6 +106,9 @@
if !ok {
return fmt.Errorf("Could not inherit flag %s from %s", name, iConfig.Name)
}
+ if fa.Redacted {
+ myFa.Redact()
+ }
if name == "RELEASE_ACONFIG_VALUE_SETS" {
// If there is a value assigned, add the trace.
if len(fa.Value.GetStringValue()) > 0 {
@@ -166,6 +168,13 @@
}
myInherits = append(myInherits, inherit)
myInheritsSet[inherit] = true
+ // TODO: there are some configs that rely on vgsbr being
+ // present on branches where it isn't. Once the broken configs
+ // are fixed, we can be more strict. In the meantime, they
+ // will wind up inheriting `trunk_stable` instead of the
+ // non-existent (alias) that they reference today. Once fixed,
+ // this becomes:
+ // iConfig, err := configs.GetReleaseConfigStrict(inherit)
iConfig, err := configs.GetReleaseConfig(inherit)
if err != nil {
return err
@@ -261,9 +270,6 @@
if err := fa.UpdateValue(*value); err != nil {
return err
}
- if fa.Redacted {
- delete(config.FlagArtifacts, name)
- }
}
}
// Now remove any duplicates from the actual value of RELEASE_ACONFIG_VALUE_SETS
@@ -313,6 +319,10 @@
if err != nil {
return err
}
+ // Redacted flags return nil when rendered.
+ if artifact == nil {
+ continue
+ }
for _, container := range v.FlagDeclaration.Containers {
if _, ok := config.PartitionBuildFlags[container]; !ok {
config.PartitionBuildFlags[container] = &rc_proto.FlagArtifacts{}
@@ -325,12 +335,7 @@
OtherNames: config.OtherNames,
Flags: func() []*rc_proto.FlagArtifact {
ret := []*rc_proto.FlagArtifact{}
- flagNames := []string{}
- for k := range config.FlagArtifacts {
- flagNames = append(flagNames, k)
- }
- sort.Strings(flagNames)
- for _, flagName := range flagNames {
+ for _, flagName := range config.FlagArtifacts.SortedFlagNames() {
flag := config.FlagArtifacts[flagName]
ret = append(ret, &rc_proto.FlagArtifact{
FlagDeclaration: flag.FlagDeclaration,
@@ -365,7 +370,7 @@
}
}
for _, rcName := range extraAconfigReleaseConfigs {
- rc, err := configs.GetReleaseConfig(rcName)
+ rc, err := configs.GetReleaseConfigStrict(rcName)
if err != nil {
return err
}
diff --git a/cmd/release_config/release_config_lib/release_configs.go b/cmd/release_config/release_config_lib/release_configs.go
index 831ec02..f947b7f 100644
--- a/cmd/release_config/release_config_lib/release_configs.go
+++ b/cmd/release_config/release_config_lib/release_configs.go
@@ -410,6 +410,14 @@
}
func (configs *ReleaseConfigs) GetReleaseConfig(name string) (*ReleaseConfig, error) {
+ return configs.getReleaseConfig(name, configs.allowMissing)
+}
+
+func (configs *ReleaseConfigs) GetReleaseConfigStrict(name string) (*ReleaseConfig, error) {
+ return configs.getReleaseConfig(name, false)
+}
+
+func (configs *ReleaseConfigs) getReleaseConfig(name string, allow_missing bool) (*ReleaseConfig, error) {
trace := []string{name}
for target, ok := configs.Aliases[name]; ok; target, ok = configs.Aliases[name] {
name = *target
@@ -418,7 +426,7 @@
if config, ok := configs.ReleaseConfigs[name]; ok {
return config, nil
}
- if configs.allowMissing {
+ if allow_missing {
if config, ok := configs.ReleaseConfigs["trunk_staging"]; ok {
return config, nil
}
@@ -467,7 +475,7 @@
dirName := filepath.Dir(contrib.path)
for k, names := range contrib.FlagValueDirs {
for _, rcName := range names {
- if config, err := configs.GetReleaseConfig(rcName); err == nil {
+ if config, err := configs.getReleaseConfig(rcName, false); err == nil {
rcPath := filepath.Join(dirName, "release_configs", fmt.Sprintf("%s.textproto", config.Name))
if _, err := os.Stat(rcPath); err != nil {
errors = append(errors, fmt.Sprintf("%s exists but %s does not contribute to %s",
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 3dd6f9a..e3804e5 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -465,7 +465,7 @@
func (d dex2oatDependencyTag) AllowDisabledModuleDependencyProxy(
ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool {
return android.OtherModuleProviderOrDefault(
- ctx, target, android.CommonPropertiesProviderKey).ReplacedByPrebuilt
+ ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt
}
// Dex2oatDepTag represents the dependency onto the dex2oatd module. It is added to any module that
diff --git a/etc/adb_keys.go b/etc/adb_keys.go
index 73bc347..cfcb1d5 100644
--- a/etc/adb_keys.go
+++ b/etc/adb_keys.go
@@ -24,7 +24,7 @@
type AdbKeysModule struct {
android.ModuleBase
- outputPath android.OutputPath
+ outputPath android.Path
installPath android.InstallPath
}
@@ -46,15 +46,16 @@
return
}
- m.outputPath = android.PathForModuleOut(ctx, "adb_keys").OutputPath
+ outputPath := android.PathForModuleOut(ctx, "adb_keys")
input := android.ExistentPathForSource(ctx, android.String(productVariables.AdbKeys))
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
- Output: m.outputPath,
+ Output: outputPath,
Input: input.Path(),
})
m.installPath = android.PathForModuleInstall(ctx, "etc/security")
- ctx.InstallFile(m.installPath, "adb_keys", m.outputPath)
+ ctx.InstallFile(m.installPath, "adb_keys", outputPath)
+ m.outputPath = outputPath
}
func (m *AdbKeysModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/etc/otacerts_zip.go b/etc/otacerts_zip.go
index d12bdac..8220cea 100644
--- a/etc/otacerts_zip.go
+++ b/etc/otacerts_zip.go
@@ -44,7 +44,7 @@
android.ModuleBase
properties otacertsZipProperties
- outputPath android.OutputPath
+ outputPath android.Path
}
// otacerts_zip collects key files defined in PRODUCT_DEFAULT_DEV_CERTIFICATE
@@ -117,11 +117,11 @@
// Read .x509.pem files listed in PRODUCT_EXTRA_OTA_KEYS or PRODUCT_EXTRA_RECOVERY_KEYS.
extras := ctx.Config().ExtraOtaKeys(ctx, m.InRecovery())
srcPaths := append([]android.SourcePath{pem}, extras...)
- m.outputPath = android.PathForModuleOut(ctx, m.outputFileName()).OutputPath
+ outputPath := android.PathForModuleOut(ctx, m.outputFileName())
rule := android.NewRuleBuilder(pctx, ctx)
cmd := rule.Command().BuiltTool("soong_zip").
- FlagWithOutput("-o ", m.outputPath).
+ FlagWithOutput("-o ", outputPath).
Flag("-j ").
Flag("-symlinks=false ")
for _, src := range srcPaths {
@@ -130,7 +130,8 @@
rule.Build(ctx.ModuleName(), "Generating the otacerts zip file")
installPath := android.PathForModuleInstall(ctx, "etc", proptools.String(m.properties.Relative_install_path))
- ctx.InstallFile(installPath, m.outputFileName(), m.outputPath)
+ ctx.InstallFile(installPath, m.outputFileName(), outputPath)
+ m.outputPath = outputPath
}
func (m *otacertsZipModule) AndroidMkEntries() []android.AndroidMkEntries {
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 943ec81..b0b5da9 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -184,7 +184,7 @@
subdirProperties prebuiltSubdirProperties
sourceFilePaths android.Paths
- outputFilePaths android.OutputPaths
+ outputFilePaths android.WritablePaths
// The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
installDirBase string
installDirBase64 string
@@ -317,7 +317,7 @@
p.additionalDependencies = &paths
}
-func (p *PrebuiltEtc) OutputFile() android.OutputPath {
+func (p *PrebuiltEtc) OutputFile() android.Path {
if p.usedSrcsProperty {
panic(fmt.Errorf("OutputFile not available on multi-source prebuilt %q", p.Name()))
}
@@ -410,7 +410,7 @@
ctx.PropertyErrorf("filename", "filename cannot contain separator '/'")
return
}
- p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
+ p.outputFilePaths = android.WritablePaths{android.PathForModuleOut(ctx, filename)}
ip := installProperties{
filename: filename,
@@ -453,7 +453,7 @@
filename = src.Base()
installDirPath = baseInstallDirPath
}
- output := android.PathForModuleOut(ctx, filename).OutputPath
+ output := android.PathForModuleOut(ctx, filename)
ip := installProperties{
filename: filename,
sourceFilePath: src,
@@ -473,7 +473,7 @@
if filename == "" {
filename = ctx.ModuleName()
}
- p.outputFilePaths = android.OutputPaths{android.PathForModuleOut(ctx, filename).OutputPath}
+ p.outputFilePaths = android.WritablePaths{android.PathForModuleOut(ctx, filename)}
ip := installProperties{
filename: filename,
sourceFilePath: p.sourceFilePaths[0],
@@ -501,7 +501,7 @@
type installProperties struct {
filename string
sourceFilePath android.Path
- outputFilePath android.OutputPath
+ outputFilePath android.WritablePath
installDirPath android.InstallPath
symlinks []string
}
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index 469f1fb..9d4ba3e 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -29,7 +29,7 @@
properties avbAddHashFooterProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -97,8 +97,8 @@
return
}
input := android.PathForModuleSrc(ctx, proptools.String(a.properties.Src))
- a.output = android.PathForModuleOut(ctx, a.installFileName()).OutputPath
- builder.Command().Text("cp").Input(input).Output(a.output)
+ output := android.PathForModuleOut(ctx, a.installFileName())
+ builder.Command().Text("cp").Input(input).Output(output)
cmd := builder.Command().BuiltTool("avbtool").Text("add_hash_footer")
@@ -141,12 +141,13 @@
cmd.Flag(fmt.Sprintf(" --rollback_index %d", rollbackIndex))
}
- cmd.FlagWithOutput("--image ", a.output)
+ cmd.FlagWithOutput("--image ", output)
builder.Build("avbAddHashFooter", fmt.Sprintf("avbAddHashFooter %s", ctx.ModuleName()))
a.installDir = android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(a.installDir, a.installFileName(), a.output)
+ ctx.InstallFile(a.installDir, a.installFileName(), output)
+ a.output = output
}
func addAvbProp(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, prop avbProp) {
diff --git a/filesystem/avb_gen_vbmeta_image.go b/filesystem/avb_gen_vbmeta_image.go
index a7fd782..0669a2c 100644
--- a/filesystem/avb_gen_vbmeta_image.go
+++ b/filesystem/avb_gen_vbmeta_image.go
@@ -28,7 +28,7 @@
properties avbGenVbmetaImageProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -78,11 +78,12 @@
}
cmd.FlagWithArg("--salt ", proptools.String(a.properties.Salt))
- a.output = android.PathForModuleOut(ctx, a.installFileName()).OutputPath
- cmd.FlagWithOutput("--output_vbmeta_image ", a.output)
+ output := android.PathForModuleOut(ctx, a.installFileName())
+ cmd.FlagWithOutput("--output_vbmeta_image ", output)
builder.Build("avbGenVbmetaImage", fmt.Sprintf("avbGenVbmetaImage %s", ctx.ModuleName()))
- ctx.SetOutputFiles([]android.Path{a.output}, "")
+ ctx.SetOutputFiles([]android.Path{output}, "")
+ a.output = output
}
var _ android.AndroidMkEntriesProvider = (*avbGenVbmetaImage)(nil)
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 9d93925..c9bd617 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -34,7 +34,7 @@
properties bootimgProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -115,20 +115,20 @@
vendor := proptools.Bool(b.properties.Vendor_boot)
unsignedOutput := b.buildBootImage(ctx, vendor)
+ output := unsignedOutput
if proptools.Bool(b.properties.Use_avb) {
- b.output = b.signImage(ctx, unsignedOutput)
- } else {
- b.output = unsignedOutput
+ output = b.signImage(ctx, unsignedOutput)
}
b.installDir = android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(b.installDir, b.installFileName(), b.output)
+ ctx.InstallFile(b.installDir, b.installFileName(), output)
- ctx.SetOutputFiles([]android.Path{b.output}, "")
+ ctx.SetOutputFiles([]android.Path{output}, "")
+ b.output = output
}
-func (b *bootimg) buildBootImage(ctx android.ModuleContext, vendor bool) android.OutputPath {
- output := android.PathForModuleOut(ctx, "unsigned", b.installFileName()).OutputPath
+func (b *bootimg) buildBootImage(ctx android.ModuleContext, vendor bool) android.Path {
+ output := android.PathForModuleOut(ctx, "unsigned", b.installFileName())
builder := android.NewRuleBuilder(pctx, ctx)
cmd := builder.Command().BuiltTool("mkbootimg")
@@ -215,10 +215,10 @@
return output
}
-func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.OutputPath) android.OutputPath {
+func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.Path) android.Path {
propFile, toolDeps := b.buildPropFile(ctx)
- output := android.PathForModuleOut(ctx, b.installFileName()).OutputPath
+ output := android.PathForModuleOut(ctx, b.installFileName())
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Text("cp").Input(unsignedImage).Output(output)
builder.Command().BuiltTool("verity_utils").
@@ -239,7 +239,7 @@
return sha1sum(input)
}
-func (b *bootimg) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
+func (b *bootimg) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
var sb strings.Builder
var deps android.Paths
addStr := func(name string, value string) {
@@ -261,7 +261,7 @@
addStr("partition_name", partitionName)
addStr("avb_salt", b.salt())
- propFile = android.PathForModuleOut(ctx, "prop").OutputPath
+ propFile := android.PathForModuleOut(ctx, "prop")
android.WriteFileRule(ctx, propFile, sb.String())
return propFile, deps
}
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index fa66451..c346770 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -52,10 +52,10 @@
properties FilesystemProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
- fileListFile android.OutputPath
+ fileListFile android.Path
// Keeps the entries installed from this filesystem
entries []string
@@ -340,19 +340,20 @@
ctx.InstallFile(f.installDir, f.installFileName(), f.output)
ctx.SetOutputFiles([]android.Path{f.output}, "")
- f.fileListFile = android.PathForModuleOut(ctx, "fileList").OutputPath
- android.WriteFileRule(ctx, f.fileListFile, f.installedFilesList())
+ fileListFile := android.PathForModuleOut(ctx, "fileList")
+ android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
android.SetProvider(ctx, FilesystemProvider, FilesystemInfo{
- FileListFile: f.fileListFile,
+ FileListFile: fileListFile,
})
+ f.fileListFile = fileListFile
if proptools.Bool(f.properties.Unchecked_module) {
ctx.UncheckedModule()
}
}
-func (f *filesystem) appendToEntry(ctx android.ModuleContext, installedFile android.OutputPath) {
+func (f *filesystem) appendToEntry(ctx android.ModuleContext, installedFile android.Path) {
partitionBaseDir := android.PathForModuleOut(ctx, "root", f.partitionName()).String() + "/"
relPath, inTargetPartition := strings.CutPrefix(installedFile.String(), partitionBaseDir)
@@ -443,7 +444,7 @@
builder.Command().Textf("cp -prf %s/* %s", rebasedDir, installPath)
}
-func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.OutputPath {
+func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.Path {
rootDir := android.PathForModuleOut(ctx, "root").OutputPath
rebasedDir := rootDir
if f.properties.Base_dir != nil {
@@ -472,7 +473,7 @@
FlagWithArg("--out_system=", rootDir.String()+"/system")
propFile, toolDeps := f.buildPropFile(ctx)
- output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
+ output := android.PathForModuleOut(ctx, f.installFileName())
builder.Command().BuiltTool("build_image").
Text(rootDir.String()). // input directory
Input(propFile).
@@ -486,14 +487,14 @@
return output
}
-func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.OutputPath {
+func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path {
builder := android.NewRuleBuilder(pctx, ctx)
fcBin := android.PathForModuleOut(ctx, "file_contexts.bin")
builder.Command().BuiltTool("sefcontext_compile").
FlagWithOutput("-o ", fcBin).
Input(android.PathForModuleSrc(ctx, proptools.String(f.properties.File_contexts)))
builder.Build("build_filesystem_file_contexts", fmt.Sprintf("Creating filesystem file contexts for %s", f.BaseModuleName()))
- return fcBin.OutputPath
+ return fcBin
}
// Calculates avb_salt from entry list (sorted) for deterministic output.
@@ -501,7 +502,7 @@
return sha1sum(f.entries)
}
-func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
+func (f *filesystem) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
var deps android.Paths
var propFileString strings.Builder
addStr := func(name string, value string) {
@@ -597,7 +598,7 @@
}
f.checkFsTypePropertyError(ctx, fst, fsTypeStr(fst))
- propFile = android.PathForModuleOut(ctx, "prop").OutputPath
+ propFile := android.PathForModuleOut(ctx, "prop")
android.WriteFileRuleVerbatim(ctx, propFile, propFileString.String())
return propFile, deps
}
@@ -622,7 +623,7 @@
}
}
-func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) android.OutputPath {
+func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) android.Path {
if proptools.Bool(f.properties.Use_avb) {
ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+
"Consider adding this to bootimg module and signing the entire boot image.")
@@ -654,7 +655,7 @@
f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
f.copyFilesToProductOut(ctx, builder, rebasedDir)
- output := android.PathForModuleOut(ctx, f.installFileName()).OutputPath
+ output := android.PathForModuleOut(ctx, f.installFileName())
cmd := builder.Command().
BuiltTool("mkbootfs").
Text(rootDir.String()) // input directory
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
index 199c845..3119f2f 100644
--- a/filesystem/fsverity_metadata.go
+++ b/filesystem/fsverity_metadata.go
@@ -33,7 +33,7 @@
Libs []string `android:"path"`
}
-func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.OutputPath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
+func (f *filesystem) writeManifestGeneratorListFile(ctx android.ModuleContext, outputPath android.WritablePath, matchedSpecs []android.PackagingSpec, rebasedDir android.OutputPath) {
var buf strings.Builder
for _, spec := range matchedSpecs {
buf.WriteString(rebasedDir.Join(ctx, spec.RelPathInPackage()).String())
@@ -113,12 +113,12 @@
f.appendToEntry(ctx, manifestPbPath)
manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
- f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath.OutputPath, matchedSpecs, rebasedDir)
+ f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir)
sb.WriteRune('@')
sb.WriteString(manifestGeneratorListPath.String())
sb.WriteRune('\n')
cmd.Implicit(manifestGeneratorListPath)
- f.appendToEntry(ctx, manifestGeneratorListPath.OutputPath)
+ f.appendToEntry(ctx, manifestGeneratorListPath)
// STEP 2-2: generate BuildManifest.apk (unsigned)
aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2")
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index 988a57b..d0888a9 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -32,7 +32,7 @@
properties logicalPartitionProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -95,11 +95,14 @@
builder := android.NewRuleBuilder(pctx, ctx)
// Sparse the filesystem images and calculate their sizes
- sparseImages := make(map[string]android.OutputPath)
- sparseImageSizes := make(map[string]android.OutputPath)
+ sparseImages := make(map[string]android.Path)
+ sparseImageSizes := make(map[string]android.Path)
sparsePartitions := func(partitions []partitionProperties) {
for _, part := range partitions {
+ if part.Filesystem == nil {
+ continue
+ }
sparseImg, sizeTxt := sparseFilesystem(ctx, part, builder)
pName := proptools.String(part.Name)
sparseImages[pName] = sparseImg
@@ -185,31 +188,29 @@
addPartitionsToGroup(group.Partitions, gName)
}
- l.output = android.PathForModuleOut(ctx, l.installFileName()).OutputPath
- cmd.FlagWithOutput("--output=", l.output)
+ output := android.PathForModuleOut(ctx, l.installFileName())
+ cmd.FlagWithOutput("--output=", output)
builder.Build("build_logical_partition", fmt.Sprintf("Creating %s", l.BaseModuleName()))
l.installDir = android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(l.installDir, l.installFileName(), l.output)
+ ctx.InstallFile(l.installDir, l.installFileName(), output)
- ctx.SetOutputFiles([]android.Path{l.output}, "")
+ ctx.SetOutputFiles([]android.Path{output}, "")
+ l.output = output
}
// Add a rule that converts the filesystem for the given partition to the given rule builder. The
// path to the sparse file and the text file having the size of the partition are returned.
-func sparseFilesystem(ctx android.ModuleContext, p partitionProperties, builder *android.RuleBuilder) (sparseImg android.OutputPath, sizeTxt android.OutputPath) {
- if p.Filesystem == nil {
- return
- }
- img := android.PathForModuleSrc(ctx, proptools.String(p.Filesystem))
+func sparseFilesystem(ctx android.ModuleContext, p partitionProperties, builder *android.RuleBuilder) (android.Path, android.Path) {
+ img := android.PathForModuleSrc(ctx, *p.Filesystem)
name := proptools.String(p.Name)
- sparseImg = android.PathForModuleOut(ctx, name+".img").OutputPath
+ sparseImg := android.PathForModuleOut(ctx, name+".img")
builder.Temporary(sparseImg)
builder.Command().BuiltTool("img2simg").Input(img).Output(sparseImg)
- sizeTxt = android.PathForModuleOut(ctx, name+"-size.txt").OutputPath
+ sizeTxt := android.PathForModuleOut(ctx, name+"-size.txt")
builder.Temporary(sizeTxt)
builder.Command().BuiltTool("sparse_img").Flag("--get_partition_size").Input(sparseImg).
Text("| ").Text("tr").FlagWithArg("-d ", "'\n'").
diff --git a/filesystem/raw_binary.go b/filesystem/raw_binary.go
index ad36c29..707fba0 100644
--- a/filesystem/raw_binary.go
+++ b/filesystem/raw_binary.go
@@ -42,7 +42,7 @@
properties rawBinaryProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -71,7 +71,7 @@
func (r *rawBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
inputFile := android.PathForModuleSrc(ctx, proptools.String(r.properties.Src))
- outputFile := android.PathForModuleOut(ctx, r.installFileName()).OutputPath
+ outputFile := android.PathForModuleOut(ctx, r.installFileName())
ctx.Build(pctx, android.BuildParams{
Rule: toRawBinary,
@@ -83,11 +83,11 @@
},
})
- r.output = outputFile
r.installDir = android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(r.installDir, r.installFileName(), r.output)
+ ctx.InstallFile(r.installDir, r.installFileName(), outputFile)
- ctx.SetOutputFiles([]android.Path{r.output}, "")
+ ctx.SetOutputFiles([]android.Path{outputFile}, "")
+ r.output = outputFile
}
var _ android.AndroidMkEntriesProvider = (*rawBinary)(nil)
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index ebb3ff9..6a47859 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -44,7 +44,7 @@
properties VbmetaProperties
- output android.OutputPath
+ output android.Path
installDir android.InstallPath
}
@@ -161,8 +161,6 @@
const vbmetaMaxSize = 64 * 1024
func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- v.output = android.PathForModuleOut(ctx, v.installFileName()).OutputPath
-
builder := android.NewRuleBuilder(pctx, ctx)
cmd := builder.Command().BuiltTool("avbtool").Text("make_vbmeta_image")
@@ -274,18 +272,19 @@
cmd.Implicit(publicKey)
}
- cmd.FlagWithOutput("--output ", v.output)
+ output := android.PathForModuleOut(ctx, v.installFileName())
+ cmd.FlagWithOutput("--output ", output)
// libavb expects to be able to read the maximum vbmeta size, so we must provide a partition
// which matches this or the read will fail.
builder.Command().Text("truncate").
FlagWithArg("-s ", strconv.Itoa(vbmetaMaxSize)).
- Output(v.output)
+ Output(output)
builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName()))
v.installDir = android.PathForModuleInstall(ctx, "etc")
- ctx.InstallFile(v.installDir, v.installFileName(), v.output)
+ ctx.InstallFile(v.installDir, v.installFileName(), output)
extractedPublicKey := android.PathForModuleOut(ctx, v.partitionName()+".avbpubkey")
ctx.Build(pctx, android.BuildParams{
@@ -300,7 +299,8 @@
PublicKey: extractedPublicKey,
})
- ctx.SetOutputFiles([]android.Path{v.output}, "")
+ ctx.SetOutputFiles([]android.Path{output}, "")
+ v.output = output
}
// Returns the embedded shell command that prints the rollback index
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index 2b967f7..c74579a 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -64,6 +64,7 @@
generatedPrebuiltEtcModuleNames := createPrebuiltEtcModules(ctx)
avbpubkeyGenerated := createAvbpubkeyModule(ctx)
createFsGenState(ctx, generatedPrebuiltEtcModuleNames, avbpubkeyGenerated)
+ module.createAvbKeyFilegroups(ctx)
module.createInternalModules(ctx)
})
@@ -254,6 +255,51 @@
return true
}
+// Creates filegroups for the files specified in BOARD_(partition_)AVB_KEY_PATH
+func (f *filesystemCreator) createAvbKeyFilegroups(ctx android.LoadHookContext) {
+ partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
+ var files []string
+
+ if len(partitionVars.BoardAvbKeyPath) > 0 {
+ files = append(files, partitionVars.BoardAvbKeyPath)
+ }
+ for _, partition := range android.SortedKeys(partitionVars.PartitionQualifiedVariables) {
+ specificPartitionVars := partitionVars.PartitionQualifiedVariables[partition]
+ if len(specificPartitionVars.BoardAvbKeyPath) > 0 {
+ files = append(files, specificPartitionVars.BoardAvbKeyPath)
+ }
+ }
+
+ fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+ for _, file := range files {
+ if _, ok := fsGenState.avbKeyFilegroups[file]; ok {
+ continue
+ }
+ if file == "external/avb/test/data/testkey_rsa4096.pem" {
+ // There already exists a checked-in filegroup for this commonly-used key, just use that
+ fsGenState.avbKeyFilegroups[file] = "avb_testkey_rsa4096"
+ continue
+ }
+ dir := filepath.Dir(file)
+ base := filepath.Base(file)
+ name := fmt.Sprintf("avb_key_%x", strings.ReplaceAll(file, "/", "_"))
+ ctx.CreateModuleInDirectory(
+ android.FileGroupFactory,
+ dir,
+ &struct {
+ Name *string
+ Srcs []string
+ Visibility []string
+ }{
+ Name: proptools.StringPtr(name),
+ Srcs: []string{base},
+ Visibility: []string{"//visibility:public"},
+ },
+ )
+ fsGenState.avbKeyFilegroups[file] = name
+ }
+}
+
// createPrebuiltKernelModules creates `prebuilt_kernel_modules`. These modules will be added to deps of the
// autogenerated *_dlkm filsystem modules. Each _dlkm partition should have a single prebuilt_kernel_modules dependency.
// This ensures that the depmod artifacts (modules.* installed in /lib/modules/) are generated with a complete view.
@@ -419,21 +465,41 @@
}
func generateFsProps(ctx android.EarlyModuleContext, partitionType string) (*filesystem.FilesystemProperties, bool) {
+ fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
fsProps := &filesystem.FilesystemProperties{}
partitionVars := ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse
- var specificPartitionVars android.PartitionQualifiedVariablesType
var boardAvbEnable bool
+ var boardAvbKeyPath string
+ var boardAvbAlgorithm string
+ var boardAvbRollbackIndex string
var fsType string
if strings.Contains(partitionType, "ramdisk") {
fsType = "compressed_cpio"
} else {
- specificPartitionVars = partitionVars.PartitionQualifiedVariables[partitionType]
- boardAvbEnable = partitionVars.BoardAvbEnable
+ specificPartitionVars := partitionVars.PartitionQualifiedVariables[partitionType]
fsType = specificPartitionVars.BoardFileSystemType
+ boardAvbEnable = partitionVars.BoardAvbEnable
+ boardAvbKeyPath = specificPartitionVars.BoardAvbKeyPath
+ boardAvbAlgorithm = specificPartitionVars.BoardAvbAlgorithm
+ boardAvbRollbackIndex = specificPartitionVars.BoardAvbRollbackIndex
+ if boardAvbEnable {
+ if boardAvbKeyPath == "" {
+ boardAvbKeyPath = partitionVars.BoardAvbKeyPath
+ }
+ if boardAvbAlgorithm == "" {
+ boardAvbAlgorithm = partitionVars.BoardAvbAlgorithm
+ }
+ if boardAvbRollbackIndex == "" {
+ boardAvbRollbackIndex = partitionVars.BoardAvbRollbackIndex
+ }
+ }
+ if fsType == "" {
+ fsType = "ext4" //default
+ }
}
- if fsType == "" {
- fsType = "ext4" //default
+ if boardAvbKeyPath != "" {
+ boardAvbKeyPath = ":" + fsGenState.avbKeyFilegroups[boardAvbKeyPath]
}
fsProps.Type = proptools.StringPtr(fsType)
@@ -449,11 +515,11 @@
// BOARD_AVB_ENABLE
fsProps.Use_avb = proptools.BoolPtr(boardAvbEnable)
// BOARD_AVB_KEY_PATH
- fsProps.Avb_private_key = proptools.StringPtr(specificPartitionVars.BoardAvbKeyPath)
+ fsProps.Avb_private_key = proptools.StringPtr(boardAvbKeyPath)
// BOARD_AVB_ALGORITHM
- fsProps.Avb_algorithm = proptools.StringPtr(specificPartitionVars.BoardAvbAlgorithm)
+ fsProps.Avb_algorithm = proptools.StringPtr(boardAvbAlgorithm)
// BOARD_AVB_SYSTEM_ROLLBACK_INDEX
- if rollbackIndex, err := strconv.ParseInt(specificPartitionVars.BoardAvbRollbackIndex, 10, 64); err == nil {
+ if rollbackIndex, err := strconv.ParseInt(boardAvbRollbackIndex, 10, 64); err == nil {
fsProps.Rollback_index = proptools.Int64Ptr(rollbackIndex)
}
@@ -592,8 +658,10 @@
}
baseProps := generateBaseProps(proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), partitionType)))
- deps := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).fsDeps[partitionType]
- depProps := generateDepStruct(*deps)
+ fsGenState := ctx.Config().Get(fsGenStateOnceKey).(*FsGenState)
+ deps := fsGenState.fsDeps[partitionType]
+ highPriorityDeps := fsGenState.generatedPrebuiltEtcModuleNames
+ depProps := generateDepStruct(*deps, highPriorityDeps)
result, err := proptools.RepackProperties([]interface{}{baseProps, fsProps, depProps})
if err != nil {
diff --git a/fsgen/filesystem_creator_test.go b/fsgen/filesystem_creator_test.go
index 6111a41..fe4a403 100644
--- a/fsgen/filesystem_creator_test.go
+++ b/fsgen/filesystem_creator_test.go
@@ -47,6 +47,12 @@
}),
android.FixtureMergeMockFs(android.MockFS{
"external/avb/test/data/testkey_rsa4096.pem": nil,
+ "external/avb/test/Android.bp": []byte(`
+ filegroup {
+ name: "avb_testkey_rsa4096",
+ srcs: ["data/testkey_rsa4096.pem"],
+ }
+ `),
"build/soong/fsgen/Android.bp": []byte(`
soong_filesystem_creator {
name: "foo",
@@ -66,8 +72,8 @@
)
android.AssertStringEquals(
t,
- "Property expected to match the product variable 'BOARD_AVB_KEY_PATH'",
- "external/avb/test/data/testkey_rsa4096.pem",
+ "Property the avb_private_key property to be set to the existing filegroup",
+ ":avb_testkey_rsa4096",
proptools.String(fooSystem.FsProps().Avb_private_key),
)
android.AssertStringEquals(
diff --git a/fsgen/fsgen_mutators.go b/fsgen/fsgen_mutators.go
index 1253f0d..7b30264 100644
--- a/fsgen/fsgen_mutators.go
+++ b/fsgen/fsgen_mutators.go
@@ -66,6 +66,10 @@
fsDepsMutex sync.Mutex
// Map of _all_ soong module names to their corresponding installation properties
moduleToInstallationProps map[string]installationProperties
+ // List of prebuilt_* modules that are autogenerated.
+ generatedPrebuiltEtcModuleNames []string
+ // Mapping from a path to an avb key to the name of a filegroup module that contains it
+ avbKeyFilegroups map[string]string
}
type installationProperties struct {
@@ -174,8 +178,10 @@
},
"ramdisk": {},
},
- fsDepsMutex: sync.Mutex{},
- moduleToInstallationProps: map[string]installationProperties{},
+ fsDepsMutex: sync.Mutex{},
+ moduleToInstallationProps: map[string]installationProperties{},
+ generatedPrebuiltEtcModuleNames: generatedPrebuiltEtcModuleNames,
+ avbKeyFilegroups: map[string]string{},
}
if avbpubkeyGenerated {
@@ -284,7 +290,7 @@
soongGeneratedPartitionMap := getAllSoongGeneratedPartitionNames(mctx.Config(), fsGenState.soongGeneratedPartitions)
m := mctx.Module()
if partition, ok := soongGeneratedPartitionMap[m.Name()]; ok {
- depsStruct := generateDepStruct(*fsDeps[partition])
+ depsStruct := generateDepStruct(*fsDeps[partition], fsGenState.generatedPrebuiltEtcModuleNames)
if err := proptools.AppendMatchingProperties(m.GetProperties(), depsStruct, nil); err != nil {
mctx.ModuleErrorf(err.Error())
}
@@ -343,12 +349,12 @@
return false
}
-func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct {
+func generateDepStruct(deps map[string]*depCandidateProps, highPriorityDeps []string) *packagingPropsStruct {
depsStruct := packagingPropsStruct{}
for depName, depProps := range deps {
bitness := getBitness(depProps.Arch)
fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace)
- if isHighPriorityDep(depName) {
+ if android.InList(depName, highPriorityDeps) {
depsStruct.High_priority_deps = append(depsStruct.High_priority_deps, fullyQualifiedDepName)
} else if android.InList("32", bitness) && android.InList("64", bitness) {
// If both 32 and 64 bit variants are enabled for this module
@@ -383,6 +389,7 @@
depsStruct.Multilib.Prefer32.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Prefer32.Deps)
depsStruct.Multilib.Both.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Both.Deps)
depsStruct.Multilib.Common.Deps = android.SortedUniqueStrings(depsStruct.Multilib.Common.Deps)
+ depsStruct.High_priority_deps = android.SortedUniqueStrings(depsStruct.High_priority_deps)
return &depsStruct
}
diff --git a/fsgen/vbmeta_partitions.go b/fsgen/vbmeta_partitions.go
index 52f8ae5..b7fff68 100644
--- a/fsgen/vbmeta_partitions.go
+++ b/fsgen/vbmeta_partitions.go
@@ -53,7 +53,8 @@
var chainedPartitions []string
var partitionTypesHandledByChainedPartitions []string
- for chainedName, props := range partitionVars.ChainedVbmetaPartitions {
+ for _, chainedName := range android.SortedKeys(partitionVars.ChainedVbmetaPartitions) {
+ props := partitionVars.ChainedVbmetaPartitions[chainedName]
chainedName = "vbmeta_" + chainedName
if len(props.Partitions) == 0 {
continue
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 1282bfb..9d2dbc7 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -115,7 +115,7 @@
func (t hostToolDependencyTag) AllowDisabledModuleDependencyProxy(
ctx android.OtherModuleProviderContext, target android.ModuleProxy) bool {
return android.OtherModuleProviderOrDefault(
- ctx, target, android.CommonPropertiesProviderKey).ReplacedByPrebuilt
+ ctx, target, android.CommonModuleInfoKey).ReplacedByPrebuilt
}
var _ android.AllowDisabledModuleDependency = (*hostToolDependencyTag)(nil)
@@ -353,7 +353,7 @@
if h, ok := android.OtherModuleProvider(ctx, module, android.HostToolProviderKey); ok {
// A HostToolProvider provides the path to a tool, which will be copied
// into the sandbox.
- if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonPropertiesProviderKey).Enabled {
+ if !android.OtherModuleProviderOrDefault(ctx, module, android.CommonModuleInfoKey).Enabled {
if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{tool})
} else {
diff --git a/java/app.go b/java/app.go
index 0939d17..8bb73cb 100644
--- a/java/app.go
+++ b/java/app.go
@@ -848,7 +848,7 @@
packageName := packageNameProp.Get()
fileName := "privapp_allowlist_" + packageName + ".xml"
- outPath := android.PathForModuleOut(ctx, fileName).OutputPath
+ outPath := android.PathForModuleOut(ctx, fileName)
ctx.Build(pctx, android.BuildParams{
Rule: modifyAllowlist,
Input: android.PathForModuleSrc(ctx, *a.appProperties.Privapp_allowlist),
@@ -857,7 +857,7 @@
"packageName": packageName,
},
})
- return &outPath
+ return outPath
}
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
diff --git a/java/app_import.go b/java/app_import.go
index 6b88f1c..f044c68 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -88,7 +88,7 @@
hideApexVariantFromMake bool
- provenanceMetaDataFile android.OutputPath
+ provenanceMetaDataFile android.Path
}
type AndroidAppImportProperties struct {
@@ -259,7 +259,7 @@
}
func (a *AndroidAppImport) uncompressEmbeddedJniLibs(
- ctx android.ModuleContext, inputPath android.Path, outputPath android.OutputPath) {
+ ctx android.ModuleContext, inputPath android.Path, outputPath android.WritablePath) {
// Test apps don't need their JNI libraries stored uncompressed. As a matter of fact, messing
// with them may invalidate pre-existing signature data.
if ctx.InstallInTestcases() && (Bool(a.properties.Presigned) || Bool(a.properties.Preprocessed)) {
@@ -345,7 +345,7 @@
// Uncompress JNI libraries in the apk
jnisUncompressed := android.PathForModuleOut(ctx, "jnis-uncompressed", ctx.ModuleName()+".apk")
- a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed.OutputPath)
+ a.uncompressEmbeddedJniLibs(ctx, srcApk, jnisUncompressed)
var pathFragments []string
relInstallPath := String(a.properties.Relative_install_path)
@@ -493,7 +493,7 @@
return a.certificate
}
-func (a *AndroidAppImport) ProvenanceMetaDataFile() android.OutputPath {
+func (a *AndroidAppImport) ProvenanceMetaDataFile() android.Path {
return a.provenanceMetaDataFile
}
diff --git a/java/dex.go b/java/dex.go
index 1f71aee..983377e 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -295,7 +295,7 @@
return d8Flags, d8Deps, artProfileOutput
}
-func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
+func (d *dexer) r8Flags(ctx android.ModuleContext, dexParams *compileDexParams, debugMode bool) (r8Flags []string, r8Deps android.Paths, artProfileOutput *android.OutputPath) {
flags := dexParams.flags
opt := d.dexProperties.Optimize
@@ -363,7 +363,9 @@
r8Flags = append(r8Flags, "--force-proguard-compatibility")
}
- if Bool(opt.Optimize) || Bool(opt.Obfuscate) {
+ // Avoid unnecessary stack frame noise by only injecting source map ids for non-debug
+ // optimized or obfuscated targets.
+ if (Bool(opt.Optimize) || Bool(opt.Obfuscate)) && !debugMode {
// TODO(b/213833843): Allow configuration of the prefix via a build variable.
var sourceFilePrefix = "go/retraceme "
var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\""
@@ -428,17 +430,18 @@
// Adds --art-profile to r8/d8 command.
// r8/d8 will output a generated profile file to match the optimized dex code.
func (d *dexer) addArtProfile(ctx android.ModuleContext, dexParams *compileDexParams) (flags []string, deps android.Paths, artProfileOutputPath *android.OutputPath) {
- if dexParams.artProfileInput != nil {
- artProfileInputPath := android.PathForModuleSrc(ctx, *dexParams.artProfileInput)
- artProfileOutputPathValue := android.PathForModuleOut(ctx, "profile.prof.txt").OutputPath
- artProfileOutputPath = &artProfileOutputPathValue
- flags = []string{
- "--art-profile",
- artProfileInputPath.String(),
- artProfileOutputPath.String(),
- }
- deps = append(deps, artProfileInputPath)
+ if dexParams.artProfileInput == nil {
+ return nil, nil, nil
}
+ artProfileInputPath := android.PathForModuleSrc(ctx, *dexParams.artProfileInput)
+ artProfileOutputPathValue := android.PathForModuleOut(ctx, "profile.prof.txt").OutputPath
+ artProfileOutputPath = &artProfileOutputPathValue
+ flags = []string{
+ "--art-profile",
+ artProfileInputPath.String(),
+ artProfileOutputPath.String(),
+ }
+ deps = append(deps, artProfileInputPath)
return flags, deps, artProfileOutputPath
}
@@ -482,7 +485,8 @@
proguardUsageZip,
proguardConfiguration,
}
- r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams)
+ debugMode := android.InList("--debug", commonFlags)
+ r8Flags, r8Deps, r8ArtProfileOutputPath := d.r8Flags(ctx, dexParams, debugMode)
rule := r8
args := map[string]string{
"r8Flags": strings.Join(append(commonFlags, r8Flags...), " "),
diff --git a/java/java.go b/java/java.go
index 078f578..64ef782 100644
--- a/java/java.go
+++ b/java/java.go
@@ -226,9 +226,9 @@
// Rule for generating device binary default wrapper
deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{
- Command: `echo -e '#!/system/bin/sh\n` +
+ Command: `printf '#!/system/bin/sh\n` +
`export CLASSPATH=/system/framework/$jar_name\n` +
- `exec app_process /$partition/bin $main_class "$$@"'> ${out}`,
+ `exec app_process /$partition/bin $main_class "$$@"\n'> ${out}`,
Description: "Generating device binary wrapper ${jar_name}",
}, "jar_name", "partition", "main_class")
)
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 8b0ca97..d09a02e 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -184,7 +184,7 @@
}
jarArgs := resourcePathsToJarArgs(transitiveSrcFiles)
jarArgs = append(jarArgs, "-srcjar") // Move srcfiles to the right package
- srcjar := android.PathForModuleOut(ctx, ctx.ModuleName()+"-transitive.srcjar").OutputPath
+ srcjar := android.PathForModuleOut(ctx, ctx.ModuleName()+"-transitive.srcjar")
TransformResourcesToJar(ctx, srcjar, jarArgs, transitiveSrcFiles)
// Gather all the fragments dependencies.
diff --git a/java/ravenwood.go b/java/ravenwood.go
index 4c9fdc2..4c43a9f 100644
--- a/java/ravenwood.go
+++ b/java/ravenwood.go
@@ -14,6 +14,8 @@
package java
import (
+ "strconv"
+
"android/soong/android"
"android/soong/tradefed"
@@ -36,6 +38,14 @@
var ravenwoodTestResourceApkTag = dependencyTag{name: "ravenwoodtestresapk"}
var ravenwoodTestInstResourceApkTag = dependencyTag{name: "ravenwoodtest-inst-res-apk"}
+var genManifestProperties = pctx.AndroidStaticRule("genManifestProperties",
+ blueprint.RuleParams{
+ Command: "echo targetSdkVersionInt=$targetSdkVersionInt > $out && " +
+ "echo targetSdkVersionRaw=$targetSdkVersionRaw >> $out && " +
+ "echo packageName=$packageName >> $out && " +
+ "echo instPackageName=$instPackageName >> $out",
+ }, "targetSdkVersionInt", "targetSdkVersionRaw", "packageName", "instPackageName")
+
const ravenwoodUtilsName = "ravenwood-utils"
const ravenwoodRuntimeName = "ravenwood-runtime"
@@ -68,6 +78,17 @@
// the ravenwood test can access it. This APK will be loaded as resources of the test
// instrumentation app itself.
Inst_resource_apk *string
+
+ // Specify the package name of the test target apk.
+ // This will be set to the target Context's package name.
+ // (i.e. Instrumentation.getTargetContext().getPackageName())
+ // If this is omitted, Package_name will be used.
+ Package_name *string
+
+ // Specify the package name of this test module.
+ // This will be set to the test Context's package name.
+ //(i.e. Instrumentation.getContext().getPackageName())
+ Inst_package_name *string
}
type ravenwoodTest struct {
@@ -216,6 +237,27 @@
copyResApk(ravenwoodTestResourceApkTag, "ravenwood-res.apk")
copyResApk(ravenwoodTestInstResourceApkTag, "ravenwood-inst-res.apk")
+ // Generate manifest properties
+ propertiesOutputPath := android.PathForModuleGen(ctx, "ravenwood.properties")
+
+ targetSdkVersion := proptools.StringDefault(r.deviceProperties.Target_sdk_version, "")
+ targetSdkVersionInt := r.TargetSdkVersion(ctx).FinalOrFutureInt() // FinalOrFutureInt may be 10000.
+ packageName := proptools.StringDefault(r.ravenwoodTestProperties.Package_name, "")
+ instPackageName := proptools.StringDefault(r.ravenwoodTestProperties.Inst_package_name, "")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: genManifestProperties,
+ Description: "genManifestProperties",
+ Output: propertiesOutputPath,
+ Args: map[string]string{
+ "targetSdkVersionInt": strconv.Itoa(targetSdkVersionInt),
+ "targetSdkVersionRaw": targetSdkVersion,
+ "packageName": packageName,
+ "instPackageName": instPackageName,
+ },
+ })
+ installProps := ctx.InstallFile(installPath, "ravenwood.properties", propertiesOutputPath)
+ installDeps = append(installDeps, installProps)
+
// Install our JAR with all dependencies
ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.outputFile, installDeps...)
}
diff --git a/java/ravenwood_test.go b/java/ravenwood_test.go
index 5d62ede..6394a9a 100644
--- a/java/ravenwood_test.go
+++ b/java/ravenwood_test.go
@@ -177,6 +177,12 @@
resource_apk: "app2",
inst_resource_apk: "app3",
sdk_version: "test_current",
+ target_sdk_version: "34",
+ package_name: "a.b.c",
+ inst_package_name: "x.y.z",
+ }
+ android_ravenwood_test {
+ name: "ravenwood-test-empty",
}
`)
@@ -199,12 +205,16 @@
// Verify that we've emitted test artifacts in expected location
outputJar := module.Output(installPathPrefix + "/ravenwood-test/ravenwood-test.jar")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-test.config")
+ module.Output(installPathPrefix + "/ravenwood-test/ravenwood.properties")
module.Output(installPathPrefix + "/ravenwood-test/lib64/jni-lib1.so")
module.Output(installPathPrefix + "/ravenwood-test/lib64/libblue.so")
module.Output(installPathPrefix + "/ravenwood-test/lib64/libpink.so")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-res.apk")
module.Output(installPathPrefix + "/ravenwood-test/ravenwood-res-apks/ravenwood-inst-res.apk")
+ module = ctx.ModuleForTests("ravenwood-test-empty", "android_common")
+ module.Output(installPathPrefix + "/ravenwood-test-empty/ravenwood.properties")
+
// ravenwood-runtime*.so are included in the runtime, so it shouldn't be emitted.
for _, o := range module.AllOutputs() {
android.AssertStringDoesNotContain(t, "runtime libs shouldn't be included", o, "/ravenwood-test/lib64/ravenwood-runtime")
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index 679632c..c372db2 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -46,7 +46,7 @@
)
type ProvenanceMetadata interface {
- ProvenanceMetaDataFile() android.OutputPath
+ ProvenanceMetaDataFile() android.Path
}
func init() {
@@ -74,7 +74,7 @@
return false
}
if p, ok := module.(ProvenanceMetadata); ok {
- return p.ProvenanceMetaDataFile().String() != ""
+ return p.ProvenanceMetaDataFile() != nil
}
return false
}
@@ -101,7 +101,7 @@
context.Phony("droidcore", android.PathForPhony(context, "provenance_metadata"))
}
-func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.OutputPath {
+func GenerateArtifactProvenanceMetaData(ctx android.ModuleContext, artifactPath android.Path, installedFile android.InstallPath) android.Path {
onDevicePathOfInstalledFile := android.InstallPathToOnDevicePath(ctx, installedFile)
artifactMetaDataFile := android.PathForIntermediates(ctx, "provenance_metadata", ctx.ModuleDir(), ctx.ModuleName(), "provenance_metadata.textproto")
ctx.Build(pctx, android.BuildParams{
diff --git a/scripts/gen_build_prop.py b/scripts/gen_build_prop.py
index 0b7780e..5f52d6f 100644
--- a/scripts/gen_build_prop.py
+++ b/scripts/gen_build_prop.py
@@ -608,7 +608,7 @@
build_product_prop(args)
case "vendor":
build_vendor_prop(args)
- case "system_dlkm" | "vendor_dlkm" | "odm_dlkm":
+ case "system_dlkm" | "vendor_dlkm" | "odm_dlkm" | "bootimage":
build_prop(args, gen_build_info=False, gen_common_build_props=True, variables=[])
case _:
sys.exit(f"not supported partition {args.partition}")
diff --git a/scripts/ninja_determinism_test.py b/scripts/ninja_determinism_test.py
new file mode 100755
index 0000000..e207b96
--- /dev/null
+++ b/scripts/ninja_determinism_test.py
@@ -0,0 +1,210 @@
+#!/usr/bin/env python3
+
+import asyncio
+import argparse
+import dataclasses
+import hashlib
+import os
+import re
+import socket
+import subprocess
+import sys
+import zipfile
+
+from typing import List
+
+def get_top() -> str:
+ path = '.'
+ while not os.path.isfile(os.path.join(path, 'build/soong/soong_ui.bash')):
+ if os.path.abspath(path) == '/':
+ sys.exit('Could not find android source tree root.')
+ path = os.path.join(path, '..')
+ return os.path.abspath(path)
+
+
+_PRODUCT_REGEX = re.compile(r'([a-zA-Z_][a-zA-Z0-9_]*)(?:(?:-([a-zA-Z_][a-zA-Z0-9_]*))?-(user|userdebug|eng))?')
+
+
+@dataclasses.dataclass(frozen=True)
+class Product:
+ """Represents a TARGET_PRODUCT and TARGET_BUILD_VARIANT."""
+ product: str
+ release: str
+ variant: str
+
+ def __post_init__(self):
+ if not _PRODUCT_REGEX.match(str(self)):
+ raise ValueError(f'Invalid product name: {self}')
+
+ def __str__(self):
+ return self.product + '-' + self.release + '-' + self.variant
+
+
+async def run_make_nothing(product: Product, out_dir: str) -> bool:
+ """Runs a build and returns if it succeeded or not."""
+ with open(os.path.join(out_dir, 'build.log'), 'wb') as f:
+ result = await asyncio.create_subprocess_exec(
+ 'prebuilts/build-tools/linux-x86/bin/nsjail',
+ '-q',
+ '--cwd',
+ os.getcwd(),
+ '-e',
+ '-B',
+ '/',
+ '-B',
+ f'{os.path.abspath(out_dir)}:{os.path.join(os.getcwd(), "out")}',
+ '--time_limit',
+ '0',
+ '--skip_setsid',
+ '--keep_caps',
+ '--disable_clone_newcgroup',
+ '--disable_clone_newnet',
+ '--rlimit_as',
+ 'soft',
+ '--rlimit_core',
+ 'soft',
+ '--rlimit_cpu',
+ 'soft',
+ '--rlimit_fsize',
+ 'soft',
+ '--rlimit_nofile',
+ 'soft',
+ '--proc_rw',
+ '--hostname',
+ socket.gethostname(),
+ '--',
+ 'build/soong/soong_ui.bash',
+ '--make-mode',
+ f'TARGET_PRODUCT={product.product}',
+ f'TARGET_RELEASE={product.release}',
+ f'TARGET_BUILD_VARIANT={product.variant}',
+ '--skip-ninja',
+ 'nothing', stdout=f, stderr=subprocess.STDOUT)
+ return await result.wait() == 0
+
+SUBNINJA_OR_INCLUDE_REGEX = re.compile(rb'\n(?:include|subninja) ')
+
+def find_subninjas_and_includes(contents) -> List[str]:
+ results = []
+ def get_path_from_directive(i):
+ j = contents.find(b'\n', i)
+ if j < 0:
+ path_bytes = contents[i:]
+ else:
+ path_bytes = contents[i:j]
+ path_bytes = path_bytes.removesuffix(b'\r')
+ path = path_bytes.decode()
+ if '$' in path:
+ sys.exit('includes/subninjas with variables are unsupported: '+path)
+ return path
+
+ if contents.startswith(b"include "):
+ results.append(get_path_from_directive(len(b"include ")))
+ elif contents.startswith(b"subninja "):
+ results.append(get_path_from_directive(len(b"subninja ")))
+
+ for match in SUBNINJA_OR_INCLUDE_REGEX.finditer(contents):
+ results.append(get_path_from_directive(match.end()))
+
+ return results
+
+
+def transitively_included_ninja_files(out_dir: str, ninja_file: str, seen):
+ with open(ninja_file, 'rb') as f:
+ contents = f.read()
+
+ results = [ninja_file]
+ seen[ninja_file] = True
+ sub_files = find_subninjas_and_includes(contents)
+ for sub_file in sub_files:
+ sub_file = os.path.join(out_dir, sub_file.removeprefix('out/'))
+ if sub_file not in seen:
+ results.extend(transitively_included_ninja_files(out_dir, sub_file, seen))
+
+ return results
+
+
+def hash_ninja_file(out_dir: str, ninja_file: str, hasher):
+ with open(ninja_file, 'rb') as f:
+ contents = f.read()
+
+ sub_files = find_subninjas_and_includes(contents)
+
+ hasher.update(contents)
+
+ for sub_file in sub_files:
+ hash_ninja_file(out_dir, os.path.join(out_dir, sub_file.removeprefix('out/')), hasher)
+
+
+def hash_files(files: List[str]) -> str:
+ hasher = hashlib.md5()
+ for file in files:
+ with open(file, 'rb') as f:
+ hasher.update(f.read())
+ return hasher.hexdigest()
+
+
+def dist_ninja_files(out_dir: str, zip_name: str, ninja_files: List[str]):
+ dist_dir = os.getenv('DIST_DIR', os.path.join(os.getenv('OUT_DIR', 'out'), 'dist'))
+ os.makedirs(dist_dir, exist_ok=True)
+
+ with open(os.path.join(dist_dir, zip_name), 'wb') as f:
+ with zipfile.ZipFile(f, mode='w') as zf:
+ for ninja_file in ninja_files:
+ zf.write(ninja_file, arcname=os.path.basename(out_dir)+'/out/' + os.path.relpath(ninja_file, out_dir))
+
+
+async def main():
+ parser = argparse.ArgumentParser()
+ args = parser.parse_args()
+
+ os.chdir(get_top())
+ subprocess.check_call(['touch', 'build/soong/Android.bp'])
+
+ product = Product(
+ 'aosp_cf_x86_64_phone',
+ 'trunk_staging',
+ 'userdebug',
+ )
+ os.environ['TARGET_PRODUCT'] = 'aosp_cf_x86_64_phone'
+ os.environ['TARGET_RELEASE'] = 'trunk_staging'
+ os.environ['TARGET_BUILD_VARIANT'] = 'userdebug'
+
+ out_dir1 = os.path.join(os.getenv('OUT_DIR', 'out'), 'determinism_test_out1')
+ out_dir2 = os.path.join(os.getenv('OUT_DIR', 'out'), 'determinism_test_out2')
+
+ os.makedirs(out_dir1, exist_ok=True)
+ os.makedirs(out_dir2, exist_ok=True)
+
+ success1, success2 = await asyncio.gather(
+ run_make_nothing(product, out_dir1),
+ run_make_nothing(product, out_dir2))
+
+ if not success1:
+ with open(os.path.join(out_dir1, 'build.log'), 'r') as f:
+ print(f.read(), file=sys.stderr)
+ sys.exit('build failed')
+ if not success2:
+ with open(os.path.join(out_dir2, 'build.log'), 'r') as f:
+ print(f.read(), file=sys.stderr)
+ sys.exit('build failed')
+
+ ninja_files1 = transitively_included_ninja_files(out_dir1, os.path.join(out_dir1, f'combined-{product.product}.ninja'), {})
+ ninja_files2 = transitively_included_ninja_files(out_dir2, os.path.join(out_dir2, f'combined-{product.product}.ninja'), {})
+
+ dist_ninja_files(out_dir1, 'determinism_test_files_1.zip', ninja_files1)
+ dist_ninja_files(out_dir2, 'determinism_test_files_2.zip', ninja_files2)
+
+ hash1 = hash_files(ninja_files1)
+ hash2 = hash_files(ninja_files2)
+
+ if hash1 != hash2:
+ sys.exit("ninja files were not deterministic! See disted determinism_test_files_1/2.zip")
+
+ print("Success, ninja files were deterministic")
+
+
+if __name__ == "__main__":
+ asyncio.run(main())
+
+
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 320e97f..7f5a426 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -204,7 +204,7 @@
func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
}
-func (s *ShBinary) OutputFile() android.OutputPath {
+func (s *ShBinary) OutputFile() android.Path {
return s.outputFilePath
}
diff --git a/ui/build/androidmk_denylist.go b/ui/build/androidmk_denylist.go
index c54d55f..6f57cb1 100644
--- a/ui/build/androidmk_denylist.go
+++ b/ui/build/androidmk_denylist.go
@@ -29,6 +29,9 @@
"device/google_car/",
"device/sample/",
"frameworks/",
+ "hardware/libhardware/",
+ "hardware/libhardware_legacy/",
+ "hardware/ril/",
// Do not block other directories in kernel/, see b/319658303.
"kernel/configs/",
"kernel/prebuilts/",
@@ -37,8 +40,10 @@
"libnativehelper/",
"packages/",
"pdk/",
+ "platform_testing/",
"prebuilts/",
"sdk/",
+ "system/",
"test/",
"trusty/",
// Add back toolchain/ once defensive Android.mk files are removed
diff --git a/ui/build/soong.go b/ui/build/soong.go
index e6d01dd..0963f76 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -433,13 +433,13 @@
}
}
-func updateSymlinks(ctx Context, dir, prevCWD, cwd string) error {
+func updateSymlinks(ctx Context, dir, prevCWD, cwd string, updateSemaphore chan struct{}) error {
defer symlinkWg.Done()
visit := func(path string, d fs.DirEntry, err error) error {
if d.IsDir() && path != dir {
symlinkWg.Add(1)
- go updateSymlinks(ctx, path, prevCWD, cwd)
+ go updateSymlinks(ctx, path, prevCWD, cwd, updateSemaphore)
return filepath.SkipDir
}
f, err := d.Info()
@@ -470,12 +470,27 @@
return nil
}
+ <-updateSemaphore
+ defer func() { updateSemaphore <- struct{}{} }()
if err := filepath.WalkDir(dir, visit); err != nil {
return err
}
return nil
}
+// b/376466642: If the concurrency of updateSymlinks is unbounded, Go's runtime spawns a
+// theoretically unbounded number of threads to handle blocking syscalls. This causes the runtime to
+// panic due to hitting thread limits in rare cases. Limiting to GOMAXPROCS concurrent symlink
+// updates should make this a non-issue.
+func newUpdateSemaphore() chan struct{} {
+ numPermits := runtime.GOMAXPROCS(0)
+ c := make(chan struct{}, numPermits)
+ for i := 0; i < numPermits; i++ {
+ c <- struct{}{}
+ }
+ return c
+}
+
func fixOutDirSymlinks(ctx Context, config Config, outDir string) error {
cwd, err := os.Getwd()
if err != nil {
@@ -508,7 +523,7 @@
}
symlinkWg.Add(1)
- if err := updateSymlinks(ctx, outDir, prevCWD, cwd); err != nil {
+ if err := updateSymlinks(ctx, outDir, prevCWD, cwd, newUpdateSemaphore()); err != nil {
return err
}
symlinkWg.Wait()
diff --git a/ui/metrics/Android.bp b/ui/metrics/Android.bp
index 77871fc..591e3cc 100644
--- a/ui/metrics/Android.bp
+++ b/ui/metrics/Android.bp
@@ -26,6 +26,7 @@
"soong-ui-metrics_proto",
"soong-ui-mk_metrics_proto",
"soong-shared",
+ "soong-ui-metrics_combined_proto",
],
srcs: [
"hostinfo.go",
@@ -63,6 +64,19 @@
}
bootstrap_go_package {
+ name: "soong-ui-metrics_combined_proto",
+ pkgPath: "android/soong/ui/metrics/combined_metrics_proto",
+ deps: [
+ "golang-protobuf-reflect-protoreflect",
+ "golang-protobuf-runtime-protoimpl",
+ "soong-cmd-find_input_delta-proto",
+ ],
+ srcs: [
+ "metrics_proto/metrics.pb.go",
+ ],
+}
+
+bootstrap_go_package {
name: "soong-ui-metrics_upload_proto",
pkgPath: "android/soong/ui/metrics/upload_proto",
deps: [
diff --git a/ui/metrics/metrics_proto/combined_metrics.pb.go b/ui/metrics/metrics_proto/combined_metrics.pb.go
new file mode 100644
index 0000000..f49d64d
--- /dev/null
+++ b/ui/metrics/metrics_proto/combined_metrics.pb.go
@@ -0,0 +1,239 @@
+// Copyright 2018 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.33.0
+// protoc v3.21.12
+// source: combined_metrics.proto
+
+package metrics_proto
+
+import (
+ find_input_delta_proto "android/soong/cmd/find_input_delta/find_input_delta_proto"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// These field numbers are also found in the inner message declarations.
+// We verify that the values are the same, and that every enum value is checked
+// in combined_metrics_test.go.
+// Do not change this enum without also updating:
+// - the submessage's .proto file
+// - combined_metrics_test.go
+type FieldNumbers int32
+
+const (
+ FieldNumbers_FIELD_NUMBERS_UNSPECIFIED FieldNumbers = 0
+ FieldNumbers_FIELD_NUMBERS_FILE_LIST FieldNumbers = 1
+)
+
+// Enum value maps for FieldNumbers.
+var (
+ FieldNumbers_name = map[int32]string{
+ 0: "FIELD_NUMBERS_UNSPECIFIED",
+ 1: "FIELD_NUMBERS_FILE_LIST",
+ }
+ FieldNumbers_value = map[string]int32{
+ "FIELD_NUMBERS_UNSPECIFIED": 0,
+ "FIELD_NUMBERS_FILE_LIST": 1,
+ }
+)
+
+func (x FieldNumbers) Enum() *FieldNumbers {
+ p := new(FieldNumbers)
+ *p = x
+ return p
+}
+
+func (x FieldNumbers) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (FieldNumbers) Descriptor() protoreflect.EnumDescriptor {
+ return file_combined_metrics_proto_enumTypes[0].Descriptor()
+}
+
+func (FieldNumbers) Type() protoreflect.EnumType {
+ return &file_combined_metrics_proto_enumTypes[0]
+}
+
+func (x FieldNumbers) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *FieldNumbers) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = FieldNumbers(num)
+ return nil
+}
+
+// Deprecated: Use FieldNumbers.Descriptor instead.
+func (FieldNumbers) EnumDescriptor() ([]byte, []int) {
+ return file_combined_metrics_proto_rawDescGZIP(), []int{0}
+}
+
+type SoongCombinedMetrics struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // cmd/find_input_delta/find_input_delta_proto.FileList
+ FileList *find_input_delta_proto.FileList `protobuf:"bytes,1,opt,name=file_list,json=fileList" json:"file_list,omitempty"`
+}
+
+func (x *SoongCombinedMetrics) Reset() {
+ *x = SoongCombinedMetrics{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_combined_metrics_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *SoongCombinedMetrics) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SoongCombinedMetrics) ProtoMessage() {}
+
+func (x *SoongCombinedMetrics) ProtoReflect() protoreflect.Message {
+ mi := &file_combined_metrics_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use SoongCombinedMetrics.ProtoReflect.Descriptor instead.
+func (*SoongCombinedMetrics) Descriptor() ([]byte, []int) {
+ return file_combined_metrics_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *SoongCombinedMetrics) GetFileList() *find_input_delta_proto.FileList {
+ if x != nil {
+ return x.FileList
+ }
+ return nil
+}
+
+var File_combined_metrics_proto protoreflect.FileDescriptor
+
+var file_combined_metrics_proto_rawDesc = []byte{
+ 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x1a, 0x3b, 0x63,
+ 0x6d, 0x64, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65,
+ 0x6c, 0x74, 0x61, 0x2f, 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64,
+ 0x65, 0x6c, 0x74, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x5f,
+ 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, 0x14, 0x53, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4d, 0x65, 0x74, 0x72, 0x69,
+ 0x63, 0x73, 0x12, 0x45, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e,
+ 0x66, 0x69, 0x6e, 0x64, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x74, 0x61,
+ 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x52,
+ 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x2a, 0x4a, 0x0a, 0x0c, 0x46, 0x69, 0x65,
+ 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x49, 0x45,
+ 0x4c, 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45,
+ 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x49, 0x45, 0x4c,
+ 0x44, 0x5f, 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x53, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x4c,
+ 0x49, 0x53, 0x54, 0x10, 0x01, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64,
+ 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+}
+
+var (
+ file_combined_metrics_proto_rawDescOnce sync.Once
+ file_combined_metrics_proto_rawDescData = file_combined_metrics_proto_rawDesc
+)
+
+func file_combined_metrics_proto_rawDescGZIP() []byte {
+ file_combined_metrics_proto_rawDescOnce.Do(func() {
+ file_combined_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_combined_metrics_proto_rawDescData)
+ })
+ return file_combined_metrics_proto_rawDescData
+}
+
+var file_combined_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_combined_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_combined_metrics_proto_goTypes = []interface{}{
+ (FieldNumbers)(0), // 0: soong_build_metrics.FieldNumbers
+ (*SoongCombinedMetrics)(nil), // 1: soong_build_metrics.SoongCombinedMetrics
+ (*find_input_delta_proto.FileList)(nil), // 2: android.find_input_delta_proto.FileList
+}
+var file_combined_metrics_proto_depIdxs = []int32{
+ 2, // 0: soong_build_metrics.SoongCombinedMetrics.file_list:type_name -> android.find_input_delta_proto.FileList
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_combined_metrics_proto_init() }
+func file_combined_metrics_proto_init() {
+ if File_combined_metrics_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_combined_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*SoongCombinedMetrics); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_combined_metrics_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_combined_metrics_proto_goTypes,
+ DependencyIndexes: file_combined_metrics_proto_depIdxs,
+ EnumInfos: file_combined_metrics_proto_enumTypes,
+ MessageInfos: file_combined_metrics_proto_msgTypes,
+ }.Build()
+ File_combined_metrics_proto = out.File
+ file_combined_metrics_proto_rawDesc = nil
+ file_combined_metrics_proto_goTypes = nil
+ file_combined_metrics_proto_depIdxs = nil
+}
diff --git a/ui/metrics/metrics_proto/combined_metrics.proto b/ui/metrics/metrics_proto/combined_metrics.proto
new file mode 100644
index 0000000..3cd9a53
--- /dev/null
+++ b/ui/metrics/metrics_proto/combined_metrics.proto
@@ -0,0 +1,36 @@
+// Copyright 2018 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.
+
+syntax = "proto2";
+
+package soong_build_metrics;
+option go_package = "android/soong/ui/metrics/metrics_proto";
+
+import "cmd/find_input_delta/find_input_delta_proto/file_list.proto";
+
+// These field numbers are also found in the inner message declarations.
+// We verify that the values are the same, and that every enum value is checked
+// in combined_metrics_test.go.
+// Do not change this enum without also updating:
+// - the submessage's .proto file
+// - combined_metrics_test.go
+enum FieldNumbers {
+ FIELD_NUMBERS_UNSPECIFIED = 0;
+ FIELD_NUMBERS_FILE_LIST = 1;
+}
+
+message SoongCombinedMetrics {
+ // cmd/find_input_delta/find_input_delta_proto.FileList
+ optional android.find_input_delta_proto.FileList file_list = 1;
+}
diff --git a/ui/metrics/metrics_proto/combined_metrics_test.go b/ui/metrics/metrics_proto/combined_metrics_test.go
new file mode 100644
index 0000000..eedb12a
--- /dev/null
+++ b/ui/metrics/metrics_proto/combined_metrics_test.go
@@ -0,0 +1,33 @@
+package metrics_proto
+
+import (
+ "testing"
+
+ find_input_delta_proto "android/soong/cmd/find_input_delta/find_input_delta_proto"
+)
+
+func TestCombinedMetricsMessageNums(t *testing.T) {
+ testCases := []struct {
+ Name string
+ FieldNumbers map[string]int32
+ }{
+ {
+ Name: "find_input_delta_proto",
+ FieldNumbers: find_input_delta_proto.FieldNumbers_value,
+ },
+ }
+ verifiedMap := make(map[string]bool)
+ for _, tc := range testCases {
+ for k, v := range tc.FieldNumbers {
+ if FieldNumbers_value[k] != v {
+ t.Errorf("%s: Expected FieldNumbers.%s == %v, found %v", tc.Name, k, FieldNumbers_value[k], v)
+ }
+ verifiedMap[k] = true
+ }
+ }
+ for k, v := range FieldNumbers_value {
+ if !verifiedMap[k] {
+ t.Errorf("No test case verifies FieldNumbers.%s=%v", k, v)
+ }
+ }
+}
diff --git a/ui/metrics/metrics_proto/regen.sh b/ui/metrics/metrics_proto/regen.sh
index 8eb2d74..5e5f9b8 100755
--- a/ui/metrics/metrics_proto/regen.sh
+++ b/ui/metrics/metrics_proto/regen.sh
@@ -12,6 +12,6 @@
die "could not find aprotoc. ${error_msg}"
fi
-if ! aprotoc --go_out=paths=source_relative:. metrics.proto; then
+if ! aprotoc --go_out=paths=source_relative:. -I .:../../.. metrics.proto combined_metrics.proto; then
die "build failed. ${error_msg}"
fi