diff --git a/cc/cc_test.go b/cc/cc_test.go index dcf117c27..80a6361ba 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -264,11 +264,24 @@ func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, var } } +func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) { + t.Helper() + assertString(t, params.Rule.String(), android.WriteFile.String()) + actual := strings.FieldsFunc(strings.ReplaceAll(params.Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' }) + assertArrayString(t, actual, expected) +} + func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) { t.Helper() vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") - actual := strings.FieldsFunc(strings.ReplaceAll(vndkSnapshot.Output(output).Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' }) - assertArrayString(t, actual, expected) + checkWriteFileOutput(t, vndkSnapshot.Output(output), expected) +} + +func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) { + t.Helper() + vndkLibraries := ctx.ModuleForTests(module, "") + output := insertVndkVersion(module, "VER") + checkWriteFileOutput(t, vndkLibraries.Output(output), expected) } func TestVndk(t *testing.T) { @@ -321,6 +334,21 @@ func TestVndk(t *testing.T) { }, }, } + vndk_libraries_txt { + name: "llndk.libraries.txt", + } + vndk_libraries_txt { + name: "vndkcore.libraries.txt", + } + vndk_libraries_txt { + name: "vndksp.libraries.txt", + } + vndk_libraries_txt { + name: "vndkprivate.libraries.txt", + } + vndk_libraries_txt { + name: "vndkcorevariant.libraries.txt", + } `, config) checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "") @@ -355,7 +383,6 @@ func TestVndk(t *testing.T) { checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"}) checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"}) checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"}) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", nil) // merged & tagged & filtered-out(libclang_rt) checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ "LLNDK: libc.so", @@ -371,19 +398,25 @@ func TestVndk(t *testing.T) { "VNDK-private: libvndk-private.so", "VNDK-private: libvndk_sp_private-x.so", }) - checkVndkOutput(t, ctx, "vndk/llndk.libraries.txt", []string{ - "libc.so", "libdl.so", "libft2.so", "libm.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{ - "libvndk-private.so", "libvndk.so", - }) - checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{ - "libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{ - "libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", - }) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{}) + checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"}) + checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"}) + checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil) +} + +func TestVndkLibrariesTxtAndroidMk(t *testing.T) { + config := android.TestArchConfig(buildDir, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + ctx := testCcWithConfig(t, ` + vndk_libraries_txt { + name: "llndk.libraries.txt", + }`, config) + + module := ctx.ModuleForTests("llndk.libraries.txt", "") + entries := android.AndroidMkEntriesForTest(t, config, "", module.Module()) + assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.VER.txt"}) } func TestVndkUsingCoreVariant(t *testing.T) { @@ -422,20 +455,17 @@ func TestVndkUsingCoreVariant(t *testing.T) { }, nocrt: true, } + + vndk_libraries_txt { + name: "vndkcorevariant.libraries.txt", + } `, config) - checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"}) - checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{ - "libc++.so", "libvndk2.so", "libvndk_sp.so", - }) + checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"}) } func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { - config := android.TestArchConfig(buildDir, nil) - config.TestProductVariables.DeviceVndkVersion = nil - config.TestProductVariables.Platform_vndk_version = nil - - ctx := testCcWithConfig(t, ` + ctx := testCcNoVndk(t, ` cc_library { name: "libvndk", vendor_available: true, @@ -444,7 +474,7 @@ func TestVndkWhenVndkVersionIsNotSet(t *testing.T) { }, nocrt: true, } - `, config) + `) checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ "LLNDK: libc.so", diff --git a/cc/testing.go b/cc/testing.go index fafaeb0c9..4d6e50eef 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -269,6 +269,7 @@ func CreateTestContext(bp string, fs map[string][]byte, ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(ObjectFactory)) ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory)) ctx.RegisterModuleType("vndk_prebuilt_shared", android.ModuleFactoryAdaptor(VndkPrebuiltSharedFactory)) + ctx.RegisterModuleType("vndk_libraries_txt", android.ModuleFactoryAdaptor(VndkLibrariesTxt)) ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) { ctx.BottomUp("image", ImageMutator).Parallel() ctx.BottomUp("link", LinkageMutator).Parallel() diff --git a/cc/vndk.go b/cc/vndk.go index bb4aafce3..0b65acafa 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -360,22 +360,99 @@ func VndkMutator(mctx android.BottomUpMutatorContext) { } func init() { + android.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxt) android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) } +type vndkLibrariesTxt struct { + android.ModuleBase + outputFile android.OutputPath +} + +// vndk_libraries_txt is a special kind of module type in that it name is one of +// - llndk.libraries.txt +// - vndkcore.libraries.txt +// - vndksp.libraries.txt +// - vndkprivate.libraries.txt +// - vndkcorevariant.libraries.txt +// A module behaves like a prebuilt_etc but its content is generated by soong. +// By being a soong module, these files can be referenced by other soong modules. +// For example, apex_vndk can depend on these files as prebuilt. +func VndkLibrariesTxt() android.Module { + m := &vndkLibrariesTxt{} + android.InitAndroidModule(m) + return m +} + +func insertVndkVersion(filename string, vndkVersion string) string { + if index := strings.LastIndex(filename, "."); index != -1 { + return filename[:index] + "." + vndkVersion + filename[index:] + } + return filename +} + +func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var list []string + switch txt.Name() { + case "llndk.libraries.txt": + for _, filename := range android.SortedStringMapValues(llndkLibraries(ctx.Config())) { + if strings.HasPrefix(filename, "libclang_rt.hwasan-") { + continue + } + list = append(list, filename) + } + case "vndkcore.libraries.txt": + list = android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) + case "vndksp.libraries.txt": + list = android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) + case "vndkprivate.libraries.txt": + list = android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) + case "vndkcorevariant.libraries.txt": + list = android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) + default: + ctx.ModuleErrorf("name(%s) is unknown.", txt.Name()) + return + } + + filename := insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion()) + txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath + ctx.Build(pctx, android.BuildParams{ + Rule: android.WriteFile, + Output: txt.outputFile, + Description: "Writing " + txt.outputFile.String(), + Args: map[string]string{ + "content": strings.Join(list, "\\n"), + }, + }) + + installPath := android.PathForModuleInstall(ctx, "etc") + ctx.InstallFile(installPath, filename, txt.outputFile) +} + +func (txt *vndkLibrariesTxt) AndroidMkEntries() android.AndroidMkEntries { + return android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(txt.outputFile), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base()) + }, + }, + } +} + func VndkSnapshotSingleton() android.Singleton { return &vndkSnapshotSingleton{} } type vndkSnapshotSingleton struct { - installedLlndkLibraries []string - llndkLibrariesFile android.Path - vndkSpLibrariesFile android.Path - vndkCoreLibrariesFile android.Path - vndkPrivateLibrariesFile android.Path - vndkCoreVariantLibrariesFile android.Path - vndkLibrariesFile android.Path - vndkSnapshotZipFile android.OptionalPath + installedLlndkLibraries []string + llndkLibrariesFile android.Path + vndkSpLibrariesFile android.Path + vndkCoreLibrariesFile android.Path + vndkPrivateLibrariesFile android.Path + vndkLibrariesFile android.Path + vndkSnapshotZipFile android.OptionalPath } func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { @@ -768,15 +845,13 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) - vndkcorevariant := android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) c.llndkLibrariesFile = installListFile(llndk, "llndk.libraries.txt") c.vndkCoreLibrariesFile = installListFile(vndkcore, "vndkcore.libraries.txt") c.vndkSpLibrariesFile = installListFile(vndksp, "vndksp.libraries.txt") c.vndkPrivateLibrariesFile = installListFile(vndkprivate, "vndkprivate.libraries.txt") - c.vndkCoreVariantLibrariesFile = installListFile(vndkcorevariant, "vndkcorevariant.libraries.txt") - // merged & tagged & filtered-out(libclang_rt) + // Build list of vndk libs as merged & tagged & filter-out(libclang_rt): // Since each target have different set of libclang_rt.* files, // keep the common set of files in vndk.libraries.txt var merged []string @@ -812,12 +887,6 @@ func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " ")) ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " ")) - ctx.Strict("LLNDK_LIBRARIES_FILE", c.llndkLibrariesFile.String()) - ctx.Strict("VNDKCORE_LIBRARIES_FILE", c.vndkCoreLibrariesFile.String()) - ctx.Strict("VNDKSP_LIBRARIES_FILE", c.vndkSpLibrariesFile.String()) - ctx.Strict("VNDKPRIVATE_LIBRARIES_FILE", c.vndkPrivateLibrariesFile.String()) - ctx.Strict("VNDKCOREVARIANT_LIBRARIES_FILE", c.vndkCoreVariantLibrariesFile.String()) - ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String()) ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String()) }