Put dependency in apex_manifest.json
To generate ld.config.txt dynamically(b/123722631), each APEX should
provide some dependency information:
a) list of libraries which other APEXes(or system) can use from this apex
b) list of libraries which this apex uses from other APEXes(or system)
This change puts dependency information in apex_manifest.json at
build-time with two additional keys:
a) provideNativeLibs
b) requireNativeLibs
Bug: 138695532
Test: m (runs soong tests)
Test: find $OUT/apex -name apex_manifest.json -exec cat {} \;
(shows contents of apex_manifest.json files)
Change-Id: Iaad12c8c35454222ad177ce923cce76ef12a8a5a
diff --git a/apex/apex.go b/apex/apex.go
index 441911b..5ca9d7d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -46,6 +46,14 @@
Description: "fs_config ${out}",
}, "ro_paths", "exec_paths")
+ injectApexDependency = pctx.StaticRule("injectApexDependency", blueprint.RuleParams{
+ Command: `rm -f $out && ${jsonmodify} $in ` +
+ `-a provideNativeLibs ${provideNativeLibs} ` +
+ `-a requireNativeLibs ${requireNativeLibs} -o $out`,
+ CommandDeps: []string{"${jsonmodify}"},
+ Description: "Inject dependency into ${out}",
+ }, "provideNativeLibs", "requireNativeLibs")
+
// TODO(b/113233103): make sure that file_contexts is sane, i.e., validate
// against the binary policy using sefcontext_compiler -p <policy>.
@@ -139,6 +147,7 @@
pctx.HostBinToolVariable("soong_zip", "soong_zip")
pctx.HostBinToolVariable("zip2zip", "zip2zip")
pctx.HostBinToolVariable("zipalign", "zipalign")
+ pctx.HostBinToolVariable("jsonmodify", "jsonmodify")
android.RegisterModuleType("apex", apexBundleFactory)
android.RegisterModuleType("apex_test", testApexBundleFactory)
@@ -427,6 +436,9 @@
flattened bool
testApex bool
+
+ // intermediate path for apex_manifest.json
+ manifestOut android.WritablePath
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -751,6 +763,10 @@
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
+ // native lib dependencies
+ var provideNativeLibs []string
+ var requireNativeLibs []string
+
// Check if "uses" requirements are met with dependent apexBundles
var providedNativeSharedLibs []string
useVendor := proptools.Bool(a.properties.Use_vendor)
@@ -783,6 +799,9 @@
switch depTag {
case sharedLibTag:
if cc, ok := child.(*cc.Module); ok {
+ if cc.HasStubsVariants() {
+ provideNativeLibs = append(provideNativeLibs, cc.OutputFile().Path().Base())
+ }
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
return true
@@ -894,6 +913,7 @@
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
a.externalDeps = append(a.externalDeps, cc.Name())
}
+ requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
// Don't track further
return false
}
@@ -954,6 +974,21 @@
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = filesInfo
+ a.manifestOut = android.PathForModuleOut(ctx, "apex_manifest.json")
+ // put dependency({provide|require}NativeLibs) in apex_manifest.json
+ manifestSrc := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
+ provideNativeLibs = android.SortedUniqueStrings(provideNativeLibs)
+ requireNativeLibs = android.SortedUniqueStrings(android.RemoveListFromList(requireNativeLibs, provideNativeLibs))
+ ctx.Build(pctx, android.BuildParams{
+ Rule: injectApexDependency,
+ Input: manifestSrc,
+ Output: a.manifestOut,
+ Args: map[string]string{
+ "provideNativeLibs": strings.Join(provideNativeLibs, " "),
+ "requireNativeLibs": strings.Join(requireNativeLibs, " "),
+ },
+ })
+
if a.apexTypes.zip() {
a.buildUnflattenedApex(ctx, zipApex)
}
@@ -1001,8 +1036,6 @@
a.container_private_key_file = key
}
- manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
-
var abis []string
for _, target := range ctx.MultiTargets() {
if len(target.Arch.Abi) > 0 {
@@ -1032,7 +1065,7 @@
}
}
implicitInputs := append(android.Paths(nil), filesToCopy...)
- implicitInputs = append(implicitInputs, manifest)
+ implicitInputs = append(implicitInputs, a.manifestOut)
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
@@ -1127,7 +1160,7 @@
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
"copy_commands": strings.Join(copyCommands, " && "),
- "manifest": manifest.String(),
+ "manifest": a.manifestOut.String(),
"file_contexts": fileContexts.String(),
"canned_fs_config": cannedFsConfig.String(),
"key": a.private_key_file.String(),
@@ -1165,7 +1198,7 @@
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
"copy_commands": strings.Join(copyCommands, " && "),
- "manifest": manifest.String(),
+ "manifest": a.manifestOut.String(),
},
})
}
@@ -1196,16 +1229,7 @@
if a.installable() {
// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
// with other ordinary files.
- manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
-
- // rename to apex_manifest.json
- copiedManifest := android.PathForModuleOut(ctx, "apex_manifest.json")
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: manifest,
- Output: copiedManifest,
- })
- a.filesInfo = append(a.filesInfo, apexFile{copiedManifest, ctx.ModuleName() + ".apex_manifest.json", ".", etc, nil, nil})
+ a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, ctx.ModuleName() + ".apex_manifest.json", ".", etc, nil, nil})
// rename to apex_pubkey
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")