Loading android/util.go +7 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,13 @@ func LastUniqueStrings(list []string) []string { 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 // call stack. func checkCalledFromInit() { Loading apex/apex.go +39 −15 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ var ( 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>. Loading Loading @@ -143,6 +151,7 @@ func init() { 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) Loading Loading @@ -431,6 +440,9 @@ type apexBundle struct { flattened bool testApex bool // intermediate path for apex_manifest.json manifestOut android.WritablePath } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, Loading Loading @@ -755,6 +767,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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) Loading Loading @@ -787,6 +803,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 Loading Loading @@ -898,6 +917,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 } Loading Loading @@ -958,6 +978,21 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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) } Loading Loading @@ -1005,8 +1040,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap 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 { Loading Loading @@ -1036,7 +1069,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap } } 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") Loading Loading @@ -1131,7 +1164,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap "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(), Loading Loading @@ -1169,7 +1202,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), "copy_commands": strings.Join(copyCommands, " && "), "manifest": manifest.String(), "manifest": a.manifestOut.String(), }, }) } Loading Loading @@ -1200,16 +1233,7 @@ func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) { 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") Loading apex/apex_test.go +110 −0 Original line number Diff line number Diff line Loading @@ -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 func TestBasicApex(t *testing.T) { ctx, _ := testApex(t, ` Loading Loading @@ -1060,6 +1067,109 @@ func TestHeaderLibsDependency(t *testing.T) { 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) { ctx, _ := testApex(t, ` apex { Loading Loading
android/util.go +7 −0 Original line number Diff line number Diff line Loading @@ -199,6 +199,13 @@ func LastUniqueStrings(list []string) []string { 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 // call stack. func checkCalledFromInit() { Loading
apex/apex.go +39 −15 Original line number Diff line number Diff line Loading @@ -46,6 +46,14 @@ var ( 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>. Loading Loading @@ -143,6 +151,7 @@ func init() { 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) Loading Loading @@ -431,6 +440,9 @@ type apexBundle struct { flattened bool testApex bool // intermediate path for apex_manifest.json manifestOut android.WritablePath } func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext, Loading Loading @@ -755,6 +767,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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) Loading Loading @@ -787,6 +803,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 Loading Loading @@ -898,6 +917,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 } Loading Loading @@ -958,6 +978,21 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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) } Loading Loading @@ -1005,8 +1040,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap 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 { Loading Loading @@ -1036,7 +1069,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap } } 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") Loading Loading @@ -1131,7 +1164,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap "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(), Loading Loading @@ -1169,7 +1202,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, apexType ap "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir, "image_dir": android.PathForModuleOut(ctx, "image"+suffix).String(), "copy_commands": strings.Join(copyCommands, " && "), "manifest": manifest.String(), "manifest": a.manifestOut.String(), }, }) } Loading Loading @@ -1200,16 +1233,7 @@ func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) { 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") Loading
apex/apex_test.go +110 −0 Original line number Diff line number Diff line Loading @@ -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 func TestBasicApex(t *testing.T) { ctx, _ := testApex(t, ` Loading Loading @@ -1060,6 +1067,109 @@ func TestHeaderLibsDependency(t *testing.T) { 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) { ctx, _ := testApex(t, ` apex { Loading