Materialize the copy commands of an APEX rule as a Ninja response file.

For some APEX packages (i.e. the Runtime Testing APEX), the set of
files to copy can be so large that the copy commands (which are part
of the Ninja shell command executed for an APEX package) may exceed
the maximum length of argument to the exec() functions (ARG_MAX). To
work around this limitation, record these copy commands in a Ninja
response file (rspfile) and `source` this file in the Ninja command to
execute them.

Test: m nothing (`apex/apex_test.go` amended)
Test: m com.android.runtime.testing (with CL https://android-review.googlesource.com/c/platform/art/+/1008034/ cherry-picked)
Bug: 129534335
Change-Id: I09ff2d9cf66bfd4cbc12cb724a45d455d08da0b2
diff --git a/apex/apex.go b/apex/apex.go
index 4729e0f..86385b7 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -52,7 +52,7 @@
 	// TODO(b/114327326): automate the generation of file_contexts
 	apexRule = pctx.StaticRule("apexRule", blueprint.RuleParams{
 		Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
-			`(${copy_commands}) && ` +
+			`(. ${out}.copy_commands) && ` +
 			`APEXER_TOOL_PATH=${tool_path} ` +
 			`${apexer} --force --manifest ${manifest} ` +
 			`--file_contexts ${file_contexts} ` +
@@ -62,18 +62,22 @@
 		CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}",
 			"${mke2fs}", "${resize2fs}", "${sefcontext_compile}",
 			"${soong_zip}", "${zipalign}", "${aapt2}", "prebuilts/sdk/current/public/android.jar"},
-		Description: "APEX ${image_dir} => ${out}",
+		Rspfile:        "${out}.copy_commands",
+		RspfileContent: "${copy_commands}",
+		Description:    "APEX ${image_dir} => ${out}",
 	}, "tool_path", "image_dir", "copy_commands", "manifest", "file_contexts", "canned_fs_config", "key", "opt_flags")
 
 	zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
 		Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
-			`(${copy_commands}) && ` +
+			`(. ${out}.copy_commands) && ` +
 			`APEXER_TOOL_PATH=${tool_path} ` +
 			`${apexer} --force --manifest ${manifest} ` +
 			`--payload_type zip ` +
 			`${image_dir} ${out} `,
-		CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"},
-		Description: "ZipAPEX ${image_dir} => ${out}",
+		CommandDeps:    []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"},
+		Rspfile:        "${out}.copy_commands",
+		RspfileContent: "${copy_commands}",
+		Description:    "ZipAPEX ${image_dir} => ${out}",
 	}, "tool_path", "image_dir", "copy_commands", "manifest")
 
 	apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",