diff --git a/cc/cc.go b/cc/cc.go index 806a6edd0..57f5ab87f 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -215,6 +215,10 @@ type BaseProperties struct { // Allows this module to use non-APEX version of libraries. Useful // for building binaries that are started before APEXes are activated. Bootstrap *bool + + // Even if DeviceConfig().VndkUseCoreVariant() is set, this module must use vendor variant. + // see soong/cc/config/vndk.go + MustUseVendorVariant bool `blueprint:"mutated"` } type VendorProperties struct { @@ -586,7 +590,7 @@ func (c *Module) isNdk() bool { func (c *Module) isLlndk(config android.Config) bool { // Returns true for both LLNDK (public) and LLNDK-private libs. - return inList(c.Name(), *llndkLibraries(config)) + return inList(c.BaseModuleName(), *llndkLibraries(config)) } func (c *Module) isLlndkPublic(config android.Config) bool { @@ -596,7 +600,7 @@ func (c *Module) isLlndkPublic(config android.Config) bool { func (c *Module) isVndkPrivate(config android.Config) bool { // Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private. - return inList(c.Name(), *vndkPrivateLibraries(config)) + return inList(c.BaseModuleName(), *vndkPrivateLibraries(config)) } func (c *Module) isVndk() bool { @@ -639,7 +643,7 @@ func (c *Module) isVndkExt() bool { } func (c *Module) mustUseVendorVariant() bool { - return c.isVndkSp() || inList(c.Name(), config.VndkMustUseVendorVariantList) + return c.isVndkSp() || c.Properties.MustUseVendorVariant } func (c *Module) getVndkExtendsModuleName() string { @@ -2113,7 +2117,6 @@ func (c *Module) header() bool { } func (c *Module) getMakeLinkType(actx android.ModuleContext) string { - name := actx.ModuleName() if c.useVndk() { if lib, ok := c.linker.(*llndkStubDecorator); ok { if Bool(lib.Properties.Vendor_available) { @@ -2135,7 +2138,7 @@ func (c *Module) getMakeLinkType(actx android.ModuleContext) string { // TODO(b/114741097): use the correct ndk stl once build errors have been fixed //family, link := getNdkStlFamilyAndLinkType(c) //return fmt.Sprintf("native:ndk:%s:%s", family, link) - } else if inList(name, *vndkUsingCoreVariantLibraries(actx.Config())) { + } else if actx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() { return "native:platform_vndk" } else { return "native:platform" diff --git a/cc/cc_test.go b/cc/cc_test.go index 689aacd84..f13bee5ff 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -264,6 +264,13 @@ func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, var } } +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) +} + func TestVndk(t *testing.T) { config := android.TestArchConfig(buildDir, nil) config.TestProductVariables.DeviceVndkVersion = StringPtr("current") @@ -336,6 +343,69 @@ func TestVndk(t *testing.T) { checkVndkSnapshot(t, ctx, "libvndk", vndkCoreLib2ndPath, variant2nd) checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLibPath, variant) checkVndkSnapshot(t, ctx, "libvndk_sp", vndkSpLib2ndPath, variant2nd) + + 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.so", "libvndk_private.so"}) + checkVndkOutput(t, ctx, "vndk/vndkprivate.libraries.txt", []string{"libft2.so", "libvndk_private.so", "libvndk_sp_private.so"}) + checkVndkOutput(t, ctx, "vndk/vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp.so", "libvndk_sp_private.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", + "LLNDK: libdl.so", + "LLNDK: libft2.so", + "LLNDK: libm.so", + "VNDK-SP: libc++.so", + "VNDK-SP: libvndk_sp.so", + "VNDK-SP: libvndk_sp_private.so", + "VNDK-core: libvndk.so", + "VNDK-core: libvndk_private.so", + "VNDK-private: libft2.so", + "VNDK-private: libvndk_private.so", + "VNDK-private: libvndk_sp_private.so", + }) +} + +func TestVndkUsingCoreVariant(t *testing.T) { + config := android.TestArchConfig(buildDir, nil) + config.TestProductVariables.DeviceVndkVersion = StringPtr("current") + config.TestProductVariables.Platform_vndk_version = StringPtr("VER") + config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true) + + setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"}) + + ctx := testCcWithConfig(t, ` + cc_library { + name: "libvndk", + vendor_available: true, + vndk: { + enabled: true, + }, + nocrt: true, + } + + cc_library { + name: "libvndk_sp", + vendor_available: true, + vndk: { + enabled: true, + support_system_process: true, + }, + nocrt: true, + } + + cc_library { + name: "libvndk2", + vendor_available: false, + vndk: { + enabled: true, + }, + nocrt: true, + } + `, config) + + checkVndkOutput(t, ctx, "vndk/vndkcore.libraries.txt", []string{"libvndk.so", "libvndk2.so"}) + checkVndkOutput(t, ctx, "vndk/vndkcorevariant.libraries.txt", []string{"libvndk2.so"}) } func TestVndkDepError(t *testing.T) { @@ -1340,9 +1410,9 @@ func TestMakeLinkType(t *testing.T) { assertArrayString(t, *vndkSpLibraries(config), []string{"libc++", "libvndksp"}) assertArrayString(t, *llndkLibraries(config), - []string{"libc", "libdl", "libllndk", "libllndkprivate", "libm"}) + []string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"}) assertArrayString(t, *vndkPrivateLibraries(config), - []string{"libllndkprivate", "libvndkprivate"}) + []string{"libft2", "libllndkprivate", "libvndkprivate"}) vendorVariant27 := "android_arm64_armv8-a_vendor.27_shared" diff --git a/cc/testing.go b/cc/testing.go index 6fa6ea7af..fafaeb0c9 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -144,6 +144,18 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libdl", symbol_file: "", } + cc_library { + name: "libft2", + no_libcrt: true, + nocrt: true, + system_shared_libs: [], + recovery_available: true, + } + llndk_library { + name: "libft2", + symbol_file: "", + vendor_available: false, + } cc_library { name: "libc++_static", no_libcrt: true, diff --git a/cc/vndk.go b/cc/vndk.go index 14bbf1156..57ee62a1b 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -194,14 +194,16 @@ func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error { } var ( - vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires") - vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires") - llndkLibrariesKey = android.NewOnceKey("llndkLibrarires") - vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires") - vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires") - modulePathsKey = android.NewOnceKey("modulePaths") - vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs") - vndkLibrariesLock sync.Mutex + vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires") + vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires") + llndkLibrariesKey = android.NewOnceKey("llndkLibrarires") + vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires") + vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires") + modulePathsKey = android.NewOnceKey("modulePaths") + vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs") + vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey") + testVndkMustUseVendorVariantListKey = android.NewOnceKey("testVndkMustUseVendorVariantListKey") + vndkLibrariesLock sync.Mutex headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"} ) @@ -248,6 +250,26 @@ func vndkSnapshotOutputs(config android.Config) *android.RuleBuilderInstalls { }).(*android.RuleBuilderInstalls) } +func vndkMustUseVendorVariantList(cfg android.Config) []string { + return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} { + override := cfg.Once(testVndkMustUseVendorVariantListKey, func() interface{} { + return []string(nil) + }).([]string) + if override != nil { + return override + } + return config.VndkMustUseVendorVariantList + }).([]string) +} + +// test may call this to override global configuration(config.VndkMustUseVendorVariantList) +// when it is called, it must be before the first call to vndkMustUseVendorVariantList() +func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) { + config.Once(testVndkMustUseVendorVariantListKey, func() interface{} { + return mustUseVendorVariantList + }) +} + func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { lib := m.linker.(*llndkStubDecorator) name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix) @@ -276,7 +298,10 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { defer vndkLibrariesLock.Unlock() modulePaths := modulePaths(mctx.Config()) - if mctx.DeviceConfig().VndkUseCoreVariant() && !inList(name, config.VndkMustUseVendorVariantList) { + if inList(name, vndkMustUseVendorVariantList(mctx.Config())) { + m.Properties.MustUseVendorVariant = true + } + if mctx.DeviceConfig().VndkUseCoreVariant() && !m.mustUseVendorVariant() { vndkUsingCoreVariantLibraries := vndkUsingCoreVariantLibraries(mctx.Config()) if !inList(name, *vndkUsingCoreVariantLibraries) { *vndkUsingCoreVariantLibraries = append(*vndkUsingCoreVariantLibraries, name) @@ -365,6 +390,8 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } + c.buildVndkLibrariesTxtFiles(ctx) + outputs := vndkSnapshotOutputs(ctx.Config()) snapshotDir := "vndk-snapshot" @@ -604,3 +631,88 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex installSnapshotFileFromContent(modulePathTxtBuilder.String(), filepath.Join(configsDir, "module_paths.txt")) } + +func installListFile(ctx android.SingletonContext, list []string, pathComponents ...string) android.OutputPath { + out := android.PathForOutput(ctx, pathComponents...) + ctx.Build(pctx, android.BuildParams{ + Rule: android.WriteFile, + Output: out, + Description: "Writing " + out.String(), + Args: map[string]string{ + "content": strings.Join(list, "\\n"), + }, + }) + return out +} + +func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) { + var ( + llndk, vndkcore, vndksp, vndkprivate, vndkcorevariant, merged []string + ) + vndkVersion := ctx.DeviceConfig().PlatformVndkVersion() + config := ctx.Config() + ctx.VisitAllModules(func(m android.Module) { + if !m.Enabled() { + return + } + c, ok := m.(*Module) + if !ok || c.Os().Class != android.Device { + return + } + lib, ok := c.linker.(interface{ shared() bool }) + if !ok || !lib.shared() { + return + } + + if !c.OutputFile().Valid() { + return + } + + filename := c.OutputFile().Path().Base() + if c.isLlndk(config) { + llndk = append(llndk, filename) + if c.isVndkPrivate(config) { + vndkprivate = append(vndkprivate, filename) + } + } else if c.vndkVersion() == vndkVersion && c.isVndk() && !c.isVndkExt() { + if c.isVndkSp() { + vndksp = append(vndksp, filename) + } else { + vndkcore = append(vndkcore, filename) + } + if c.isVndkPrivate(config) { + vndkprivate = append(vndkprivate, filename) + } + if ctx.DeviceConfig().VndkUseCoreVariant() && !c.mustUseVendorVariant() { + vndkcorevariant = append(vndkcorevariant, filename) + } + } + }) + llndk = android.SortedUniqueStrings(llndk) + vndkcore = android.SortedUniqueStrings(vndkcore) + vndksp = android.SortedUniqueStrings(vndksp) + vndkprivate = android.SortedUniqueStrings(vndkprivate) + vndkcorevariant = android.SortedUniqueStrings(vndkcorevariant) + + installListFile(ctx, llndk, "vndk", "llndk.libraries.txt") + installListFile(ctx, vndkcore, "vndk", "vndkcore.libraries.txt") + installListFile(ctx, vndksp, "vndk", "vndksp.libraries.txt") + installListFile(ctx, vndkprivate, "vndk", "vndkprivate.libraries.txt") + installListFile(ctx, vndkcorevariant, "vndk", "vndkcorevariant.libraries.txt") + + // merged & tagged & filtered-out(libclang_rt) + filterOutLibClangRt := func(libList []string) (filtered []string) { + for _, lib := range libList { + if !strings.HasPrefix(lib, "libclang_rt.") { + filtered = append(filtered, lib) + } + } + return + } + merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...) + merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...) + merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...) + merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...) + + installListFile(ctx, merged, "vndk", "vndk.libraries.txt") +}