Loading cc/cc_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -251,12 +251,12 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) { vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") snapshotPath := filepath.Join(subDir, name+".so") mod := ctx.ModuleForTests(name, variant).Module().(*Module) if !mod.outputFile.Valid() { t.Errorf("%q must have output\n", name) return } snapshotPath := filepath.Join(subDir, mod.outputFile.Path().Base()) out := vndkSnapshot.Output(snapshotPath) if out.Input != mod.outputFile.Path() { Loading cc/vndk.go +190 −116 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import ( "errors" "fmt" "path/filepath" "sort" "strings" "sync" Loading Loading @@ -199,8 +200,6 @@ var ( llndkLibrariesKey = android.NewOnceKey("llndkLibrarires") vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires") vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires") modulePathsKey = android.NewOnceKey("modulePaths") vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs") vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey") vndkLibrariesLock sync.Mutex Loading Loading @@ -247,18 +246,6 @@ func vndkUsingCoreVariantLibraries(config android.Config) map[string]string { }).(map[string]string) } func modulePaths(config android.Config) map[string]string { return config.Once(modulePathsKey, func() interface{} { return make(map[string]string) }).(map[string]string) } func vndkSnapshotOutputs(config android.Config) *android.RuleBuilderInstalls { return config.Once(vndkSnapshotOutputsKey, func() interface{} { return &android.RuleBuilderInstalls{} }).(*android.RuleBuilderInstalls) } func vndkMustUseVendorVariantList(cfg android.Config) []string { return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} { return config.VndkMustUseVendorVariantList Loading Loading @@ -297,8 +284,6 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { vndkLibrariesLock.Lock() defer vndkLibrariesLock.Unlock() modulePaths(mctx.Config())[name] = mctx.ModuleDir() if inList(name, vndkMustUseVendorVariantList(mctx.Config())) { m.Properties.MustUseVendorVariant = true } Loading Loading @@ -376,10 +361,6 @@ func VndkMutator(mctx android.BottomUpMutatorContext) { func init() { android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) { outputs := vndkSnapshotOutputs(ctx.Config()) ctx.Strict("SOONG_VNDK_SNAPSHOT_FILES", outputs.String()) }) } func VndkSnapshotSingleton() android.Singleton { Loading @@ -388,12 +369,13 @@ func VndkSnapshotSingleton() android.Singleton { type vndkSnapshotSingleton struct { installedLlndkLibraries []string llnkdLibrariesFile android.Path llndkLibrariesFile android.Path vndkSpLibrariesFile android.Path vndkCoreLibrariesFile android.Path vndkPrivateLibrariesFile android.Path vndkCoreVariantLibrariesFile android.Path vndkLibrariesFile android.Path vndkSnapshotZipFile android.OptionalPath } func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { Loading @@ -413,15 +395,42 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } outputs := vndkSnapshotOutputs(ctx.Config()) var snapshotOutputs android.Paths /* VNDK snapshot zipped artifacts directory structure: {SNAPSHOT_ARCH}/ arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ shared/ vndk-core/ (VNDK-core libraries, e.g. libbinder.so) vndk-sp/ (VNDK-SP libraries, e.g. libc++.so) arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ shared/ vndk-core/ (VNDK-core libraries, e.g. libbinder.so) vndk-sp/ (VNDK-SP libraries, e.g. libc++.so) binder32/ (This directory is newly introduced in v28 (Android P) to hold prebuilts built for 32-bit binder interface.) arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/ ... configs/ (various *.txt configuration files) include/ (header files of same directory structure with source tree) NOTICE_FILES/ (notice files of libraries, e.g. libcutils.so.txt) */ snapshotDir := "vndk-snapshot" snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) vndkLibDir := make(map[android.ArchType]string) snapshotVariantDir := ctx.DeviceConfig().DeviceArch() targetArchDirMap := make(map[android.ArchType]string) for _, target := range ctx.Config().Targets[android.Android] { dir := snapshotVariantDir dir := snapshotArchDir if ctx.DeviceConfig().BinderBitness() == "32" { dir = filepath.Join(dir, "binder32") } Loading @@ -430,64 +439,55 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex arch += "-" + target.Arch.ArchVariant } dir = filepath.Join(dir, arch) vndkLibDir[target.Arch.ArchType] = dir targetArchDirMap[target.Arch.ArchType] = dir } configsDir := filepath.Join(snapshotVariantDir, "configs") noticeDir := filepath.Join(snapshotVariantDir, "NOTICE_FILES") includeDir := filepath.Join(snapshotVariantDir, "include") configsDir := filepath.Join(snapshotArchDir, "configs") noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES") includeDir := filepath.Join(snapshotArchDir, "include") // set of include paths exported by VNDK libraries exportedIncludes := make(map[string]bool) // generated header files among exported headers. var generatedHeaders android.Paths // set of notice files copied. noticeBuilt := make(map[string]bool) installSnapshotFileFromPath := func(path android.Path, out string) { // paths of VNDK modules for GPL license checking modulePaths := make(map[string]string) // actual module names of .so files // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full" moduleNames := make(map[string]string) installSnapshotFileFromPath := func(path android.Path, out string) android.OutputPath { outPath := android.PathForOutput(ctx, out) ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: path, Output: android.PathForOutput(ctx, snapshotDir, out), Output: outPath, Description: "vndk snapshot " + out, Args: map[string]string{ "cpFlags": "-f -L", }, }) *outputs = append(*outputs, android.RuleBuilderInstall{ From: android.PathForOutput(ctx, snapshotDir, out), To: out, }) return outPath } installSnapshotFileFromContent := func(content, out string) { installSnapshotFileFromContent := func(content, out string) android.OutputPath { outPath := android.PathForOutput(ctx, out) ctx.Build(pctx, android.BuildParams{ Rule: android.WriteFile, Output: android.PathForOutput(ctx, snapshotDir, out), Output: outPath, Description: "vndk snapshot " + out, Args: map[string]string{ "content": content, }, }) *outputs = append(*outputs, android.RuleBuilderInstall{ From: android.PathForOutput(ctx, snapshotDir, out), To: out, }) } tryBuildNotice := func(m *Module) { name := ctx.ModuleName(m) + ".so.txt" if _, ok := noticeBuilt[name]; ok { return } noticeBuilt[name] = true if m.NoticeFile().Valid() { installSnapshotFileFromPath(m.NoticeFile().Path(), filepath.Join(noticeDir, name)) } return outPath } vndkCoreLibraries := android.SortedStringKeys(vndkCoreLibraries(ctx.Config())) vndkSpLibraries := android.SortedStringKeys(vndkSpLibraries(ctx.Config())) vndkPrivateLibraries := android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())) var generatedHeaders android.Paths includeDirs := make(map[string]bool) type vndkSnapshotLibraryInterface interface { exportedFlagsProducer libraryInterface Loading @@ -496,12 +496,31 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex var _ vndkSnapshotLibraryInterface = (*prebuiltLibraryLinker)(nil) var _ vndkSnapshotLibraryInterface = (*libraryDecorator)(nil) installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, dir string) bool { name := ctx.ModuleName(m) libOut := filepath.Join(dir, name+".so") installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, vndkType string) (android.Paths, bool) { targetArchDir, ok := targetArchDirMap[m.Target().Arch.ArchType] if !ok { return nil, false } var ret android.Paths libPath := m.outputFile.Path() stem := libPath.Base() snapshotLibOut := filepath.Join(targetArchDir, "shared", vndkType, stem) ret = append(ret, installSnapshotFileFromPath(libPath, snapshotLibOut)) installSnapshotFileFromPath(m.outputFile.Path(), libOut) tryBuildNotice(m) moduleNames[stem] = ctx.ModuleName(m) modulePaths[stem] = ctx.ModuleDir(m) if m.NoticeFile().Valid() { noticeName := stem + ".txt" // skip already copied notice file if _, ok := noticeBuilt[noticeName]; !ok { noticeBuilt[noticeName] = true ret = append(ret, installSnapshotFileFromPath( m.NoticeFile().Path(), filepath.Join(noticeDir, noticeName))) } } if ctx.Config().VndkSnapshotBuildArtifacts() { prop := struct { Loading @@ -515,20 +534,19 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex prop.ExportedSystemDirs = l.exportedSystemDirs().Strings() prop.RelativeInstallPath = m.RelativeInstallPath() propOut := libOut + ".json" propOut := snapshotLibOut + ".json" j, err := json.Marshal(prop) if err != nil { ctx.Errorf("json marshal to %q failed: %#v", propOut, err) return false return nil, false } installSnapshotFileFromContent(string(j), propOut) ret = append(ret, installSnapshotFileFromContent(string(j), propOut)) } return true return ret, true } isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, libDir string, isVndkSnapshotLib bool) { isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) { if m.Target().NativeBridge == android.NativeBridgeEnabled { return nil, "", false } Loading @@ -539,14 +557,15 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex if !ok || !l.shared() { return nil, "", false } name := ctx.ModuleName(m) if inList(name, vndkCoreLibraries) { return l, filepath.Join("shared", "vndk-core"), true } else if inList(name, vndkSpLibraries) { return l, filepath.Join("shared", "vndk-sp"), true if m.vndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() { if m.isVndkSp() { return l, "vndk-sp", true } else { return nil, "", false return l, "vndk-core", true } } return nil, "", false } ctx.VisitAllModules(func(module android.Module) { Loading @@ -555,31 +574,32 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } baseDir, ok := vndkLibDir[m.Target().Arch.ArchType] l, vndkType, ok := isVndkSnapshotLibrary(m) if !ok { return } l, libDir, ok := isVndkSnapshotLibrary(m) libs, ok := installVndkSnapshotLib(m, l, vndkType) if !ok { return } if !installVndkSnapshotLib(m, l, filepath.Join(baseDir, libDir)) { return } snapshotOutputs = append(snapshotOutputs, libs...) // We glob headers from include directories inside source tree. So we first gather // all include directories inside our source tree. On the contrast, we manually // collect generated headers from dependencies as they can't globbed. generatedHeaders = append(generatedHeaders, l.exportedDeps()...) for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) { includeDirs[dir.String()] = true exportedIncludes[dir.String()] = true } }) if ctx.Config().VndkSnapshotBuildArtifacts() { headers := make(map[string]bool) globbedHeaders := make(map[string]bool) for _, dir := range android.SortedStringKeys(includeDirs) { // workaround to determine if dir is under output directory for _, dir := range android.SortedStringKeys(exportedIncludes) { // Skip if dir is for generated headers if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) { continue } Loading @@ -598,14 +618,14 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex if strings.HasSuffix(header, "/") { continue } headers[header] = true globbedHeaders[header] = true } } } for _, header := range android.SortedStringKeys(headers) { installSnapshotFileFromPath(android.PathForSource(ctx, header), filepath.Join(includeDir, header)) for _, header := range android.SortedStringKeys(globbedHeaders) { snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath( android.PathForSource(ctx, header), filepath.Join(includeDir, header))) } isHeader := func(path string) bool { Loading @@ -617,6 +637,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return false } // For generated headers, manually install one by one, rather than glob for _, path := range android.PathsToDirectorySortedPaths(android.FirstUniquePaths(generatedHeaders)) { header := path.String() Loading @@ -624,33 +645,85 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex continue } installSnapshotFileFromPath(path, filepath.Join(includeDir, header)) snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath( path, filepath.Join(includeDir, header))) } } installSnapshotFileFromContent(android.JoinWithSuffix(vndkCoreLibraries, ".so", "\\n"), filepath.Join(configsDir, "vndkcore.libraries.txt")) installSnapshotFileFromContent(android.JoinWithSuffix(vndkPrivateLibraries, ".so", "\\n"), filepath.Join(configsDir, "vndkprivate.libraries.txt")) snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath(c.vndkCoreLibrariesFile, filepath.Join(configsDir, "vndkcore.libraries.txt")), installSnapshotFileFromPath(c.vndkPrivateLibrariesFile, filepath.Join(configsDir, "vndkprivate.libraries.txt")), installSnapshotFileFromPath(c.vndkSpLibrariesFile, filepath.Join(configsDir, "vndksp.libraries.txt")), installSnapshotFileFromPath(c.llndkLibrariesFile, filepath.Join(configsDir, "llndk.libraries.txt")), ) var modulePathTxtBuilder strings.Builder /* Dump a map to a list file as: {key1} {value1} {key2} {value2} ... */ installMapListFile := func(m map[string]string, path string) android.OutputPath { var txtBuilder strings.Builder for idx, k := range android.SortedStringKeys(m) { if idx > 0 { txtBuilder.WriteString("\\n") } txtBuilder.WriteString(k) txtBuilder.WriteString(" ") txtBuilder.WriteString(m[k]) } return installSnapshotFileFromContent(txtBuilder.String(), path) } /* module_paths.txt contains paths on which VNDK modules are defined. e.g., libbase.so system/core/base libc.so bionic/libc ... */ snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt"))) /* module_names.txt contains names as which VNDK modules are defined, because output filename and module name can be different with stem and suffix properties. e.g., libcutils.so libcutils libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full ... */ snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt"))) // All artifacts are ready. Sort them to normalize ninja and then zip. sort.Slice(snapshotOutputs, func(i, j int) bool { return snapshotOutputs[i].String() < snapshotOutputs[j].String() }) modulePaths := modulePaths(ctx.Config()) zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip") zipRule := android.NewRuleBuilder() first := true for _, lib := range android.SortedStringKeys(modulePaths) { if first { first = false } else { modulePathTxtBuilder.WriteString("\\n") } modulePathTxtBuilder.WriteString(lib) modulePathTxtBuilder.WriteString(".so ") modulePathTxtBuilder.WriteString(modulePaths[lib]) } // If output files are too many, soong_zip command can exceed ARG_MAX. // So first dump file lists into a single list file, and then feed it to Soong snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list") zipRule.Command(). Text("( xargs"). FlagWithRspFileInputList("-n1 echo < ", snapshotOutputs). FlagWithOutput("| tr -d \\' > ", snapshotOutputList). Text(")") zipRule.Temporary(snapshotOutputList) zipRule.Command(). BuiltTool(ctx, "soong_zip"). FlagWithOutput("-o ", zipPath). FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()). FlagWithInput("-l ", snapshotOutputList) installSnapshotFileFromContent(modulePathTxtBuilder.String(), filepath.Join(configsDir, "module_paths.txt")) zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String()) c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath) } func getVndkFileName(m *Module) (string, error) { Loading Loading @@ -697,7 +770,7 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) vndkcorevariant := android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) c.llnkdLibrariesFile = installListFile(llndk, "llndk.libraries.txt") 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") Loading Loading @@ -739,11 +812,12 @@ 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.llnkdLibrariesFile.String()) 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()) } Loading
cc/cc_test.go +1 −1 Original line number Diff line number Diff line Loading @@ -251,12 +251,12 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string func checkVndkSnapshot(t *testing.T, ctx *android.TestContext, name, subDir, variant string) { vndkSnapshot := ctx.SingletonForTests("vndk-snapshot") snapshotPath := filepath.Join(subDir, name+".so") mod := ctx.ModuleForTests(name, variant).Module().(*Module) if !mod.outputFile.Valid() { t.Errorf("%q must have output\n", name) return } snapshotPath := filepath.Join(subDir, mod.outputFile.Path().Base()) out := vndkSnapshot.Output(snapshotPath) if out.Input != mod.outputFile.Path() { Loading
cc/vndk.go +190 −116 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import ( "errors" "fmt" "path/filepath" "sort" "strings" "sync" Loading Loading @@ -199,8 +200,6 @@ var ( llndkLibrariesKey = android.NewOnceKey("llndkLibrarires") vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires") vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibrarires") modulePathsKey = android.NewOnceKey("modulePaths") vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs") vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey") vndkLibrariesLock sync.Mutex Loading Loading @@ -247,18 +246,6 @@ func vndkUsingCoreVariantLibraries(config android.Config) map[string]string { }).(map[string]string) } func modulePaths(config android.Config) map[string]string { return config.Once(modulePathsKey, func() interface{} { return make(map[string]string) }).(map[string]string) } func vndkSnapshotOutputs(config android.Config) *android.RuleBuilderInstalls { return config.Once(vndkSnapshotOutputsKey, func() interface{} { return &android.RuleBuilderInstalls{} }).(*android.RuleBuilderInstalls) } func vndkMustUseVendorVariantList(cfg android.Config) []string { return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} { return config.VndkMustUseVendorVariantList Loading Loading @@ -297,8 +284,6 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { vndkLibrariesLock.Lock() defer vndkLibrariesLock.Unlock() modulePaths(mctx.Config())[name] = mctx.ModuleDir() if inList(name, vndkMustUseVendorVariantList(mctx.Config())) { m.Properties.MustUseVendorVariant = true } Loading Loading @@ -376,10 +361,6 @@ func VndkMutator(mctx android.BottomUpMutatorContext) { func init() { android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) { outputs := vndkSnapshotOutputs(ctx.Config()) ctx.Strict("SOONG_VNDK_SNAPSHOT_FILES", outputs.String()) }) } func VndkSnapshotSingleton() android.Singleton { Loading @@ -388,12 +369,13 @@ func VndkSnapshotSingleton() android.Singleton { type vndkSnapshotSingleton struct { installedLlndkLibraries []string llnkdLibrariesFile android.Path llndkLibrariesFile android.Path vndkSpLibrariesFile android.Path vndkCoreLibrariesFile android.Path vndkPrivateLibrariesFile android.Path vndkCoreVariantLibrariesFile android.Path vndkLibrariesFile android.Path vndkSnapshotZipFile android.OptionalPath } func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { Loading @@ -413,15 +395,42 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } outputs := vndkSnapshotOutputs(ctx.Config()) var snapshotOutputs android.Paths /* VNDK snapshot zipped artifacts directory structure: {SNAPSHOT_ARCH}/ arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ shared/ vndk-core/ (VNDK-core libraries, e.g. libbinder.so) vndk-sp/ (VNDK-SP libraries, e.g. libc++.so) arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ shared/ vndk-core/ (VNDK-core libraries, e.g. libbinder.so) vndk-sp/ (VNDK-SP libraries, e.g. libc++.so) binder32/ (This directory is newly introduced in v28 (Android P) to hold prebuilts built for 32-bit binder interface.) arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/ ... configs/ (various *.txt configuration files) include/ (header files of same directory structure with source tree) NOTICE_FILES/ (notice files of libraries, e.g. libcutils.so.txt) */ snapshotDir := "vndk-snapshot" snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) vndkLibDir := make(map[android.ArchType]string) snapshotVariantDir := ctx.DeviceConfig().DeviceArch() targetArchDirMap := make(map[android.ArchType]string) for _, target := range ctx.Config().Targets[android.Android] { dir := snapshotVariantDir dir := snapshotArchDir if ctx.DeviceConfig().BinderBitness() == "32" { dir = filepath.Join(dir, "binder32") } Loading @@ -430,64 +439,55 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex arch += "-" + target.Arch.ArchVariant } dir = filepath.Join(dir, arch) vndkLibDir[target.Arch.ArchType] = dir targetArchDirMap[target.Arch.ArchType] = dir } configsDir := filepath.Join(snapshotVariantDir, "configs") noticeDir := filepath.Join(snapshotVariantDir, "NOTICE_FILES") includeDir := filepath.Join(snapshotVariantDir, "include") configsDir := filepath.Join(snapshotArchDir, "configs") noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES") includeDir := filepath.Join(snapshotArchDir, "include") // set of include paths exported by VNDK libraries exportedIncludes := make(map[string]bool) // generated header files among exported headers. var generatedHeaders android.Paths // set of notice files copied. noticeBuilt := make(map[string]bool) installSnapshotFileFromPath := func(path android.Path, out string) { // paths of VNDK modules for GPL license checking modulePaths := make(map[string]string) // actual module names of .so files // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full" moduleNames := make(map[string]string) installSnapshotFileFromPath := func(path android.Path, out string) android.OutputPath { outPath := android.PathForOutput(ctx, out) ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: path, Output: android.PathForOutput(ctx, snapshotDir, out), Output: outPath, Description: "vndk snapshot " + out, Args: map[string]string{ "cpFlags": "-f -L", }, }) *outputs = append(*outputs, android.RuleBuilderInstall{ From: android.PathForOutput(ctx, snapshotDir, out), To: out, }) return outPath } installSnapshotFileFromContent := func(content, out string) { installSnapshotFileFromContent := func(content, out string) android.OutputPath { outPath := android.PathForOutput(ctx, out) ctx.Build(pctx, android.BuildParams{ Rule: android.WriteFile, Output: android.PathForOutput(ctx, snapshotDir, out), Output: outPath, Description: "vndk snapshot " + out, Args: map[string]string{ "content": content, }, }) *outputs = append(*outputs, android.RuleBuilderInstall{ From: android.PathForOutput(ctx, snapshotDir, out), To: out, }) } tryBuildNotice := func(m *Module) { name := ctx.ModuleName(m) + ".so.txt" if _, ok := noticeBuilt[name]; ok { return } noticeBuilt[name] = true if m.NoticeFile().Valid() { installSnapshotFileFromPath(m.NoticeFile().Path(), filepath.Join(noticeDir, name)) } return outPath } vndkCoreLibraries := android.SortedStringKeys(vndkCoreLibraries(ctx.Config())) vndkSpLibraries := android.SortedStringKeys(vndkSpLibraries(ctx.Config())) vndkPrivateLibraries := android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())) var generatedHeaders android.Paths includeDirs := make(map[string]bool) type vndkSnapshotLibraryInterface interface { exportedFlagsProducer libraryInterface Loading @@ -496,12 +496,31 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex var _ vndkSnapshotLibraryInterface = (*prebuiltLibraryLinker)(nil) var _ vndkSnapshotLibraryInterface = (*libraryDecorator)(nil) installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, dir string) bool { name := ctx.ModuleName(m) libOut := filepath.Join(dir, name+".so") installVndkSnapshotLib := func(m *Module, l vndkSnapshotLibraryInterface, vndkType string) (android.Paths, bool) { targetArchDir, ok := targetArchDirMap[m.Target().Arch.ArchType] if !ok { return nil, false } var ret android.Paths libPath := m.outputFile.Path() stem := libPath.Base() snapshotLibOut := filepath.Join(targetArchDir, "shared", vndkType, stem) ret = append(ret, installSnapshotFileFromPath(libPath, snapshotLibOut)) installSnapshotFileFromPath(m.outputFile.Path(), libOut) tryBuildNotice(m) moduleNames[stem] = ctx.ModuleName(m) modulePaths[stem] = ctx.ModuleDir(m) if m.NoticeFile().Valid() { noticeName := stem + ".txt" // skip already copied notice file if _, ok := noticeBuilt[noticeName]; !ok { noticeBuilt[noticeName] = true ret = append(ret, installSnapshotFileFromPath( m.NoticeFile().Path(), filepath.Join(noticeDir, noticeName))) } } if ctx.Config().VndkSnapshotBuildArtifacts() { prop := struct { Loading @@ -515,20 +534,19 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex prop.ExportedSystemDirs = l.exportedSystemDirs().Strings() prop.RelativeInstallPath = m.RelativeInstallPath() propOut := libOut + ".json" propOut := snapshotLibOut + ".json" j, err := json.Marshal(prop) if err != nil { ctx.Errorf("json marshal to %q failed: %#v", propOut, err) return false return nil, false } installSnapshotFileFromContent(string(j), propOut) ret = append(ret, installSnapshotFileFromContent(string(j), propOut)) } return true return ret, true } isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, libDir string, isVndkSnapshotLib bool) { isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) { if m.Target().NativeBridge == android.NativeBridgeEnabled { return nil, "", false } Loading @@ -539,14 +557,15 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex if !ok || !l.shared() { return nil, "", false } name := ctx.ModuleName(m) if inList(name, vndkCoreLibraries) { return l, filepath.Join("shared", "vndk-core"), true } else if inList(name, vndkSpLibraries) { return l, filepath.Join("shared", "vndk-sp"), true if m.vndkVersion() == ctx.DeviceConfig().PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() { if m.isVndkSp() { return l, "vndk-sp", true } else { return nil, "", false return l, "vndk-core", true } } return nil, "", false } ctx.VisitAllModules(func(module android.Module) { Loading @@ -555,31 +574,32 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } baseDir, ok := vndkLibDir[m.Target().Arch.ArchType] l, vndkType, ok := isVndkSnapshotLibrary(m) if !ok { return } l, libDir, ok := isVndkSnapshotLibrary(m) libs, ok := installVndkSnapshotLib(m, l, vndkType) if !ok { return } if !installVndkSnapshotLib(m, l, filepath.Join(baseDir, libDir)) { return } snapshotOutputs = append(snapshotOutputs, libs...) // We glob headers from include directories inside source tree. So we first gather // all include directories inside our source tree. On the contrast, we manually // collect generated headers from dependencies as they can't globbed. generatedHeaders = append(generatedHeaders, l.exportedDeps()...) for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) { includeDirs[dir.String()] = true exportedIncludes[dir.String()] = true } }) if ctx.Config().VndkSnapshotBuildArtifacts() { headers := make(map[string]bool) globbedHeaders := make(map[string]bool) for _, dir := range android.SortedStringKeys(includeDirs) { // workaround to determine if dir is under output directory for _, dir := range android.SortedStringKeys(exportedIncludes) { // Skip if dir is for generated headers if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) { continue } Loading @@ -598,14 +618,14 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex if strings.HasSuffix(header, "/") { continue } headers[header] = true globbedHeaders[header] = true } } } for _, header := range android.SortedStringKeys(headers) { installSnapshotFileFromPath(android.PathForSource(ctx, header), filepath.Join(includeDir, header)) for _, header := range android.SortedStringKeys(globbedHeaders) { snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath( android.PathForSource(ctx, header), filepath.Join(includeDir, header))) } isHeader := func(path string) bool { Loading @@ -617,6 +637,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return false } // For generated headers, manually install one by one, rather than glob for _, path := range android.PathsToDirectorySortedPaths(android.FirstUniquePaths(generatedHeaders)) { header := path.String() Loading @@ -624,33 +645,85 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex continue } installSnapshotFileFromPath(path, filepath.Join(includeDir, header)) snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath( path, filepath.Join(includeDir, header))) } } installSnapshotFileFromContent(android.JoinWithSuffix(vndkCoreLibraries, ".so", "\\n"), filepath.Join(configsDir, "vndkcore.libraries.txt")) installSnapshotFileFromContent(android.JoinWithSuffix(vndkPrivateLibraries, ".so", "\\n"), filepath.Join(configsDir, "vndkprivate.libraries.txt")) snapshotOutputs = append(snapshotOutputs, installSnapshotFileFromPath(c.vndkCoreLibrariesFile, filepath.Join(configsDir, "vndkcore.libraries.txt")), installSnapshotFileFromPath(c.vndkPrivateLibrariesFile, filepath.Join(configsDir, "vndkprivate.libraries.txt")), installSnapshotFileFromPath(c.vndkSpLibrariesFile, filepath.Join(configsDir, "vndksp.libraries.txt")), installSnapshotFileFromPath(c.llndkLibrariesFile, filepath.Join(configsDir, "llndk.libraries.txt")), ) var modulePathTxtBuilder strings.Builder /* Dump a map to a list file as: {key1} {value1} {key2} {value2} ... */ installMapListFile := func(m map[string]string, path string) android.OutputPath { var txtBuilder strings.Builder for idx, k := range android.SortedStringKeys(m) { if idx > 0 { txtBuilder.WriteString("\\n") } txtBuilder.WriteString(k) txtBuilder.WriteString(" ") txtBuilder.WriteString(m[k]) } return installSnapshotFileFromContent(txtBuilder.String(), path) } /* module_paths.txt contains paths on which VNDK modules are defined. e.g., libbase.so system/core/base libc.so bionic/libc ... */ snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt"))) /* module_names.txt contains names as which VNDK modules are defined, because output filename and module name can be different with stem and suffix properties. e.g., libcutils.so libcutils libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full ... */ snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt"))) // All artifacts are ready. Sort them to normalize ninja and then zip. sort.Slice(snapshotOutputs, func(i, j int) bool { return snapshotOutputs[i].String() < snapshotOutputs[j].String() }) modulePaths := modulePaths(ctx.Config()) zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip") zipRule := android.NewRuleBuilder() first := true for _, lib := range android.SortedStringKeys(modulePaths) { if first { first = false } else { modulePathTxtBuilder.WriteString("\\n") } modulePathTxtBuilder.WriteString(lib) modulePathTxtBuilder.WriteString(".so ") modulePathTxtBuilder.WriteString(modulePaths[lib]) } // If output files are too many, soong_zip command can exceed ARG_MAX. // So first dump file lists into a single list file, and then feed it to Soong snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list") zipRule.Command(). Text("( xargs"). FlagWithRspFileInputList("-n1 echo < ", snapshotOutputs). FlagWithOutput("| tr -d \\' > ", snapshotOutputList). Text(")") zipRule.Temporary(snapshotOutputList) zipRule.Command(). BuiltTool(ctx, "soong_zip"). FlagWithOutput("-o ", zipPath). FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()). FlagWithInput("-l ", snapshotOutputList) installSnapshotFileFromContent(modulePathTxtBuilder.String(), filepath.Join(configsDir, "module_paths.txt")) zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String()) c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath) } func getVndkFileName(m *Module) (string, error) { Loading Loading @@ -697,7 +770,7 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) vndkcorevariant := android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) c.llnkdLibrariesFile = installListFile(llndk, "llndk.libraries.txt") 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") Loading Loading @@ -739,11 +812,12 @@ 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.llnkdLibrariesFile.String()) 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()) }