Include headers and props to VNDK snapshot

For all vndk snapshot libraries, header files exported by the libraries
will be included to the snapshot. Android.bp will contain necessary
information to link against/install vndk snapshot libraires:
export_include_dirs, export_system_include_dirs, export_flags, and
relative_install_path.

Bug: 132818174
Test: 1) m nothing && mv out/soong/build.ninja /tmp && m nothing &&
         diff -u -u out/soong/build.ninja /tmp/build.ninja
Test: 2) VNDK_SNAPSHOT_BUILD_ARTIFACTS=true \
           development/vndk/snapshot/build.sh
Test: 3) development/vndk/snasphot/update.py
Test: 4) see contents of Android.bp and include directories
Change-Id: I791ab181545eb483242b04446afd40958bbb2b17
This commit is contained in:
Inseob Kim 2019-05-14 18:52:49 +09:00
parent 02ed5df4ac
commit ae55303f36
5 changed files with 203 additions and 133 deletions

View File

@ -852,6 +852,10 @@ func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
return ExistentPathForSource(ctx, "frameworks", "base").Valid() return ExistentPathForSource(ctx, "frameworks", "base").Valid()
} }
func (c *config) VndkSnapshotBuildArtifacts() bool {
return Bool(c.productVariables.VndkSnapshotBuildArtifacts)
}
func (c *deviceConfig) Arches() []Arch { func (c *deviceConfig) Arches() []Arch {
var arches []Arch var arches []Arch
for _, target := range c.config.Targets[Android] { for _, target := range c.config.Targets[Android] {

View File

@ -261,7 +261,8 @@ type productVariables struct {
PgoAdditionalProfileDirs []string `json:",omitempty"` PgoAdditionalProfileDirs []string `json:",omitempty"`
VndkUseCoreVariant *bool `json:",omitempty"` VndkUseCoreVariant *bool `json:",omitempty"`
VndkSnapshotBuildArtifacts *bool `json:",omitempty"`
BoardVendorSepolicyDirs []string `json:",omitempty"` BoardVendorSepolicyDirs []string `json:",omitempty"`
BoardOdmSepolicyDirs []string `json:",omitempty"` BoardOdmSepolicyDirs []string `json:",omitempty"`

View File

@ -508,6 +508,7 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa
type libraryInterface interface { type libraryInterface interface {
getWholeStaticMissingDeps() []string getWholeStaticMissingDeps() []string
static() bool static() bool
shared() bool
objs() Objects objs() Objects
reuseObjs() (Objects, exportedFlagsProducer) reuseObjs() (Objects, exportedFlagsProducer)
toc() android.OptionalPath toc() android.OptionalPath

View File

@ -15,8 +15,8 @@
package cc package cc
import ( import (
"encoding/json"
"errors" "errors"
"fmt"
"path/filepath" "path/filepath"
"sort" "sort"
"strings" "strings"
@ -206,16 +206,9 @@ var (
modulePathsKey = android.NewOnceKey("modulePaths") modulePathsKey = android.NewOnceKey("modulePaths")
vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs") vndkSnapshotOutputsKey = android.NewOnceKey("vndkSnapshotOutputs")
vndkLibrariesLock sync.Mutex vndkLibrariesLock sync.Mutex
)
type vndkSnapshotOutputPaths struct { headerExts = []string{".h", ".hh", ".hpp", ".hxx", ".h++", ".inl", ".inc", ".ipp", ".h.generic"}
configs android.Paths )
notices android.Paths
vndkCoreLibs android.Paths
vndkCoreLibs2nd android.Paths
vndkSpLibs android.Paths
vndkSpLibs2nd android.Paths
}
func vndkCoreLibraries(config android.Config) *[]string { func vndkCoreLibraries(config android.Config) *[]string {
return config.Once(vndkCoreLibrariesKey, func() interface{} { return config.Once(vndkCoreLibrariesKey, func() interface{} {
@ -253,10 +246,10 @@ func modulePaths(config android.Config) map[string]string {
}).(map[string]string) }).(map[string]string)
} }
func vndkSnapshotOutputs(config android.Config) *vndkSnapshotOutputPaths { func vndkSnapshotOutputs(config android.Config) *android.RuleBuilderInstalls {
return config.Once(vndkSnapshotOutputsKey, func() interface{} { return config.Once(vndkSnapshotOutputsKey, func() interface{} {
return &vndkSnapshotOutputPaths{} return &android.RuleBuilderInstalls{}
}).(*vndkSnapshotOutputPaths) }).(*android.RuleBuilderInstalls)
} }
func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
@ -357,13 +350,7 @@ func init() {
android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) { android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
outputs := vndkSnapshotOutputs(ctx.Config()) outputs := vndkSnapshotOutputs(ctx.Config())
ctx.Strict("SOONG_VNDK_SNAPSHOT_FILES", outputs.String())
ctx.Strict("SOONG_VNDK_SNAPSHOT_CONFIGS", strings.Join(outputs.configs.Strings(), " "))
ctx.Strict("SOONG_VNDK_SNAPSHOT_NOTICES", strings.Join(outputs.notices.Strings(), " "))
ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS", strings.Join(outputs.vndkCoreLibs.Strings(), " "))
ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS", strings.Join(outputs.vndkSpLibs.Strings(), " "))
ctx.Strict("SOONG_VNDK_SNAPSHOT_CORE_LIBS_2ND", strings.Join(outputs.vndkCoreLibs2nd.Strings(), " "))
ctx.Strict("SOONG_VNDK_SNAPSHOT_SP_LIBS_2ND", strings.Join(outputs.vndkSpLibs2nd.Strings(), " "))
}) })
} }
@ -373,26 +360,6 @@ func VndkSnapshotSingleton() android.Singleton {
type vndkSnapshotSingleton struct{} type vndkSnapshotSingleton struct{}
func installVndkSnapshotLib(ctx android.SingletonContext, name string, module *Module, dir string) android.Path {
if !module.outputFile.Valid() {
panic(fmt.Errorf("module %s has no outputFile\n", name))
}
out := android.PathForOutput(ctx, dir, name+".so")
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Input: module.outputFile.Path(),
Output: out,
Description: "vndk snapshot " + dir + "/" + name + ".so",
Args: map[string]string{
"cpFlags": "-f -L",
},
})
return out
}
func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
// BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot. // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot.
if ctx.DeviceConfig().VndkVersion() != "current" { if ctx.DeviceConfig().VndkVersion() != "current" {
@ -411,30 +378,58 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
snapshotDir := "vndk-snapshot" snapshotDir := "vndk-snapshot"
var vndkLibPath, vndkLib2ndPath string vndkLibDir := make(map[android.ArchType]string)
snapshotVariantPath := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) snapshotVariantDir := ctx.DeviceConfig().DeviceArch()
if ctx.DeviceConfig().BinderBitness() == "32" { for _, target := range ctx.Config().Targets[android.Android] {
vndkLibPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf( dir := snapshotVariantDir
"arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant())) if ctx.DeviceConfig().BinderBitness() == "32" {
vndkLib2ndPath = filepath.Join(snapshotVariantPath, "binder32", fmt.Sprintf( dir = filepath.Join(dir, "binder32")
"arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant())) }
} else { arch := "arch-" + target.Arch.ArchType.String()
vndkLibPath = filepath.Join(snapshotVariantPath, fmt.Sprintf( if target.Arch.ArchVariant != "" {
"arch-%s-%s", ctx.DeviceConfig().DeviceArch(), ctx.DeviceConfig().DeviceArchVariant())) arch += "-" + target.Arch.ArchVariant
vndkLib2ndPath = filepath.Join(snapshotVariantPath, fmt.Sprintf( }
"arch-%s-%s", ctx.DeviceConfig().DeviceSecondaryArch(), ctx.DeviceConfig().DeviceSecondaryArchVariant())) dir = filepath.Join(dir, arch)
vndkLibDir[target.Arch.ArchType] = dir
} }
configsDir := filepath.Join(snapshotVariantDir, "configs")
vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core") noticeDir := filepath.Join(snapshotVariantDir, "NOTICE_FILES")
vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp") includeDir := filepath.Join(snapshotVariantDir, "include")
vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
noticePath := filepath.Join(snapshotVariantPath, "NOTICE_FILES")
noticeBuilt := make(map[string]bool) noticeBuilt := make(map[string]bool)
installSnapshotFileFromPath := func(path android.Path, out string) {
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Input: path,
Output: android.PathForOutput(ctx, snapshotDir, out),
Description: "vndk snapshot " + out,
Args: map[string]string{
"cpFlags": "-f -L",
},
})
*outputs = append(*outputs, android.RuleBuilderInstall{
From: android.PathForOutput(ctx, snapshotDir, out),
To: out,
})
}
installSnapshotFileFromContent := func(content, out string) {
ctx.Build(pctx, android.BuildParams{
Rule: android.WriteFile,
Output: android.PathForOutput(ctx, snapshotDir, out),
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) { tryBuildNotice := func(m *Module) {
name := ctx.ModuleName(m) name := ctx.ModuleName(m) + ".so.txt"
if _, ok := noticeBuilt[name]; ok { if _, ok := noticeBuilt[name]; ok {
return return
@ -443,17 +438,7 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
noticeBuilt[name] = true noticeBuilt[name] = true
if m.NoticeFile().Valid() { if m.NoticeFile().Valid() {
out := android.PathForOutput(ctx, noticePath, name+".so.txt") installSnapshotFileFromPath(m.NoticeFile().Path(), filepath.Join(noticeDir, name))
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Input: m.NoticeFile().Path(),
Output: out,
Description: "vndk snapshot notice " + name + ".so.txt",
Args: map[string]string{
"cpFlags": "-f -L",
},
})
outputs.notices = append(outputs.notices, out)
} }
} }
@ -461,84 +446,160 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
vndkSpLibraries := vndkSpLibraries(ctx.Config()) vndkSpLibraries := vndkSpLibraries(ctx.Config())
vndkPrivateLibraries := vndkPrivateLibraries(ctx.Config()) vndkPrivateLibraries := vndkPrivateLibraries(ctx.Config())
var generatedHeaders android.Paths
includeDirs := make(map[string]bool)
type vndkSnapshotLibraryInterface interface {
exportedFlagsProducer
libraryInterface
}
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")
installSnapshotFileFromPath(m.outputFile.Path(), libOut)
tryBuildNotice(m)
if ctx.Config().VndkSnapshotBuildArtifacts() {
prop := struct {
ExportedDirs []string `json:",omitempty"`
ExportedSystemDirs []string `json:",omitempty"`
ExportedFlags []string `json:",omitempty"`
RelativeInstallPath string `json:",omitempty"`
}{}
prop.ExportedFlags = l.exportedFlags()
prop.ExportedDirs = l.exportedDirs()
prop.ExportedSystemDirs = l.exportedSystemDirs()
prop.RelativeInstallPath = m.RelativeInstallPath()
propOut := libOut + ".json"
j, err := json.Marshal(prop)
if err != nil {
ctx.Errorf("json marshal to %q failed: %#v", propOut, err)
return false
}
installSnapshotFileFromContent(string(j), propOut)
}
return true
}
isVndkSnapshotLibrary := func(m *Module) (i vndkSnapshotLibraryInterface, libDir string, isVndkSnapshotLib bool) {
if m.Target().NativeBridge == android.NativeBridgeEnabled {
return nil, "", false
}
if !m.useVndk() || !m.IsForPlatform() || !m.installable() {
return nil, "", false
}
l, ok := m.linker.(vndkSnapshotLibraryInterface)
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
} else {
return nil, "", false
}
}
ctx.VisitAllModules(func(module android.Module) { ctx.VisitAllModules(func(module android.Module) {
m, ok := module.(*Module) m, ok := module.(*Module)
if !ok || !m.Enabled() || !m.useVndk() || !m.installable() { if !ok || !m.Enabled() {
return return
} }
if m.Target().NativeBridge == android.NativeBridgeEnabled { baseDir, ok := vndkLibDir[m.Target().Arch.ArchType]
if !ok {
return return
} }
lib, is_lib := m.linker.(*libraryDecorator) l, libDir, ok := isVndkSnapshotLibrary(m)
prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker) if !ok {
if !(is_lib && lib.shared()) && !(is_prebuilt_lib && prebuilt_lib.shared()) {
return return
} }
is_2nd := m.Target().Arch.ArchType != ctx.Config().DevicePrimaryArchType() if !installVndkSnapshotLib(m, l, filepath.Join(baseDir, libDir)) {
return
}
name := ctx.ModuleName(module) generatedHeaders = append(generatedHeaders, l.exportedDeps()...)
for _, dir := range append(l.exportedDirs(), l.exportedSystemDirs()...) {
includeDirs[dir] = true
}
})
if inList(name, *vndkCoreLibraries) { if ctx.Config().VndkSnapshotBuildArtifacts() {
if is_2nd { headers := make(map[string]bool)
out := installVndkSnapshotLib(ctx, name, m, vndkCoreLib2ndPath)
outputs.vndkCoreLibs2nd = append(outputs.vndkCoreLibs2nd, out) for _, dir := range android.SortedStringKeys(includeDirs) {
} else { // workaround to determine if dir is under output directory
out := installVndkSnapshotLib(ctx, name, m, vndkCoreLibPath) if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
outputs.vndkCoreLibs = append(outputs.vndkCoreLibs, out) continue
} }
tryBuildNotice(m) exts := headerExts
} else if inList(name, *vndkSpLibraries) { // Glob all files under this special directory, because of C++ headers.
if is_2nd { if strings.HasPrefix(dir, "external/libcxx/include") {
out := installVndkSnapshotLib(ctx, name, m, vndkSpLib2ndPath) exts = []string{""}
outputs.vndkSpLibs2nd = append(outputs.vndkSpLibs2nd, out) }
} else { for _, ext := range exts {
out := installVndkSnapshotLib(ctx, name, m, vndkSpLibPath) glob, err := ctx.GlobWithDeps(dir+"/**/*"+ext, nil)
outputs.vndkSpLibs = append(outputs.vndkSpLibs, out) if err != nil {
ctx.Errorf("%#v\n", err)
return
}
for _, header := range glob {
if strings.HasSuffix(header, "/") {
continue
}
headers[header] = true
}
} }
tryBuildNotice(m)
} }
})
configsPath := filepath.Join(snapshotVariantPath, "configs") for _, header := range android.SortedStringKeys(headers) {
vndkCoreTxt := android.PathForOutput(ctx, configsPath, "vndkcore.libraries.txt") installSnapshotFileFromPath(android.PathForSource(ctx, header),
vndkPrivateTxt := android.PathForOutput(ctx, configsPath, "vndkprivate.libraries.txt") filepath.Join(includeDir, header))
modulePathTxt := android.PathForOutput(ctx, configsPath, "module_paths.txt") }
ctx.Build(pctx, android.BuildParams{ isHeader := func(path string) bool {
Rule: android.WriteFile, for _, ext := range headerExts {
Output: vndkCoreTxt, if strings.HasSuffix(path, ext) {
Description: "vndk snapshot vndkcore.libraries.txt", return true
Args: map[string]string{ }
"content": android.JoinWithSuffix(*vndkCoreLibraries, ".so", "\\n"), }
}, return false
}) }
outputs.configs = append(outputs.configs, vndkCoreTxt)
ctx.Build(pctx, android.BuildParams{ for _, path := range android.PathsToDirectorySortedPaths(android.FirstUniquePaths(generatedHeaders)) {
Rule: android.WriteFile, header := path.String()
Output: vndkPrivateTxt,
Description: "vndk snapshot vndkprivate.libraries.txt", if !isHeader(header) {
Args: map[string]string{ continue
"content": android.JoinWithSuffix(*vndkPrivateLibraries, ".so", "\\n"), }
},
}) installSnapshotFileFromPath(path, filepath.Join(includeDir, header))
outputs.configs = append(outputs.configs, vndkPrivateTxt) }
}
installSnapshotFileFromContent(android.JoinWithSuffix(*vndkCoreLibraries, ".so", "\\n"),
filepath.Join(configsDir, "vndkcore.libraries.txt"))
installSnapshotFileFromContent(android.JoinWithSuffix(*vndkPrivateLibraries, ".so", "\\n"),
filepath.Join(configsDir, "vndkprivate.libraries.txt"))
var modulePathTxtBuilder strings.Builder var modulePathTxtBuilder strings.Builder
modulePaths := modulePaths(ctx.Config()) modulePaths := modulePaths(ctx.Config())
var libs []string
for lib := range modulePaths {
libs = append(libs, lib)
}
sort.Strings(libs)
first := true first := true
for _, lib := range libs { for _, lib := range android.SortedStringKeys(modulePaths) {
if first { if first {
first = false first = false
} else { } else {
@ -549,13 +610,6 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
modulePathTxtBuilder.WriteString(modulePaths[lib]) modulePathTxtBuilder.WriteString(modulePaths[lib])
} }
ctx.Build(pctx, android.BuildParams{ installSnapshotFileFromContent(modulePathTxtBuilder.String(),
Rule: android.WriteFile, filepath.Join(configsDir, "module_paths.txt"))
Output: modulePathTxt,
Description: "vndk snapshot module_paths.txt",
Args: map[string]string{
"content": modulePathTxtBuilder.String(),
},
})
outputs.configs = append(outputs.configs, modulePathTxt)
} }

View File

@ -61,6 +61,13 @@ type vndkPrebuiltProperties struct {
// Prebuilt files for each arch. // Prebuilt files for each arch.
Srcs []string `android:"arch_variant"` Srcs []string `android:"arch_variant"`
// list of directories relative to the Blueprints file that will be added to the include
// path (using -isystem) for any module that links against this module.
Export_system_include_dirs []string `android:"arch_variant"`
// list of flags that will be used for any module that links against this module.
Export_flags []string `android:"arch_variant"`
// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols, // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
// etc). // etc).
Check_elf_files *bool Check_elf_files *bool
@ -123,6 +130,9 @@ func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) andro
func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext, func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path { flags Flags, deps PathDeps, objs Objects) android.Path {
if len(p.properties.Srcs) > 0 && p.shared() { if len(p.properties.Srcs) > 0 && p.shared() {
p.libraryDecorator.exportIncludes(ctx)
p.libraryDecorator.reexportSystemDirs(p.properties.Export_system_include_dirs...)
p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
// current VNDK prebuilts are only shared libs. // current VNDK prebuilts are only shared libs.
return p.singleSourcePath(ctx) return p.singleSourcePath(ctx)
} }