Support long commands in RuleBuilder
If a command exceeds the linux max command line length, it will be put
into a script instead.
Fixes: 380945706
Test: Presubmits
Change-Id: I9bc4b293d6d638b38e7fb11e6c2bc35196306d9f
diff --git a/android/packaging.go b/android/packaging.go
index dcd8844..d96cccd 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -18,7 +18,6 @@
"fmt"
"path/filepath"
"sort"
- "strings"
"github.com/google/blueprint"
"github.com/google/blueprint/gobtools"
@@ -594,10 +593,6 @@
}
seenDir := make(map[string]bool)
- preparerPath := PathForModuleOut(ctx, "preparer.sh")
- cmd := builder.Command().Tool(preparerPath)
- var sb strings.Builder
- sb.WriteString("set -e\n")
dirs := make([]WritablePath, 0, len(dirsToSpecs))
for dir, _ := range dirsToSpecs {
@@ -616,22 +611,19 @@
entries = append(entries, ps.relPathInPackage)
if _, ok := seenDir[destDir]; !ok {
seenDir[destDir] = true
- sb.WriteString(fmt.Sprintf("mkdir -p %s\n", destDir))
+ builder.Command().Textf("mkdir -p %s", destDir)
}
if ps.symlinkTarget == "" {
- cmd.Implicit(ps.srcPath)
- sb.WriteString(fmt.Sprintf("cp %s %s\n", ps.srcPath, destPath))
+ builder.Command().Text("cp").Input(ps.srcPath).Text(destPath)
} else {
- sb.WriteString(fmt.Sprintf("ln -sf %s %s\n", ps.symlinkTarget, destPath))
+ builder.Command().Textf("ln -sf %s %s", ps.symlinkTarget, destPath)
}
if ps.executable {
- sb.WriteString(fmt.Sprintf("chmod a+x %s\n", destPath))
+ builder.Command().Textf("chmod a+x %s", destPath)
}
}
}
- WriteExecutableFileRuleVerbatim(ctx, preparerPath, sb.String())
-
return entries
}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 83f8b99..89cb9cf 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -853,6 +853,18 @@
pool = localPool
}
+ // If the command length is getting close to linux's maximum, dump it to a file, which allows
+ // for longer commands.
+ if len(commandString) > 100000 {
+ hasher := sha256.New()
+ hasher.Write([]byte(output.String()))
+ script := PathForOutput(r.ctx, "rule_builder_scripts", fmt.Sprintf("%x.sh", hasher.Sum(nil)))
+ commandString = "set -eu\n\n" + commandString + "\n"
+ WriteExecutableFileRuleVerbatim(r.ctx, script, commandString)
+ inputs = append(inputs, script)
+ commandString = script.String()
+ }
+
commandString = proptools.NinjaEscape(commandString)
args_vars := make([]string, len(r.args))
diff --git a/filesystem/aconfig_files.go b/filesystem/aconfig_files.go
index 7de404f..c80ae03 100644
--- a/filesystem/aconfig_files.go
+++ b/filesystem/aconfig_files.go
@@ -16,7 +16,6 @@
import (
"android/soong/android"
- "strings"
"github.com/google/blueprint/proptools"
)
@@ -26,57 +25,34 @@
return
}
- aconfigFlagsBuilderPath := android.PathForModuleOut(ctx, "aconfig_flags_builder.sh")
- aconfigToolPath := ctx.Config().HostToolPath(ctx, "aconfig")
- cmd := builder.Command().Tool(aconfigFlagsBuilderPath).Implicit(aconfigToolPath)
-
- var caches []string
+ var caches []android.Path
for _, ps := range specs {
- cmd.Implicits(ps.GetAconfigPaths())
- caches = append(caches, ps.GetAconfigPaths().Strings()...)
+ caches = append(caches, ps.GetAconfigPaths()...)
}
- caches = android.SortedUniqueStrings(caches)
-
- var sbCaches strings.Builder
- for _, cache := range caches {
- sbCaches.WriteString(" --cache ")
- sbCaches.WriteString(cache)
- sbCaches.WriteString(" \\\n")
- }
- sbCaches.WriteRune('\n')
-
- var sb strings.Builder
- sb.WriteString("set -e\n")
+ caches = android.SortedUniquePaths(caches)
installAconfigFlagsPath := dir.Join(ctx, "etc", "aconfig_flags.pb")
- sb.WriteString(aconfigToolPath.String())
- sb.WriteString(" dump-cache --dedup --format protobuf --out ")
- sb.WriteString(installAconfigFlagsPath.String())
- sb.WriteString(" --filter container:")
- sb.WriteString(f.PartitionType())
- sb.WriteString(" \\\n")
- sb.WriteString(sbCaches.String())
- cmd.ImplicitOutput(installAconfigFlagsPath)
+ cmd := builder.Command().
+ BuiltTool("aconfig").
+ Text(" dump-cache --dedup --format protobuf --out").
+ Output(installAconfigFlagsPath).
+ Textf("--filter container:%s", f.PartitionType())
+ for _, cache := range caches {
+ cmd.FlagWithInput("--cache ", cache)
+ }
f.appendToEntry(ctx, installAconfigFlagsPath)
installAconfigStorageDir := dir.Join(ctx, "etc", "aconfig")
- sb.WriteString("mkdir -p ")
- sb.WriteString(installAconfigStorageDir.String())
- sb.WriteRune('\n')
+ builder.Command().Text("mkdir -p").Text(installAconfigStorageDir.String())
generatePartitionAconfigStorageFile := func(fileType, fileName string) {
outputPath := installAconfigStorageDir.Join(ctx, fileName)
- sb.WriteString(aconfigToolPath.String())
- sb.WriteString(" create-storage --container ")
- sb.WriteString(f.PartitionType())
- sb.WriteString(" --file ")
- sb.WriteString(fileType)
- sb.WriteString(" --out ")
- sb.WriteString(outputPath.String())
- sb.WriteString(" --cache ")
- sb.WriteString(installAconfigFlagsPath.String())
- sb.WriteRune('\n')
- cmd.ImplicitOutput(outputPath)
+ builder.Command().
+ BuiltTool("aconfig").
+ FlagWithArg("create-storage --container ", f.PartitionType()).
+ FlagWithArg("--file ", fileType).
+ FlagWithOutput("--out ", outputPath).
+ FlagWithArg("--cache ", installAconfigFlagsPath.String())
f.appendToEntry(ctx, outputPath)
}
@@ -86,6 +62,4 @@
generatePartitionAconfigStorageFile("flag_val", "flag.val")
generatePartitionAconfigStorageFile("flag_info", "flag.info")
}
-
- android.WriteExecutableFileRuleVerbatim(ctx, aconfigFlagsBuilderPath, sb.String())
}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 746e4de..72a5211 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -16,6 +16,7 @@
import (
"os"
+ "strings"
"testing"
"android/soong/android"
@@ -182,10 +183,14 @@
module := result.ModuleForTests("myfilesystem", "android_common")
output := module.Output("out/soong/.intermediates/myfilesystem/android_common/root/system/etc/linker.config.pb")
+ fullCommand := output.RuleParams.Command
+ startIndex := strings.Index(fullCommand, "conv_linker_config")
+ linkerConfigCommand := fullCommand[startIndex:]
+
android.AssertStringDoesContain(t, "linker.config.pb should have libfoo",
- output.RuleParams.Command, "libfoo.so")
+ linkerConfigCommand, "libfoo.so")
android.AssertStringDoesNotContain(t, "linker.config.pb should not have libbar",
- output.RuleParams.Command, "libbar.so")
+ linkerConfigCommand, "libbar.so")
}
func registerComponent(ctx android.RegistrationContext) {
diff --git a/filesystem/fsverity_metadata.go b/filesystem/fsverity_metadata.go
index 3119f2f..ef46067 100644
--- a/filesystem/fsverity_metadata.go
+++ b/filesystem/fsverity_metadata.go
@@ -66,62 +66,44 @@
return
}
- fsverityBuilderPath := android.PathForModuleOut(ctx, "fsverity_builder.sh")
- metadataGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_metadata_generator")
fsverityPath := ctx.Config().HostToolPath(ctx, "fsverity")
- cmd := builder.Command().Tool(fsverityBuilderPath)
-
// STEP 1: generate .fsv_meta
var sb strings.Builder
sb.WriteString("set -e\n")
- cmd.Implicit(metadataGeneratorPath).Implicit(fsverityPath)
for _, spec := range matchedSpecs {
// srcPath is copied by CopySpecsToDir()
srcPath := rebasedDir.Join(ctx, spec.RelPathInPackage())
destPath := rebasedDir.Join(ctx, spec.RelPathInPackage()+".fsv_meta")
- sb.WriteString(metadataGeneratorPath.String())
- sb.WriteString(" --fsverity-path ")
- sb.WriteString(fsverityPath.String())
- sb.WriteString(" --signature none --hash-alg sha256 --output ")
- sb.WriteString(destPath.String())
- sb.WriteRune(' ')
- sb.WriteString(srcPath.String())
- sb.WriteRune('\n')
+ builder.Command().
+ BuiltTool("fsverity_metadata_generator").
+ FlagWithInput("--fsverity-path ", fsverityPath).
+ FlagWithArg("--signature ", "none").
+ FlagWithArg("--hash-alg ", "sha256").
+ FlagWithArg("--output ", destPath.String()).
+ Text(srcPath.String())
f.appendToEntry(ctx, destPath)
}
// STEP 2: generate signed BuildManifest.apk
// STEP 2-1: generate build_manifest.pb
- assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
- manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
- manifestGeneratorPath := ctx.Config().HostToolPath(ctx, "fsverity_manifest_generator")
- cmd.Implicit(manifestGeneratorPath)
- sb.WriteString("rm -rf ")
- sb.WriteString(assetsPath.String())
- sb.WriteString(" && mkdir -p ")
- sb.WriteString(assetsPath.String())
- sb.WriteRune('\n')
- sb.WriteString(manifestGeneratorPath.String())
- sb.WriteString(" --fsverity-path ")
- sb.WriteString(fsverityPath.String())
- sb.WriteString(" --base-dir ")
- sb.WriteString(rootDir.String())
- sb.WriteString(" --output ")
- sb.WriteString(manifestPbPath.String())
- sb.WriteRune(' ')
- f.appendToEntry(ctx, manifestPbPath)
-
manifestGeneratorListPath := android.PathForModuleOut(ctx, "fsverity_manifest.list")
f.writeManifestGeneratorListFile(ctx, manifestGeneratorListPath, matchedSpecs, rebasedDir)
- sb.WriteRune('@')
- sb.WriteString(manifestGeneratorListPath.String())
- sb.WriteRune('\n')
- cmd.Implicit(manifestGeneratorListPath)
+ assetsPath := android.PathForModuleOut(ctx, "fsverity_manifest/assets")
+ manifestPbPath := assetsPath.Join(ctx, "build_manifest.pb")
+ builder.Command().Text("rm -rf " + assetsPath.String())
+ builder.Command().Text("mkdir -p " + assetsPath.String())
+ builder.Command().
+ BuiltTool("fsverity_manifest_generator").
+ FlagWithInput("--fsverity-path ", fsverityPath).
+ FlagWithArg("--base-dir ", rootDir.String()).
+ FlagWithArg("--output ", manifestPbPath.String()).
+ FlagWithInput("@", manifestGeneratorListPath)
+
+ f.appendToEntry(ctx, manifestPbPath)
f.appendToEntry(ctx, manifestGeneratorListPath)
// STEP 2-2: generate BuildManifest.apk (unsigned)
- aapt2Path := ctx.Config().HostToolPath(ctx, "aapt2")
apkNameSuffix := ""
if f.PartitionType() == "system_ext" {
//https://source.corp.google.com/h/googleplex-android/platform/build/+/e392d2b486c2d4187b20a72b1c67cc737ecbcca5:core/Makefile;l=3410;drc=ea8f34bc1d6e63656b4ec32f2391e9d54b3ebb6b;bpv=1;bpt=0
@@ -131,55 +113,38 @@
idsigPath := rebasedDir.Join(ctx, "etc", "security", "fsverity", fmt.Sprintf("BuildManifest%s.apk.idsig", apkNameSuffix))
manifestTemplatePath := android.PathForSource(ctx, "system/security/fsverity/AndroidManifest.xml")
libs := android.PathsForModuleSrc(ctx, f.properties.Fsverity.Libs)
- cmd.Implicit(aapt2Path)
- cmd.Implicit(manifestTemplatePath)
- cmd.Implicits(libs)
- cmd.ImplicitOutput(apkPath)
- sb.WriteString(aapt2Path.String())
- sb.WriteString(" link -o ")
- sb.WriteString(apkPath.String())
- sb.WriteString(" -A ")
- sb.WriteString(assetsPath.String())
- for _, lib := range libs {
- sb.WriteString(" -I ")
- sb.WriteString(lib.String())
- }
minSdkVersion := ctx.Config().PlatformSdkCodename()
if minSdkVersion == "REL" {
minSdkVersion = ctx.Config().PlatformSdkVersion().String()
}
- sb.WriteString(" --min-sdk-version ")
- sb.WriteString(minSdkVersion)
- sb.WriteString(" --version-code ")
- sb.WriteString(ctx.Config().PlatformSdkVersion().String())
- sb.WriteString(" --version-name ")
- sb.WriteString(ctx.Config().AppsDefaultVersionName())
- sb.WriteString(" --manifest ")
- sb.WriteString(manifestTemplatePath.String())
- sb.WriteString(" --rename-manifest-package com.android.security.fsverity_metadata.")
- sb.WriteString(f.partitionName())
- sb.WriteRune('\n')
+
+ unsignedApkCommand := builder.Command().
+ BuiltTool("aapt2").
+ Text("link").
+ FlagWithOutput("-o ", apkPath).
+ FlagWithArg("-A ", assetsPath.String())
+ for _, lib := range libs {
+ unsignedApkCommand.FlagWithInput("-I ", lib)
+ }
+ unsignedApkCommand.
+ FlagWithArg("--min-sdk-version ", minSdkVersion).
+ FlagWithArg("--version-code ", ctx.Config().PlatformSdkVersion().String()).
+ FlagWithArg("--version-name ", ctx.Config().AppsDefaultVersionName()).
+ FlagWithInput("--manifest ", manifestTemplatePath).
+ Text(" --rename-manifest-package com.android.security.fsverity_metadata." + f.partitionName())
f.appendToEntry(ctx, apkPath)
// STEP 2-3: sign BuildManifest.apk
- apksignerPath := ctx.Config().HostToolPath(ctx, "apksigner")
pemPath, keyPath := ctx.Config().DefaultAppCertificate(ctx)
- cmd.Implicit(apksignerPath)
- cmd.Implicit(pemPath)
- cmd.Implicit(keyPath)
- cmd.ImplicitOutput(idsigPath)
- sb.WriteString(apksignerPath.String())
- sb.WriteString(" sign --in ")
- sb.WriteString(apkPath.String())
- sb.WriteString(" --cert ")
- sb.WriteString(pemPath.String())
- sb.WriteString(" --key ")
- sb.WriteString(keyPath.String())
- sb.WriteRune('\n')
+ builder.Command().
+ BuiltTool("apksigner").
+ Text("sign").
+ FlagWithArg("--in ", apkPath.String()).
+ FlagWithInput("--cert ", pemPath).
+ FlagWithInput("--key ", keyPath).
+ ImplicitOutput(idsigPath)
f.appendToEntry(ctx, idsigPath)
-
- android.WriteExecutableFileRuleVerbatim(ctx, fsverityBuilderPath, sb.String())
}