Put dependency in apex_manifest.json
am: e16330393a
Change-Id: I1090b2cc5154e7fefb1a16655ac874799fab740f
This commit is contained in:
@@ -199,6 +199,13 @@ func LastUniqueStrings(list []string) []string {
|
|||||||
return list[totalSkip:]
|
return list[totalSkip:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SortedUniqueStrings returns what the name says
|
||||||
|
func SortedUniqueStrings(list []string) []string {
|
||||||
|
unique := FirstUniqueStrings(list)
|
||||||
|
sort.Strings(unique)
|
||||||
|
return unique
|
||||||
|
}
|
||||||
|
|
||||||
// checkCalledFromInit panics if a Go package's init function is not on the
|
// checkCalledFromInit panics if a Go package's init function is not on the
|
||||||
// call stack.
|
// call stack.
|
||||||
func checkCalledFromInit() {
|
func checkCalledFromInit() {
|
||||||
|
54
apex/apex.go
54
apex/apex.go
@@ -46,6 +46,14 @@ var (
|
|||||||
Description: "fs_config ${out}",
|
Description: "fs_config ${out}",
|
||||||
}, "ro_paths", "exec_paths")
|
}, "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
|
// TODO(b/113233103): make sure that file_contexts is sane, i.e., validate
|
||||||
// against the binary policy using sefcontext_compiler -p <policy>.
|
// against the binary policy using sefcontext_compiler -p <policy>.
|
||||||
|
|
||||||
@@ -143,6 +151,7 @@ func init() {
|
|||||||
pctx.HostBinToolVariable("soong_zip", "soong_zip")
|
pctx.HostBinToolVariable("soong_zip", "soong_zip")
|
||||||
pctx.HostBinToolVariable("zip2zip", "zip2zip")
|
pctx.HostBinToolVariable("zip2zip", "zip2zip")
|
||||||
pctx.HostBinToolVariable("zipalign", "zipalign")
|
pctx.HostBinToolVariable("zipalign", "zipalign")
|
||||||
|
pctx.HostBinToolVariable("jsonmodify", "jsonmodify")
|
||||||
|
|
||||||
android.RegisterModuleType("apex", apexBundleFactory)
|
android.RegisterModuleType("apex", apexBundleFactory)
|
||||||
android.RegisterModuleType("apex_test", testApexBundleFactory)
|
android.RegisterModuleType("apex_test", testApexBundleFactory)
|
||||||
@@ -431,6 +440,9 @@ type apexBundle struct {
|
|||||||
flattened bool
|
flattened bool
|
||||||
|
|
||||||
testApex bool
|
testApex bool
|
||||||
|
|
||||||
|
// intermediate path for apex_manifest.json
|
||||||
|
manifestOut android.WritablePath
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
|
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
|
||||||
@@ -755,6 +767,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
|
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
|
// Check if "uses" requirements are met with dependent apexBundles
|
||||||
var providedNativeSharedLibs []string
|
var providedNativeSharedLibs []string
|
||||||
useVendor := proptools.Bool(a.properties.Use_vendor)
|
useVendor := proptools.Bool(a.properties.Use_vendor)
|
||||||
@@ -787,6 +803,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
switch depTag {
|
switch depTag {
|
||||||
case sharedLibTag:
|
case sharedLibTag:
|
||||||
if cc, ok := child.(*cc.Module); ok {
|
if cc, ok := child.(*cc.Module); ok {
|
||||||
|
if cc.HasStubsVariants() {
|
||||||
|
provideNativeLibs = append(provideNativeLibs, cc.OutputFile().Path().Base())
|
||||||
|
}
|
||||||
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
|
fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
|
||||||
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
|
filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
|
||||||
return true
|
return true
|
||||||
@@ -898,6 +917,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
|
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
|
||||||
a.externalDeps = append(a.externalDeps, cc.Name())
|
a.externalDeps = append(a.externalDeps, cc.Name())
|
||||||
}
|
}
|
||||||
|
requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
|
||||||
// Don't track further
|
// Don't track further
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -958,6 +978,21 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
a.installDir = android.PathForModuleInstall(ctx, "apex")
|
||||||
a.filesInfo = filesInfo
|
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() {
|
if a.apexTypes.zip() {
|
||||||
a.buildUnflattenedApex(ctx, zipApex)
|
a.buildUnflattenedApex(ctx, zipApex)
|
||||||
}
|
}
|
||||||
@@ -1005,8 +1040,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap
|
|||||||
a.container_private_key_file = key
|
a.container_private_key_file = key
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
|
|
||||||
|
|
||||||
var abis []string
|
var abis []string
|
||||||
for _, target := range ctx.MultiTargets() {
|
for _, target := range ctx.MultiTargets() {
|
||||||
if len(target.Arch.Abi) > 0 {
|
if len(target.Arch.Abi) > 0 {
|
||||||
@@ -1036,7 +1069,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
implicitInputs := append(android.Paths(nil), filesToCopy...)
|
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()
|
outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
|
||||||
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
|
||||||
@@ -1131,7 +1164,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap
|
|||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
|
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
"copy_commands": strings.Join(copyCommands, " && "),
|
||||||
"manifest": manifest.String(),
|
"manifest": a.manifestOut.String(),
|
||||||
"file_contexts": fileContexts.String(),
|
"file_contexts": fileContexts.String(),
|
||||||
"canned_fs_config": cannedFsConfig.String(),
|
"canned_fs_config": cannedFsConfig.String(),
|
||||||
"key": a.private_key_file.String(),
|
"key": a.private_key_file.String(),
|
||||||
@@ -1169,7 +1202,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap
|
|||||||
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
"tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
|
||||||
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
|
"image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(),
|
||||||
"copy_commands": strings.Join(copyCommands, " && "),
|
"copy_commands": strings.Join(copyCommands, " && "),
|
||||||
"manifest": manifest.String(),
|
"manifest": a.manifestOut.String(),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1200,16 +1233,7 @@ func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
|
|||||||
if a.installable() {
|
if a.installable() {
|
||||||
// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
|
// For flattened APEX, do nothing but make sure that apex_manifest.json and apex_pubkey are also copied along
|
||||||
// with other ordinary files.
|
// with other ordinary files.
|
||||||
manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
|
a.filesInfo = append(a.filesInfo, apexFile{a.manifestOut, ctx.ModuleName() + ".apex_manifest.json", ".", etc, nil, nil})
|
||||||
|
|
||||||
// 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})
|
|
||||||
|
|
||||||
// rename to apex_pubkey
|
// rename to apex_pubkey
|
||||||
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
|
copiedPubkey := android.PathForModuleOut(ctx, "apex_pubkey")
|
||||||
|
@@ -270,6 +270,13 @@ func ensureListNotContains(t *testing.T, result []string, notExpected string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureListEmpty(t *testing.T, result []string) {
|
||||||
|
t.Helper()
|
||||||
|
if len(result) > 0 {
|
||||||
|
t.Errorf("%q is expected to be empty", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Minimal test
|
// Minimal test
|
||||||
func TestBasicApex(t *testing.T) {
|
func TestBasicApex(t *testing.T) {
|
||||||
ctx, _ := testApex(t, `
|
ctx, _ := testApex(t, `
|
||||||
@@ -1060,6 +1067,109 @@ func TestHeaderLibsDependency(t *testing.T) {
|
|||||||
ensureContains(t, cFlags, "-Imy_include")
|
ensureContains(t, cFlags, "-Imy_include")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDependenciesInApexManifest(t *testing.T) {
|
||||||
|
ctx, _ := testApex(t, `
|
||||||
|
apex {
|
||||||
|
name: "myapex_nodep",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["lib_nodep"],
|
||||||
|
compile_multilib: "both",
|
||||||
|
file_contexts: "myapex",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "myapex_dep",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["lib_dep"],
|
||||||
|
compile_multilib: "both",
|
||||||
|
file_contexts: "myapex",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "myapex_provider",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["libfoo"],
|
||||||
|
compile_multilib: "both",
|
||||||
|
file_contexts: "myapex",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex {
|
||||||
|
name: "myapex_selfcontained",
|
||||||
|
key: "myapex.key",
|
||||||
|
native_shared_libs: ["lib_dep", "libfoo"],
|
||||||
|
compile_multilib: "both",
|
||||||
|
file_contexts: "myapex",
|
||||||
|
}
|
||||||
|
|
||||||
|
apex_key {
|
||||||
|
name: "myapex.key",
|
||||||
|
public_key: "testkey.avbpubkey",
|
||||||
|
private_key: "testkey.pem",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "lib_nodep",
|
||||||
|
srcs: ["mylib.cpp"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "lib_dep",
|
||||||
|
srcs: ["mylib.cpp"],
|
||||||
|
shared_libs: ["libfoo"],
|
||||||
|
system_shared_libs: [],
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library {
|
||||||
|
name: "libfoo",
|
||||||
|
srcs: ["mytest.cpp"],
|
||||||
|
stubs: {
|
||||||
|
versions: ["1"],
|
||||||
|
},
|
||||||
|
system_shared_libs: [],
|
||||||
|
stl: "none",
|
||||||
|
}
|
||||||
|
`)
|
||||||
|
|
||||||
|
names := func(s string) (ns []string) {
|
||||||
|
for _, n := range strings.Split(s, " ") {
|
||||||
|
if len(n) > 0 {
|
||||||
|
ns = append(ns, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var injectRule android.TestingBuildParams
|
||||||
|
var provideNativeLibs, requireNativeLibs []string
|
||||||
|
|
||||||
|
injectRule = ctx.ModuleForTests("myapex_nodep", "android_common_myapex_nodep").Rule("injectApexDependency")
|
||||||
|
provideNativeLibs = names(injectRule.Args["provideNativeLibs"])
|
||||||
|
requireNativeLibs = names(injectRule.Args["requireNativeLibs"])
|
||||||
|
ensureListEmpty(t, provideNativeLibs)
|
||||||
|
ensureListEmpty(t, requireNativeLibs)
|
||||||
|
|
||||||
|
injectRule = ctx.ModuleForTests("myapex_dep", "android_common_myapex_dep").Rule("injectApexDependency")
|
||||||
|
provideNativeLibs = names(injectRule.Args["provideNativeLibs"])
|
||||||
|
requireNativeLibs = names(injectRule.Args["requireNativeLibs"])
|
||||||
|
ensureListEmpty(t, provideNativeLibs)
|
||||||
|
ensureListContains(t, requireNativeLibs, "libfoo.so")
|
||||||
|
|
||||||
|
injectRule = ctx.ModuleForTests("myapex_provider", "android_common_myapex_provider").Rule("injectApexDependency")
|
||||||
|
provideNativeLibs = names(injectRule.Args["provideNativeLibs"])
|
||||||
|
requireNativeLibs = names(injectRule.Args["requireNativeLibs"])
|
||||||
|
ensureListContains(t, provideNativeLibs, "libfoo.so")
|
||||||
|
ensureListEmpty(t, requireNativeLibs)
|
||||||
|
|
||||||
|
injectRule = ctx.ModuleForTests("myapex_selfcontained", "android_common_myapex_selfcontained").Rule("injectApexDependency")
|
||||||
|
provideNativeLibs = names(injectRule.Args["provideNativeLibs"])
|
||||||
|
requireNativeLibs = names(injectRule.Args["requireNativeLibs"])
|
||||||
|
ensureListContains(t, provideNativeLibs, "libfoo.so")
|
||||||
|
ensureListEmpty(t, requireNativeLibs)
|
||||||
|
}
|
||||||
|
|
||||||
func TestNonTestApex(t *testing.T) {
|
func TestNonTestApex(t *testing.T) {
|
||||||
ctx, _ := testApex(t, `
|
ctx, _ := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
|
Reference in New Issue
Block a user