native shared libs in an SDK can be snapshotted
The snapshot script can now handle native shared libs in an SDK. Bug: 138182343 Test: create following sdk module: sdk { name: "mysdk", native_shared_libs: ["libc", "libdl"], } , then execute `m mysdk` and execute the update_prebuilt-1.sh as prompted. Following directories are generated under the directory where mysdk is defined at: 1 ├── aidl ├── Android.bp ├── arm64 │ ├── include │ ├── include_gen │ └── lib │ ├── libc.so │ └── libdl.so ├── include │ └── bionic │ └── libc │ └── include │ ├── alloca.h │ ├── android │ │ ├── api-level.h <omitted> Change-Id: Ia1dcc5564c1cd17c6ccf441d06d5995af55db9ee
This commit is contained in:
parent
4f45daf9ed
commit
73c54ee7fe
4 changed files with 402 additions and 75 deletions
33
cc/cc.go
33
cc/cc.go
|
@ -689,6 +689,27 @@ func (c *Module) nativeCoverage() bool {
|
|||
return c.linker != nil && c.linker.nativeCoverage()
|
||||
}
|
||||
|
||||
func (c *Module) ExportedIncludeDirs() android.Paths {
|
||||
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
|
||||
return flagsProducer.exportedDirs()
|
||||
}
|
||||
return []android.Path{}
|
||||
}
|
||||
|
||||
func (c *Module) ExportedSystemIncludeDirs() android.Paths {
|
||||
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
|
||||
return flagsProducer.exportedSystemDirs()
|
||||
}
|
||||
return []android.Path{}
|
||||
}
|
||||
|
||||
func (c *Module) ExportedFlags() []string {
|
||||
if flagsProducer, ok := c.linker.(exportedFlagsProducer); ok {
|
||||
return flagsProducer.exportedFlags()
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func isBionic(name string) bool {
|
||||
switch name {
|
||||
case "libc", "libm", "libdl", "linker":
|
||||
|
@ -1290,7 +1311,7 @@ func (c *Module) beginMutator(actx android.BottomUpMutatorContext) {
|
|||
}
|
||||
|
||||
// Split name#version into name and version
|
||||
func stubsLibNameAndVersion(name string) (string, string) {
|
||||
func StubsLibNameAndVersion(name string) (string, string) {
|
||||
if sharp := strings.LastIndex(name, "#"); sharp != -1 && sharp != len(name)-1 {
|
||||
version := name[sharp+1:]
|
||||
libname := name[:sharp]
|
||||
|
@ -1337,7 +1358,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||
nonvariantLibs = []string{}
|
||||
for _, entry := range list {
|
||||
// strip #version suffix out
|
||||
name, _ := stubsLibNameAndVersion(entry)
|
||||
name, _ := StubsLibNameAndVersion(entry)
|
||||
if ctx.useSdk() && inList(name, ndkPrebuiltSharedLibraries) {
|
||||
if !inList(name, ndkMigratedLibs) {
|
||||
nonvariantLibs = append(nonvariantLibs, name+".ndk."+version)
|
||||
|
@ -1443,7 +1464,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||
// If the version is not specified, add dependency to the latest stubs library.
|
||||
// The stubs library will be used when the depending module is built for APEX and
|
||||
// the dependent module is not in the same APEX.
|
||||
latestVersion := latestStubsVersionFor(actx.Config(), name)
|
||||
latestVersion := LatestStubsVersionFor(actx.Config(), name)
|
||||
if version == "" && latestVersion != "" && versionVariantAvail {
|
||||
actx.AddVariationDependencies([]blueprint.Variation{
|
||||
{Mutator: "link", Variation: "shared"},
|
||||
|
@ -1466,7 +1487,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
|
|||
lib = impl
|
||||
}
|
||||
|
||||
name, version := stubsLibNameAndVersion(lib)
|
||||
name, version := StubsLibNameAndVersion(lib)
|
||||
sharedLibNames = append(sharedLibNames, name)
|
||||
|
||||
addSharedLibDependencies(depTag, name, version)
|
||||
|
@ -2142,7 +2163,9 @@ func (c *Module) IsInstallableToApex() bool {
|
|||
if shared, ok := c.linker.(interface {
|
||||
shared() bool
|
||||
}); ok {
|
||||
return shared.shared()
|
||||
// Stub libs and prebuilt libs in a versioned SDK are not
|
||||
// installable to APEX even though they are shared libs.
|
||||
return shared.shared() && !c.IsStubs() && c.ContainingSdk().Unversioned()
|
||||
} else if _, ok := c.linker.(testPerSrc); ok {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -158,6 +158,10 @@ type FlagExporterProperties struct {
|
|||
// listed in local_include_dirs.
|
||||
Export_include_dirs []string `android:"arch_variant"`
|
||||
|
||||
// list of directories that will be added to the system include path
|
||||
// using -isystem for this module and any module that links against this module.
|
||||
Export_system_include_dirs []string `android:"arch_variant"`
|
||||
|
||||
Target struct {
|
||||
Vendor struct {
|
||||
// list of exported include directories, like
|
||||
|
@ -245,10 +249,13 @@ func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
|
|||
|
||||
func (f *flagExporter) exportIncludes(ctx ModuleContext) {
|
||||
f.dirs = append(f.dirs, f.exportedIncludes(ctx)...)
|
||||
f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
|
||||
}
|
||||
|
||||
func (f *flagExporter) exportIncludesAsSystem(ctx ModuleContext) {
|
||||
// all dirs are force exported as system
|
||||
f.systemDirs = append(f.systemDirs, f.exportedIncludes(ctx)...)
|
||||
f.systemDirs = append(f.systemDirs, android.PathsForModuleSrc(ctx, f.Properties.Export_system_include_dirs)...)
|
||||
}
|
||||
|
||||
func (f *flagExporter) reexportDirs(dirs ...android.Path) {
|
||||
|
@ -1280,7 +1287,7 @@ func stubsVersionsFor(config android.Config) map[string][]string {
|
|||
|
||||
var stubsVersionsLock sync.Mutex
|
||||
|
||||
func latestStubsVersionFor(config android.Config, name string) string {
|
||||
func LatestStubsVersionFor(config android.Config, name string) string {
|
||||
versions, ok := stubsVersionsFor(config)[name]
|
||||
if ok && len(versions) > 0 {
|
||||
// the versions are alreay sorted in ascending order
|
||||
|
|
16
sdk/sdk.go
16
sdk/sdk.go
|
@ -24,6 +24,7 @@ import (
|
|||
// This package doesn't depend on the apex package, but import it to make its mutators to be
|
||||
// registered before mutators in this package. See RegisterPostDepsMutators for more details.
|
||||
_ "android/soong/apex"
|
||||
"android/soong/cc"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -148,10 +149,17 @@ func memberMutator(mctx android.BottomUpMutatorContext) {
|
|||
|
||||
targets := mctx.MultiTargets()
|
||||
for _, target := range targets {
|
||||
mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
|
||||
{Mutator: "image", Variation: "core"},
|
||||
{Mutator: "link", Variation: "shared"},
|
||||
}...), sdkMemberDepTag, m.properties.Native_shared_libs...)
|
||||
for _, lib := range m.properties.Native_shared_libs {
|
||||
name, version := cc.StubsLibNameAndVersion(lib)
|
||||
if version == "" {
|
||||
version = cc.LatestStubsVersionFor(mctx.Config(), name)
|
||||
}
|
||||
mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
|
||||
{Mutator: "image", Variation: "core"},
|
||||
{Mutator: "link", Variation: "shared"},
|
||||
{Mutator: "version", Variation: version},
|
||||
}...), sdkMemberDepTag, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
419
sdk/update.go
419
sdk/update.go
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/google/blueprint/proptools"
|
||||
|
||||
"android/soong/android"
|
||||
"android/soong/cc"
|
||||
"android/soong/java"
|
||||
)
|
||||
|
||||
|
@ -32,21 +33,31 @@ var pctx = android.NewPackageContext("android/soong/sdk")
|
|||
// generatedFile abstracts operations for writing contents into a file and emit a build rule
|
||||
// for the file.
|
||||
type generatedFile struct {
|
||||
path android.OutputPath
|
||||
content strings.Builder
|
||||
path android.OutputPath
|
||||
content strings.Builder
|
||||
indentLevel int
|
||||
}
|
||||
|
||||
func newGeneratedFile(ctx android.ModuleContext, name string) *generatedFile {
|
||||
return &generatedFile{
|
||||
path: android.PathForModuleOut(ctx, name).OutputPath,
|
||||
path: android.PathForModuleOut(ctx, name).OutputPath,
|
||||
indentLevel: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (gf *generatedFile) indent() {
|
||||
gf.indentLevel++
|
||||
}
|
||||
|
||||
func (gf *generatedFile) dedent() {
|
||||
gf.indentLevel--
|
||||
}
|
||||
|
||||
func (gf *generatedFile) printfln(format string, args ...interface{}) {
|
||||
// ninja consumes newline characters in rspfile_content. Prevent it by
|
||||
// escaping the backslash in the newline character. The extra backshash
|
||||
// is removed when the rspfile is written to the actual script file
|
||||
fmt.Fprintf(&(gf.content), format+"\\n", args...)
|
||||
fmt.Fprintf(&(gf.content), strings.Repeat(" ", gf.indentLevel)+format+"\\n", args...)
|
||||
}
|
||||
|
||||
func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
|
||||
|
@ -61,34 +72,187 @@ func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderC
|
|||
rb.Build(pctx, ctx, gf.path.Base(), "Build "+gf.path.Base())
|
||||
}
|
||||
|
||||
func (s *sdk) javaMemberNames(ctx android.ModuleContext) []string {
|
||||
result := []string{}
|
||||
func (s *sdk) javaLibs(ctx android.ModuleContext) []*java.Library {
|
||||
result := []*java.Library{}
|
||||
ctx.VisitDirectDeps(func(m android.Module) {
|
||||
if _, ok := m.(*java.Library); ok {
|
||||
result = append(result, m.Name())
|
||||
if j, ok := m.(*java.Library); ok {
|
||||
result = append(result, j)
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
// buildAndroidBp creates the blueprint file that defines prebuilt modules for each of
|
||||
// the SDK members, and the sdk_snapshot module for the specified version
|
||||
func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.OutputPath {
|
||||
bp := newGeneratedFile(ctx, "blueprint-"+version+".sh")
|
||||
// archSpecificNativeLibInfo represents an arch-specific variant of a native lib
|
||||
type archSpecificNativeLibInfo struct {
|
||||
name string
|
||||
archType string
|
||||
exportedIncludeDirs android.Paths
|
||||
exportedSystemIncludeDirs android.Paths
|
||||
exportedFlags []string
|
||||
outputFile android.Path
|
||||
}
|
||||
|
||||
makePrebuiltName := func(name string) string {
|
||||
return ctx.ModuleName() + "_" + name + string(android.SdkVersionSeparator) + version
|
||||
func (lib *archSpecificNativeLibInfo) signature() string {
|
||||
return fmt.Sprintf("%v %v %v %v",
|
||||
lib.name,
|
||||
lib.exportedIncludeDirs.Strings(),
|
||||
lib.exportedSystemIncludeDirs.Strings(),
|
||||
lib.exportedFlags)
|
||||
}
|
||||
|
||||
// nativeLibInfo represents a collection of arch-specific modules having the same name
|
||||
type nativeLibInfo struct {
|
||||
name string
|
||||
archVariants []archSpecificNativeLibInfo
|
||||
// hasArchSpecificFlags is set to true if modules for each architecture all have the same
|
||||
// include dirs, flags, etc, in which case only those of the first arch is selected.
|
||||
hasArchSpecificFlags bool
|
||||
}
|
||||
|
||||
// nativeMemberInfos collects all cc.Modules that are member of an SDK.
|
||||
func (s *sdk) nativeMemberInfos(ctx android.ModuleContext) []*nativeLibInfo {
|
||||
infoMap := make(map[string]*nativeLibInfo)
|
||||
|
||||
// Collect cc.Modules
|
||||
ctx.VisitDirectDeps(func(m android.Module) {
|
||||
ccModule, ok := m.(*cc.Module)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
depName := ctx.OtherModuleName(m)
|
||||
|
||||
if _, ok := infoMap[depName]; !ok {
|
||||
infoMap[depName] = &nativeLibInfo{name: depName}
|
||||
}
|
||||
|
||||
info := infoMap[depName]
|
||||
info.archVariants = append(info.archVariants, archSpecificNativeLibInfo{
|
||||
name: ccModule.BaseModuleName(),
|
||||
archType: ccModule.Target().Arch.ArchType.String(),
|
||||
exportedIncludeDirs: ccModule.ExportedIncludeDirs(),
|
||||
exportedSystemIncludeDirs: ccModule.ExportedSystemIncludeDirs(),
|
||||
exportedFlags: ccModule.ExportedFlags(),
|
||||
outputFile: ccModule.OutputFile().Path(),
|
||||
})
|
||||
})
|
||||
|
||||
// Determine if include dirs and flags for each module are different across arch-specific
|
||||
// modules or not. And set hasArchSpecificFlags accordingly
|
||||
for _, info := range infoMap {
|
||||
// by default, include paths and flags are assumed to be the same across arches
|
||||
info.hasArchSpecificFlags = false
|
||||
oldSignature := ""
|
||||
for _, av := range info.archVariants {
|
||||
newSignature := av.signature()
|
||||
if oldSignature == "" {
|
||||
oldSignature = newSignature
|
||||
}
|
||||
if oldSignature != newSignature {
|
||||
info.hasArchSpecificFlags = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
javaLibs := s.javaMemberNames(ctx)
|
||||
for _, name := range javaLibs {
|
||||
prebuiltName := makePrebuiltName(name)
|
||||
jar := filepath.Join("java", name, "stub.jar")
|
||||
var list []*nativeLibInfo
|
||||
for _, v := range infoMap {
|
||||
list = append(list, v)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// SDK directory structure
|
||||
// <sdk_root>/
|
||||
// Android.bp : definition of a 'sdk' module is here. This is a hand-made one.
|
||||
// <api_ver>/ : below this directory are all auto-generated
|
||||
// Android.bp : definition of 'sdk_snapshot' module is here
|
||||
// aidl/
|
||||
// frameworks/base/core/..../IFoo.aidl : an exported AIDL file
|
||||
// java/
|
||||
// java/<module_name>/stub.jar : a stub jar for a java library 'module_name'
|
||||
// include/
|
||||
// bionic/libc/include/stdlib.h : an exported header file
|
||||
// include_gen/
|
||||
// com/android/.../IFoo.h : a generated header file
|
||||
// <arch>/include/ : arch-specific exported headers
|
||||
// <arch>/include_gen/ : arch-specific generated headers
|
||||
// <arch>/lib/
|
||||
// libFoo.so : a stub library
|
||||
|
||||
const (
|
||||
aidlIncludeDir = "aidl"
|
||||
javaStubDir = "java"
|
||||
javaStubFile = "stub.jar"
|
||||
nativeIncludeDir = "include"
|
||||
nativeGeneratedIncludeDir = "include_gen"
|
||||
nativeStubDir = "lib"
|
||||
nativeStubFileSuffix = ".so"
|
||||
)
|
||||
|
||||
// path to the stub file of a java library. Relative to <sdk_root>/<api_dir>
|
||||
func javaStubFilePathFor(javaLib *java.Library) string {
|
||||
return filepath.Join(javaStubDir, javaLib.Name(), javaStubFile)
|
||||
}
|
||||
|
||||
// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
|
||||
func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
|
||||
return filepath.Join(lib.archType,
|
||||
nativeStubDir, lib.name+nativeStubFileSuffix)
|
||||
}
|
||||
|
||||
// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
|
||||
func nativeIncludeDirPathsFor(ctx android.ModuleContext, lib archSpecificNativeLibInfo,
|
||||
systemInclude bool, archSpecific bool) []string {
|
||||
var result []string
|
||||
buildDir := ctx.Config().BuildDir()
|
||||
var includeDirs []android.Path
|
||||
if !systemInclude {
|
||||
includeDirs = lib.exportedIncludeDirs
|
||||
} else {
|
||||
includeDirs = lib.exportedSystemIncludeDirs
|
||||
}
|
||||
for _, dir := range includeDirs {
|
||||
var path string
|
||||
if gen := strings.HasPrefix(dir.String(), buildDir); gen {
|
||||
path = filepath.Join(nativeGeneratedIncludeDir, dir.Rel())
|
||||
} else {
|
||||
path = filepath.Join(nativeIncludeDir, dir.String())
|
||||
}
|
||||
if archSpecific {
|
||||
path = filepath.Join(lib.archType, path)
|
||||
}
|
||||
result = append(result, path)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// A name that uniquely identifies an prebuilt SDK member for a version of SDK snapshot
|
||||
// This isn't visible to users, so could be changed in future.
|
||||
func versionedSdkMemberName(ctx android.ModuleContext, memberName string, version string) string {
|
||||
return ctx.ModuleName() + "_" + memberName + string(android.SdkVersionSeparator) + version
|
||||
}
|
||||
|
||||
// arm64, arm, x86, x86_64, etc.
|
||||
func archTypeOf(module android.Module) string {
|
||||
return module.Target().Arch.ArchType.String()
|
||||
}
|
||||
|
||||
// buildAndroidBp creates the blueprint file that defines prebuilt modules for each of
|
||||
// the SDK members, and the entire sdk_snapshot module for the specified version
|
||||
func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.OutputPath {
|
||||
bp := newGeneratedFile(ctx, "blueprint-"+version+".bp")
|
||||
bp.printfln("// This is auto-generated. DO NOT EDIT.")
|
||||
bp.printfln("")
|
||||
|
||||
javaLibModules := s.javaLibs(ctx)
|
||||
for _, m := range javaLibModules {
|
||||
name := m.Name()
|
||||
bp.printfln("java_import {")
|
||||
bp.printfln(" name: %q,", prebuiltName)
|
||||
bp.printfln(" jars: [%q],", jar)
|
||||
bp.printfln(" sdk_member_name: %q,", name)
|
||||
bp.indent()
|
||||
bp.printfln("name: %q,", versionedSdkMemberName(ctx, name, version))
|
||||
bp.printfln("sdk_member_name: %q,", name)
|
||||
bp.printfln("jars: [%q],", javaStubFilePathFor(m))
|
||||
bp.dedent()
|
||||
bp.printfln("}")
|
||||
bp.printfln("")
|
||||
|
||||
|
@ -96,25 +260,92 @@ func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.
|
|||
// doesn't exist (i.e. building in an unbundled tree). "prefer:" is set to false
|
||||
// so that this module does not eclipse the unversioned module if it exists.
|
||||
bp.printfln("java_import {")
|
||||
bp.printfln(" name: %q,", name)
|
||||
bp.printfln(" jars: [%q],", jar)
|
||||
bp.printfln(" prefer: false,")
|
||||
bp.indent()
|
||||
bp.printfln("name: %q,", name)
|
||||
bp.printfln("jars: [%q],", javaStubFilePathFor(m))
|
||||
bp.printfln("prefer: false,")
|
||||
bp.dedent()
|
||||
bp.printfln("}")
|
||||
bp.printfln("")
|
||||
|
||||
}
|
||||
|
||||
// TODO(jiyong): emit cc_prebuilt_library_shared for the native libs
|
||||
nativeLibInfos := s.nativeMemberInfos(ctx)
|
||||
for _, info := range nativeLibInfos {
|
||||
bp.printfln("cc_prebuilt_library_shared {")
|
||||
bp.indent()
|
||||
bp.printfln("name: %q,", versionedSdkMemberName(ctx, info.name, version))
|
||||
bp.printfln("sdk_member_name: %q,", info.name)
|
||||
|
||||
// a function for emitting include dirs
|
||||
printExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, systemInclude bool) {
|
||||
includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
|
||||
if len(includeDirs) == 0 {
|
||||
return
|
||||
}
|
||||
if !systemInclude {
|
||||
bp.printfln("export_include_dirs: [")
|
||||
} else {
|
||||
bp.printfln("export_system_include_dirs: [")
|
||||
}
|
||||
bp.indent()
|
||||
for _, dir := range includeDirs {
|
||||
bp.printfln("%q,", dir)
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("],")
|
||||
}
|
||||
|
||||
if !info.hasArchSpecificFlags {
|
||||
printExportedDirsForNativeLibs(info.archVariants[0], false /*systemInclude*/)
|
||||
printExportedDirsForNativeLibs(info.archVariants[0], true /*systemInclude*/)
|
||||
}
|
||||
|
||||
bp.printfln("arch: {")
|
||||
bp.indent()
|
||||
for _, av := range info.archVariants {
|
||||
bp.printfln("%s: {", av.archType)
|
||||
bp.indent()
|
||||
bp.printfln("srcs: [%q],", nativeStubFilePathFor(av))
|
||||
if info.hasArchSpecificFlags {
|
||||
// export_* properties are added inside the arch: {<arch>: {...}} block
|
||||
printExportedDirsForNativeLibs(av, false /*systemInclude*/)
|
||||
printExportedDirsForNativeLibs(av, true /*systemInclude*/)
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("},") // <arch>
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("},") // arch
|
||||
bp.printfln("stl: \"none\",")
|
||||
bp.printfln("system_shared_libs: [],")
|
||||
bp.dedent()
|
||||
bp.printfln("}") // cc_prebuilt_library_shared
|
||||
bp.printfln("")
|
||||
}
|
||||
|
||||
bp.printfln("sdk_snapshot {")
|
||||
bp.printfln(" name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+version)
|
||||
bp.printfln(" java_libs: [")
|
||||
for _, n := range javaLibs {
|
||||
bp.printfln(" %q,", makePrebuiltName(n))
|
||||
bp.indent()
|
||||
bp.printfln("name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+version)
|
||||
if len(javaLibModules) > 0 {
|
||||
bp.printfln("java_libs: [")
|
||||
bp.indent()
|
||||
for _, m := range javaLibModules {
|
||||
bp.printfln("%q,", versionedSdkMemberName(ctx, m.Name(), version))
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("],") // java_libs
|
||||
}
|
||||
bp.printfln(" ],")
|
||||
// TODO(jiyong): emit native_shared_libs
|
||||
bp.printfln("}")
|
||||
if len(nativeLibInfos) > 0 {
|
||||
bp.printfln("native_shared_libs: [")
|
||||
bp.indent()
|
||||
for _, info := range nativeLibInfos {
|
||||
bp.printfln("%q,", versionedSdkMemberName(ctx, info.name, version))
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("],") // native_shared_libs
|
||||
}
|
||||
bp.dedent()
|
||||
bp.printfln("}") // sdk_snapshot
|
||||
bp.printfln("")
|
||||
|
||||
bp.build(pctx, ctx, nil)
|
||||
|
@ -123,46 +354,104 @@ func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.
|
|||
|
||||
func (s *sdk) buildScript(ctx android.ModuleContext, version string) android.OutputPath {
|
||||
sh := newGeneratedFile(ctx, "update_prebuilt-"+version+".sh")
|
||||
buildDir := ctx.Config().BuildDir()
|
||||
|
||||
snapshotRoot := filepath.Join(ctx.ModuleDir(), version)
|
||||
aidlIncludeDir := filepath.Join(snapshotRoot, "aidl")
|
||||
javaStubsDir := filepath.Join(snapshotRoot, "java")
|
||||
snapshotPath := func(paths ...string) string {
|
||||
return filepath.Join(ctx.ModuleDir(), version, filepath.Join(paths...))
|
||||
}
|
||||
|
||||
// TODO(jiyong) instead of creating script, create a zip file having the Android.bp, the headers,
|
||||
// and the stubs and put it to the dist directory. The dist'ed zip file then would be downloaded,
|
||||
// unzipped and then uploaded to gerrit again.
|
||||
sh.printfln("#!/bin/bash")
|
||||
sh.printfln("echo Updating snapshot of %s in %s", ctx.ModuleName(), snapshotRoot)
|
||||
sh.printfln("echo Updating snapshot of %s in %s", ctx.ModuleName(), snapshotPath())
|
||||
sh.printfln("pushd $ANDROID_BUILD_TOP > /dev/null")
|
||||
sh.printfln("rm -rf %s", snapshotRoot)
|
||||
sh.printfln("mkdir -p %s", aidlIncludeDir)
|
||||
sh.printfln("mkdir -p %s", javaStubsDir)
|
||||
// TODO(jiyong): mkdir the 'native' dir
|
||||
sh.printfln("mkdir -p %s", snapshotPath(aidlIncludeDir))
|
||||
sh.printfln("mkdir -p %s", snapshotPath(javaStubDir))
|
||||
sh.printfln("mkdir -p %s", snapshotPath(nativeIncludeDir))
|
||||
sh.printfln("mkdir -p %s", snapshotPath(nativeGeneratedIncludeDir))
|
||||
for _, target := range ctx.MultiTargets() {
|
||||
arch := target.Arch.ArchType.String()
|
||||
sh.printfln("mkdir -p %s", snapshotPath(arch, nativeStubDir))
|
||||
sh.printfln("mkdir -p %s", snapshotPath(arch, nativeIncludeDir))
|
||||
sh.printfln("mkdir -p %s", snapshotPath(arch, nativeGeneratedIncludeDir))
|
||||
}
|
||||
|
||||
var implicits android.Paths
|
||||
ctx.VisitDirectDeps(func(m android.Module) {
|
||||
if javaLib, ok := m.(*java.Library); ok {
|
||||
headerJars := javaLib.HeaderJars()
|
||||
if len(headerJars) != 1 {
|
||||
panic(fmt.Errorf("there must be only one header jar from %q", m.Name()))
|
||||
}
|
||||
implicits = append(implicits, headerJars...)
|
||||
|
||||
exportedAidlIncludeDirs := javaLib.AidlIncludeDirs()
|
||||
for _, dir := range exportedAidlIncludeDirs {
|
||||
// Using tar to copy with the directory structure
|
||||
// TODO(jiyong): copy parcelable declarations only
|
||||
sh.printfln("find %s -name \"*.aidl\" | tar cf - -T - | (cd %s; tar xf -)",
|
||||
dir.String(), aidlIncludeDir)
|
||||
}
|
||||
|
||||
copiedHeaderJar := filepath.Join(javaStubsDir, m.Name(), "stub.jar")
|
||||
sh.printfln("mkdir -p $(dirname %s) && cp %s %s",
|
||||
copiedHeaderJar, headerJars[0].String(), copiedHeaderJar)
|
||||
for _, m := range s.javaLibs(ctx) {
|
||||
headerJars := m.HeaderJars()
|
||||
if len(headerJars) != 1 {
|
||||
panic(fmt.Errorf("there must be only one header jar from %q", m.Name()))
|
||||
}
|
||||
// TODO(jiyong): emit the commands for copying the headers and stub libraries for native libs
|
||||
})
|
||||
implicits = append(implicits, headerJars...)
|
||||
|
||||
exportedAidlIncludeDirs := m.AidlIncludeDirs()
|
||||
for _, dir := range exportedAidlIncludeDirs {
|
||||
// Using tar to copy with the directory structure
|
||||
// TODO(jiyong): copy parcelable declarations only
|
||||
sh.printfln("find %s -name \"*.aidl\" | tar cf - -T - | (cd %s; tar xf -)",
|
||||
dir.String(), snapshotPath(aidlIncludeDir))
|
||||
}
|
||||
|
||||
copyTarget := snapshotPath(javaStubFilePathFor(m))
|
||||
sh.printfln("mkdir -p %s && cp %s %s",
|
||||
filepath.Dir(copyTarget), headerJars[0].String(), copyTarget)
|
||||
}
|
||||
|
||||
nativeLibInfos := s.nativeMemberInfos(ctx)
|
||||
for _, info := range nativeLibInfos {
|
||||
|
||||
// a function for emitting include dirs
|
||||
printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
|
||||
includeDirs := lib.exportedIncludeDirs
|
||||
includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
|
||||
if len(includeDirs) == 0 {
|
||||
return
|
||||
}
|
||||
for _, dir := range includeDirs {
|
||||
gen := strings.HasPrefix(dir.String(), buildDir)
|
||||
targetDir := nativeIncludeDir
|
||||
if gen {
|
||||
targetDir = nativeGeneratedIncludeDir
|
||||
}
|
||||
if info.hasArchSpecificFlags {
|
||||
targetDir = filepath.Join(lib.archType, targetDir)
|
||||
}
|
||||
targetDir = snapshotPath(targetDir)
|
||||
|
||||
sourceDirRoot := "."
|
||||
sourceDirRel := dir.String()
|
||||
if gen {
|
||||
// ex) out/soong/.intermediate/foo/bar/gen/aidl
|
||||
sourceDirRoot = strings.TrimSuffix(dir.String(), dir.Rel())
|
||||
sourceDirRel = dir.Rel()
|
||||
}
|
||||
// TODO(jiyong) copy headers having other suffixes
|
||||
sh.printfln("(cd %s; find %s -name \"*.h\" | tar cf - -T - ) | (cd %s; tar xf -)",
|
||||
sourceDirRoot, sourceDirRel, targetDir)
|
||||
}
|
||||
}
|
||||
|
||||
if !info.hasArchSpecificFlags {
|
||||
printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
|
||||
}
|
||||
|
||||
// for each architecture
|
||||
for _, av := range info.archVariants {
|
||||
stub := av.outputFile
|
||||
implicits = append(implicits, stub)
|
||||
copiedStub := snapshotPath(nativeStubFilePathFor(av))
|
||||
sh.printfln("cp %s %s", stub.String(), copiedStub)
|
||||
|
||||
if info.hasArchSpecificFlags {
|
||||
printExportedDirCopyCommandsForNativeLibs(av)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bp := s.buildAndroidBp(ctx, version)
|
||||
implicits = append(implicits, bp)
|
||||
sh.printfln("cp %s %s", bp.String(), filepath.Join(snapshotRoot, "Android.bp"))
|
||||
sh.printfln("cp %s %s", bp.String(), snapshotPath("Android.bp"))
|
||||
|
||||
sh.printfln("popd > /dev/null")
|
||||
sh.printfln("rm -- \"$0\"") // self deleting so that stale script is not used
|
||||
|
@ -218,8 +507,8 @@ func (s *sdk) androidMkEntriesForScript() android.AndroidMkEntries {
|
|||
fmt.Fprintln(w, "$(LOCAL_BUILT_MODULE): $(LOCAL_ADDITIONAL_DEPENDENCIES)")
|
||||
fmt.Fprintln(w, " touch $@")
|
||||
fmt.Fprintln(w, " echo ##################################################")
|
||||
fmt.Fprintln(w, " echo To update current SDK: execute", s.updateScript.String())
|
||||
fmt.Fprintln(w, " echo To freeze current SDK: execute", s.freezeScript.String())
|
||||
fmt.Fprintln(w, " echo To update current SDK: execute", filepath.Join("\\$$ANDROID_BUILD_TOP", s.updateScript.String()))
|
||||
fmt.Fprintln(w, " echo To freeze current SDK: execute", filepath.Join("\\$$ANDROID_BUILD_TOP", s.freezeScript.String()))
|
||||
fmt.Fprintln(w, " echo ##################################################")
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue