aboutsummaryrefslogtreecommitdiffstats
path: root/java/aar.go
diff options
context:
space:
mode:
Diffstat (limited to 'java/aar.go')
-rw-r--r--java/aar.go379
1 files changed, 348 insertions, 31 deletions
diff --git a/java/aar.go b/java/aar.go
index 0df3632b..9e5cddb6 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -16,21 +16,332 @@ package java
import (
"android/soong/android"
+ "strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
-//
-// AAR (android library) prebuilts
-//
+type AndroidLibraryDependency interface {
+ Dependency
+ ExportPackage() android.Path
+ ExportedProguardFlagFiles() android.Paths
+ ExportedStaticPackages() android.Paths
+}
+
func init() {
android.RegisterModuleType("android_library_import", AARImportFactory)
+ android.RegisterModuleType("android_library", AndroidLibraryFactory)
+}
+
+//
+// AAR (android library)
+//
+
+type androidLibraryProperties struct {
+ BuildAAR bool `blueprint:"mutated"`
+}
+
+type aaptProperties struct {
+ // flags passed to aapt when creating the apk
+ Aaptflags []string
+
+ // list of directories relative to the Blueprints file containing assets.
+ // Defaults to "assets"
+ Asset_dirs []string
+
+ // list of directories relative to the Blueprints file containing
+ // Android resources
+ Resource_dirs []string
+
+ // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
+ Manifest *string
+}
+
+type aapt struct {
+ aaptSrcJar android.Path
+ exportPackage android.Path
+ manifestPath android.Path
+ proguardOptionsFile android.Path
+ rroDirs android.Paths
+ rTxt android.Path
+ extraAaptPackagesFile android.Path
+
+ aaptProperties aaptProperties
+}
+
+func (a *aapt) ExportPackage() android.Path {
+ return a.exportPackage
+}
+
+func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags []string, deps android.Paths,
+ resDirs, overlayDirs []globbedResourceDir, overlayFiles, rroDirs android.Paths, manifestPath android.Path) {
+
+ hasVersionCode := false
+ hasVersionName := false
+ for _, f := range a.aaptProperties.Aaptflags {
+ if strings.HasPrefix(f, "--version-code") {
+ hasVersionCode = true
+ } else if strings.HasPrefix(f, "--version-name") {
+ hasVersionName = true
+ }
+ }
+
+ var linkFlags []string
+
+ // Flags specified in Android.bp
+ linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
+
+ linkFlags = append(linkFlags, "--no-static-lib-packages")
+
+ // Find implicit or explicit asset and resource dirs
+ assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Asset_dirs, "assets")
+ resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
+
+ var linkDeps android.Paths
+
+ // Glob directories into lists of paths
+ for _, dir := range resourceDirs {
+ resDirs = append(resDirs, globbedResourceDir{
+ dir: dir,
+ files: androidResourceGlob(ctx, dir),
+ })
+ resOverlayDirs, resRRODirs := overlayResourceGlob(ctx, dir)
+ overlayDirs = append(overlayDirs, resOverlayDirs...)
+ rroDirs = append(rroDirs, resRRODirs...)
+ }
+
+ var assetFiles android.Paths
+ for _, dir := range assetDirs {
+ assetFiles = append(assetFiles, androidResourceGlob(ctx, dir)...)
+ }
+
+ // App manifest file
+ manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
+ manifestPath = android.PathForModuleSrc(ctx, manifestFile)
+ linkFlags = append(linkFlags, "--manifest "+manifestPath.String())
+ linkDeps = append(linkDeps, manifestPath)
+
+ linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A "))
+ linkDeps = append(linkDeps, assetFiles...)
+
+ transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkVersion)
+
+ overlayFiles = append(overlayFiles, transitiveStaticLibs...)
+ linkDeps = append(linkDeps, libDeps...)
+ linkFlags = append(linkFlags, libFlags...)
+
+ // SDK version flags
+ switch sdkVersion {
+ case "", "current", "system_current", "test_current":
+ sdkVersion = proptools.NinjaEscape([]string{ctx.Config().DefaultAppTargetSdk()})[0]
+ }
+
+ linkFlags = append(linkFlags, "--min-sdk-version "+sdkVersion)
+ linkFlags = append(linkFlags, "--target-sdk-version "+sdkVersion)
+
+ // Version code
+ if !hasVersionCode {
+ linkFlags = append(linkFlags, "--version-code", ctx.Config().PlatformSdkVersion())
+ }
+
+ if !hasVersionName {
+ var versionName string
+ if ctx.ModuleName() == "framework-res" {
+ // Some builds set AppsDefaultVersionName() to include the build number ("O-123456"). aapt2 copies the
+ // version name of framework-res into app manifests as compileSdkVersionCodename, which confuses things
+ // if it contains the build number. Use the DefaultAppTargetSdk instead.
+ versionName = ctx.Config().DefaultAppTargetSdk()
+ } else {
+ versionName = ctx.Config().AppsDefaultVersionName()
+ }
+ versionName = proptools.NinjaEscape([]string{versionName})[0]
+ linkFlags = append(linkFlags, "--version-name ", versionName)
+ }
+
+ return linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath
+}
+
+func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkVersion string) {
+ if !ctx.Config().UnbundledBuild() {
+ sdkDep := decodeSdkDep(ctx, sdkVersion)
+ if sdkDep.frameworkResModule != "" {
+ ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule)
+ }
+ }
}
+func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraLinkFlags ...string) {
+ linkFlags, linkDeps, resDirs, overlayDirs, overlayFiles, rroDirs, manifestPath := a.aapt2Flags(ctx, sdkVersion)
+
+ linkFlags = append(linkFlags, extraLinkFlags...)
+
+ packageRes := android.PathForModuleOut(ctx, "package-res.apk")
+ srcJar := android.PathForModuleGen(ctx, "R.jar")
+ proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
+ rTxt := android.PathForModuleOut(ctx, "R.txt")
+ // This file isn't used by Soong, but is generated for exporting
+ extraPackages := android.PathForModuleOut(ctx, "extra_packages")
+
+ var compiledRes, compiledOverlay android.Paths
+ for _, dir := range resDirs {
+ compiledRes = append(compiledRes, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
+ }
+ for _, dir := range overlayDirs {
+ compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
+ }
+
+ compiledOverlay = append(compiledOverlay, overlayFiles...)
+
+ aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages,
+ linkFlags, linkDeps, compiledRes, compiledOverlay)
+
+ a.aaptSrcJar = srcJar
+ a.exportPackage = packageRes
+ a.manifestPath = manifestPath
+ a.proguardOptionsFile = proguardOptionsFile
+ a.rroDirs = rroDirs
+ a.extraAaptPackagesFile = extraPackages
+ a.rTxt = rTxt
+}
+
+// aaptLibs collects libraries from dependencies and sdk_version and converts them into paths
+func aaptLibs(ctx android.ModuleContext, sdkVersion string) (transitiveStaticLibs, deps android.Paths,
+ flags []string) {
+
+ var sharedLibs android.Paths
+
+ sdkDep := decodeSdkDep(ctx, sdkVersion)
+ if sdkDep.useFiles {
+ sharedLibs = append(sharedLibs, sdkDep.jar)
+ }
+
+ ctx.VisitDirectDeps(func(module android.Module) {
+ var exportPackage android.Path
+ aarDep, _ := module.(AndroidLibraryDependency)
+ if aarDep != nil {
+ exportPackage = aarDep.ExportPackage()
+ }
+
+ switch ctx.OtherModuleDependencyTag(module) {
+ case libTag, frameworkResTag:
+ if exportPackage != nil {
+ sharedLibs = append(sharedLibs, exportPackage)
+ }
+ case staticLibTag:
+ if exportPackage != nil {
+ transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
+ transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
+ }
+ }
+ })
+
+ deps = append(deps, sharedLibs...)
+ deps = append(deps, transitiveStaticLibs...)
+
+ if len(transitiveStaticLibs) > 0 {
+ flags = append(flags, "--auto-add-overlay")
+ }
+
+ for _, sharedLib := range sharedLibs {
+ flags = append(flags, "-I "+sharedLib.String())
+ }
+
+ transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs)
+
+ return transitiveStaticLibs, deps, flags
+}
+
+type AndroidLibrary struct {
+ Library
+ aapt
+
+ androidLibraryProperties androidLibraryProperties
+
+ aarFile android.WritablePath
+
+ exportedProguardFlagFiles android.Paths
+ exportedStaticPackages android.Paths
+}
+
+func (a *AndroidLibrary) ExportedProguardFlagFiles() android.Paths {
+ return a.exportedProguardFlagFiles
+}
+
+func (a *AndroidLibrary) ExportedStaticPackages() android.Paths {
+ return a.exportedStaticPackages
+}
+
+var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
+
+func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ a.Module.deps(ctx)
+ if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) {
+ a.aapt.deps(ctx, String(a.deviceProperties.Sdk_version))
+ }
+}
+
+func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ a.aapt.buildActions(ctx, String(a.deviceProperties.Sdk_version), "--static-lib")
+
+ ctx.CheckbuildFile(a.proguardOptionsFile)
+ ctx.CheckbuildFile(a.exportPackage)
+ ctx.CheckbuildFile(a.aaptSrcJar)
+
+ // apps manifests are handled by aapt, don't let Module see them
+ a.properties.Manifest = nil
+
+ a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles,
+ a.proguardOptionsFile)
+
+ a.Module.compile(ctx, a.aaptSrcJar)
+
+ a.aarFile = android.PathForOutput(ctx, ctx.ModuleName()+".aar")
+ var res android.Paths
+ if a.androidLibraryProperties.BuildAAR {
+ BuildAAR(ctx, a.aarFile, a.outputFile, a.manifestPath, a.rTxt, res)
+ ctx.CheckbuildFile(a.aarFile)
+ }
+
+ ctx.VisitDirectDeps(func(m android.Module) {
+ if lib, ok := m.(AndroidLibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag {
+ a.exportedProguardFlagFiles = append(a.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...)
+ a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportPackage())
+ a.exportedStaticPackages = append(a.exportedStaticPackages, lib.ExportedStaticPackages()...)
+ }
+ })
+
+ a.exportedProguardFlagFiles = android.FirstUniquePaths(a.exportedProguardFlagFiles)
+ a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages)
+}
+
+func AndroidLibraryFactory() android.Module {
+ module := &AndroidLibrary{}
+
+ module.AddProperties(
+ &module.Module.properties,
+ &module.Module.deviceProperties,
+ &module.Module.protoProperties,
+ &module.aaptProperties,
+ &module.androidLibraryProperties)
+
+ module.androidLibraryProperties.BuildAAR = true
+
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+//
+// AAR (android library) prebuilts
+//
+
type AARImportProperties struct {
Aars []string
Sdk_version *string
+
+ Static_libs []string
+ Libs []string
}
type AARImport struct {
@@ -39,9 +350,26 @@ type AARImport struct {
properties AARImportProperties
- classpathFile android.WritablePath
- proguardFlags android.WritablePath
- exportPackage android.WritablePath
+ classpathFile android.WritablePath
+ proguardFlags android.WritablePath
+ exportPackage android.WritablePath
+ extraAaptPackagesFile android.WritablePath
+
+ exportedStaticPackages android.Paths
+}
+
+var _ AndroidLibraryDependency = (*AARImport)(nil)
+
+func (a *AARImport) ExportPackage() android.Path {
+ return a.exportPackage
+}
+
+func (a *AARImport) ExportedProguardFlagFiles() android.Paths {
+ return android.Paths{a.proguardFlags}
+}
+
+func (a *AARImport) ExportedStaticPackages() android.Paths {
+ return a.exportedStaticPackages
}
func (a *AARImport) Prebuilt() *android.Prebuilt {
@@ -53,13 +381,15 @@ func (a *AARImport) Name() string {
}
func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) {
- // TODO: this should use decodeSdkDep once that knows about current
if !ctx.Config().UnbundledBuild() {
- switch String(a.properties.Sdk_version) { // TODO: Res_sdk_version?
- case "current", "system_current", "test_current", "":
- ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res")
+ sdkDep := decodeSdkDep(ctx, String(a.properties.Sdk_version))
+ if sdkDep.useModule && sdkDep.frameworkResModule != "" {
+ ctx.AddDependency(ctx.Module(), frameworkResTag, sdkDep.frameworkResModule)
}
}
+
+ ctx.AddDependency(ctx.Module(), libTag, a.properties.Libs...)
+ ctx.AddDependency(ctx.Module(), staticLibTag, a.properties.Static_libs...)
}
// Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be
@@ -105,6 +435,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
srcJar := android.PathForModuleGen(ctx, "R.jar")
proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options")
+ rTxt := android.PathForModuleOut(ctx, "R.txt")
+ a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages")
var linkDeps android.Paths
@@ -117,30 +449,15 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
linkFlags = append(linkFlags, "--manifest "+manifest.String())
linkDeps = append(linkDeps, manifest)
- // Include dirs
- ctx.VisitDirectDeps(func(module android.Module) {
- var depFiles android.Paths
- if javaDep, ok := module.(Dependency); ok {
- // TODO: shared android libraries
- if ctx.OtherModuleName(module) == "framework-res" {
- depFiles = android.Paths{javaDep.(*AndroidApp).exportPackage}
- }
- }
+ transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version))
- for _, dep := range depFiles {
- linkFlags = append(linkFlags, "-I "+dep.String())
- }
- linkDeps = append(linkDeps, depFiles...)
- })
+ linkDeps = append(linkDeps, libDeps...)
+ linkFlags = append(linkFlags, libFlags...)
- sdkDep := decodeSdkDep(ctx, String(a.properties.Sdk_version))
- if sdkDep.useFiles {
- linkFlags = append(linkFlags, "-I "+sdkDep.jar.String())
- linkDeps = append(linkDeps, sdkDep.jar)
- }
+ overlayRes := append(android.Paths{flata}, transitiveStaticLibs...)
- aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile,
- linkFlags, linkDeps, nil, android.Paths{flata})
+ aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile,
+ linkFlags, linkDeps, nil, overlayRes)
}
var _ Dependency = (*AARImport)(nil)