apex: invoke `conv_linker_config validate` as validation

`conv_linker_config validate` command is used to validate the linker
configuration embedded in APEX to detect common mistakes.

For example, when used in APEX, linker configuration can't set
provideLibs/requireLibs. For APEX, there are
provideSharedLibs/requireSharedLibs in APEX manifest for that purpose.

One might make mistake by setting provideLibs in linker config.
Now, when these unsupported properties are set, there'll be build-time
error like:

 // set provideLibs key in com.android.art's linker config.
 $ m com.android.art
   ...image.apex/etc/linker.config.pb: provideLibs is set. Use provideSharedLibs in apex_manifest

Bug: 264341796
Test: m com.android.art (see above)
Change-Id: Ibaf7322616ad333569e6d721680f3d72243402a2
diff --git a/apex/builder.go b/apex/builder.go
index 4b42b74..cd7599a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -75,6 +75,7 @@
 	pctx.HostBinToolVariable("deapexer", "deapexer")
 	pctx.HostBinToolVariable("debugfs_static", "debugfs_static")
 	pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh")
+	pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
 }
 
 var (
@@ -222,6 +223,12 @@
 		CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"},
 		Description: "run apex_sepolicy_tests",
 	})
+
+	apexLinkerconfigValidationRule = pctx.StaticRule("apexLinkerconfigValidationRule", blueprint.RuleParams{
+		Command:     `${conv_linker_config} validate --type apex ${image_dir} && touch ${out}`,
+		CommandDeps: []string{"${conv_linker_config}"},
+		Description: "run apex_linkerconfig_validation",
+	}, "image_dir")
 )
 
 // buildManifest creates buile rules to modify the input apex_manifest.json to add information
@@ -843,6 +850,7 @@
 		args["outCommaList"] = signedOutputFile.String()
 	}
 	var validations android.Paths
+	validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath))
 	// TODO(b/279688635) deapexer supports [ext4]
 	if suffix == imageApexSuffix && ext4 == a.payloadFsType {
 		validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath))
@@ -1097,6 +1105,19 @@
 	return cannedFsConfig.OutputPath
 }
 
+func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path {
+	timestamp := android.PathForModuleOut(ctx, "apex_linkerconfig_validation.timestamp")
+	ctx.Build(pctx, android.BuildParams{
+		Rule:   apexLinkerconfigValidationRule,
+		Input:  apexFile,
+		Output: timestamp,
+		Args: map[string]string{
+			"image_dir": imageDir.String(),
+		},
+	})
+	return timestamp
+}
+
 // Runs apex_sepolicy_tests
 //
 // $ deapexer list -Z {apex_file} > {file_contexts}