diff options
author | Colin Cross <ccross@android.com> | 2017-11-22 16:19:37 -0800 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2017-11-29 05:05:07 +0000 |
commit | 3bc7ffa59b8277b3a36eb9e16192583b3b9a93ea (patch) | |
tree | 1a768f402d17a3181a18177e17935dbd1d3c60b2 /java/app.go | |
parent | 0875c52de753b858b74a9ac285626536bee9cb57 (diff) | |
download | android_build_soong-3bc7ffa59b8277b3a36eb9e16192583b3b9a93ea.tar.gz android_build_soong-3bc7ffa59b8277b3a36eb9e16192583b3b9a93ea.tar.bz2 android_build_soong-3bc7ffa59b8277b3a36eb9e16192583b3b9a93ea.zip |
Replace aapt support with aapt2
Use aapt2 instead of aapt to compile Android app resources.
Also generate all files into srcjars instead of individual
sources.
Test: m checkbuild
Change-Id: I5a67991a0daf0017e8159b46fcff7d5564a91468
Diffstat (limited to 'java/app.go')
-rw-r--r-- | java/app.go | 280 |
1 files changed, 178 insertions, 102 deletions
diff --git a/java/app.go b/java/app.go index 68e4d5cc..fd1fe33f 100644 --- a/java/app.go +++ b/java/app.go @@ -25,6 +25,10 @@ import ( "android/soong/android" ) +func init() { + android.RegisterPreSingletonType("overlay", OverlaySingletonFactory) +} + // AAR prebuilts // AndroidManifest.xml merging // package splits @@ -63,14 +67,14 @@ type AndroidApp struct { appProperties androidAppProperties - aaptJavaFileList android.Path - exportPackage android.Path + aaptSrcJar android.Path + exportPackage android.Path } func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { a.Module.deps(ctx) - if !proptools.Bool(a.properties.No_standard_libs) { + if !Bool(a.properties.No_framework_libs) && !Bool(a.properties.No_standard_libs) { switch String(a.deviceProperties.Sdk_version) { // TODO: Res_sdk_version? case "current", "system_current", "": ctx.AddDependency(ctx.Module(), frameworkResTag, "framework-res") @@ -81,39 +85,30 @@ func (a *AndroidApp) DepsMutator(ctx android.BottomUpMutatorContext) { } func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { - aaptFlags, aaptDeps, hasResources := a.aaptFlags(ctx) - - if hasResources { - // First generate R.java so we can build the .class files - aaptRJavaFlags := append([]string(nil), aaptFlags...) - - publicResourcesFile, proguardOptionsFile, aaptJavaFileList := - CreateResourceJavaFiles(ctx, aaptRJavaFlags, aaptDeps) - a.aaptJavaFileList = aaptJavaFileList - // TODO(ccross): export aapt generated java files as a src jar - - if Bool(a.appProperties.Export_package_resources) { - aaptPackageFlags := append([]string(nil), aaptFlags...) - var hasProduct bool - for _, f := range aaptPackageFlags { - if strings.HasPrefix(f, "--product") { - hasProduct = true - break - } - } + linkFlags, linkDeps, resDirs, overlayDirs := a.aapt2Flags(ctx) - if !hasProduct { - aaptPackageFlags = append(aaptPackageFlags, - "--product "+ctx.AConfig().ProductAAPTCharacteristics()) - } - a.exportPackage = CreateExportPackage(ctx, aaptPackageFlags, aaptDeps) - ctx.CheckbuildFile(a.exportPackage) - } - ctx.CheckbuildFile(publicResourcesFile) - ctx.CheckbuildFile(proguardOptionsFile) - ctx.CheckbuildFile(aaptJavaFileList) + packageRes := android.PathForModuleOut(ctx, "package-res.apk") + srcJar := android.PathForModuleGen(ctx, "R.jar") + proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") + + 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()...) } + aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, + linkFlags, linkDeps, compiledRes, compiledOverlay) + + a.exportPackage = packageRes + a.aaptSrcJar = srcJar + + ctx.CheckbuildFile(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 @@ -121,26 +116,8 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { // a.properties.Proguard.Enabled = true //} - if String(a.appProperties.Instrumentation_for) == "" { - a.properties.Instrument = true - } - a.Module.compile(ctx) - aaptPackageFlags := append([]string(nil), aaptFlags...) - var hasProduct bool - for _, f := range aaptPackageFlags { - if strings.HasPrefix(f, "--product") { - hasProduct = true - break - } - } - - if !hasProduct { - aaptPackageFlags = append(aaptPackageFlags, - "--product "+ctx.AConfig().ProductAAPTCharacteristics()) - } - certificate := String(a.appProperties.Certificate) if certificate == "" { certificate = ctx.AConfig().DefaultAppCertificate(ctx).String() @@ -155,7 +132,12 @@ func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) { certificates = append(certificates, filepath.Join(android.PathForSource(ctx).String(), c)) } - a.outputFile = CreateAppPackage(ctx, aaptPackageFlags, a.outputFile, certificates) + packageFile := android.PathForModuleOut(ctx, "package.apk") + + CreateAppPackage(ctx, packageFile, a.exportPackage, a.outputFile, certificates) + + a.outputFile = packageFile + ctx.InstallFile(android.PathForModuleInstall(ctx, "app"), ctx.ModuleName()+".apk", a.outputFile) } @@ -171,57 +153,55 @@ var aaptIgnoreFilenames = []string{ "*~", } -func (a *AndroidApp) aaptFlags(ctx android.ModuleContext) ([]string, android.Paths, bool) { - aaptFlags := a.appProperties.Aaptflags +type globbedResourceDir struct { + dir android.Path + files android.Paths +} + +func (a *AndroidApp) aapt2Flags(ctx android.ModuleContext) (flags []string, deps android.Paths, + resDirs, overlayDirs []globbedResourceDir) { + hasVersionCode := false hasVersionName := false - for _, f := range aaptFlags { + hasProduct := false + for _, f := range a.appProperties.Aaptflags { if strings.HasPrefix(f, "--version-code") { hasVersionCode = true } else if strings.HasPrefix(f, "--version-name") { hasVersionName = true + } else if strings.HasPrefix(f, "--product") { + hasProduct = true } } - if true /* is not a test */ { - aaptFlags = append(aaptFlags, "-z") - } + var linkFlags []string + + // Flags specified in Android.bp + linkFlags = append(linkFlags, a.appProperties.Aaptflags...) + linkFlags = append(linkFlags, "--no-static-lib-packages") + + // Find implicit or explicit asset and resource dirs assetDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Asset_dirs, "assets") resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.appProperties.Resource_dirs, "res") - var overlayResourceDirs android.Paths - // For every resource directory, check if there is an overlay directory with the same path. - // If found, it will be prepended to the list of resource directories. - for _, overlayDir := range ctx.AConfig().ResourceOverlays() { - for _, resourceDir := range resourceDirs { - overlay := overlayDir.OverlayPath(ctx, resourceDir) - if overlay.Valid() { - overlayResourceDirs = append(overlayResourceDirs, overlay.Path()) - } - } - } + var linkDeps android.Paths - if len(overlayResourceDirs) > 0 { - resourceDirs = append(overlayResourceDirs, resourceDirs...) + // Glob directories into lists of paths + for _, dir := range resourceDirs { + resDirs = append(resDirs, globbedResourceDir{ + dir: dir, + files: resourceGlob(ctx, dir), + }) + overlayDirs = append(overlayDirs, overlayResourceGlob(ctx, dir)...) } - // aapt needs to rerun if any files are added or modified in the assets or resource directories, - // use glob to create a filelist. - var aaptDeps android.Paths - var hasResources bool - for _, d := range resourceDirs { - newDeps := ctx.Glob(filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames) - aaptDeps = append(aaptDeps, newDeps...) - if len(newDeps) > 0 { - hasResources = true - } - } - for _, d := range assetDirs { - newDeps := ctx.Glob(filepath.Join(d.String(), "**/*"), aaptIgnoreFilenames) - aaptDeps = append(aaptDeps, newDeps...) + var assetFiles android.Paths + for _, dir := range assetDirs { + assetFiles = append(assetFiles, resourceGlob(ctx, dir)...) } + // App manifest file var manifestFile string if a.properties.Manifest == nil { manifestFile = "AndroidManifest.xml" @@ -230,50 +210,73 @@ func (a *AndroidApp) aaptFlags(ctx android.ModuleContext) ([]string, android.Pat } manifestPath := android.PathForModuleSrc(ctx, manifestFile) - aaptDeps = append(aaptDeps, manifestPath) + linkFlags = append(linkFlags, "--manifest "+manifestPath.String()) + linkDeps = append(linkDeps, manifestPath) - aaptFlags = append(aaptFlags, "-M "+manifestPath.String()) - aaptFlags = append(aaptFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) - aaptFlags = append(aaptFlags, android.JoinWithPrefix(resourceDirs.Strings(), "-S ")) + linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) + linkDeps = append(linkDeps, assetFiles...) + // 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} } } for _, dep := range depFiles { - aaptFlags = append(aaptFlags, "-I "+dep.String()) + linkFlags = append(linkFlags, "-I "+dep.String()) } - aaptDeps = append(aaptDeps, depFiles...) + linkDeps = append(linkDeps, depFiles...) }) + // SDK version flags sdkVersion := String(a.deviceProperties.Sdk_version) - if sdkVersion == "" { - sdkVersion = ctx.AConfig().PlatformSdkVersion() + switch sdkVersion { + case "", "current", "system_current", "test_current": + sdkVersion = ctx.AConfig().AppsDefaultVersionName() } - aaptFlags = append(aaptFlags, "--min-sdk-version "+sdkVersion) - aaptFlags = append(aaptFlags, "--target-sdk-version "+sdkVersion) + linkFlags = append(linkFlags, "--min-sdk-version "+sdkVersion) + linkFlags = append(linkFlags, "--target-sdk-version "+sdkVersion) + // Product characteristics + if !hasProduct && len(ctx.AConfig().ProductAAPTCharacteristics()) > 0 { + linkFlags = append(linkFlags, "--product", ctx.AConfig().ProductAAPTCharacteristics()) + } + + // Product AAPT config + for _, aaptConfig := range ctx.AConfig().ProductAAPTConfig() { + linkFlags = append(linkFlags, "-c", aaptConfig) + } + + // Product AAPT preferred config + if len(ctx.AConfig().ProductAAPTPreferredConfig()) > 0 { + linkFlags = append(linkFlags, "--preferred-density", ctx.AConfig().ProductAAPTPreferredConfig()) + } + + // Version code if !hasVersionCode { - aaptFlags = append(aaptFlags, "--version-code "+ctx.AConfig().PlatformSdkVersion()) + linkFlags = append(linkFlags, "--version-code", ctx.AConfig().PlatformSdkVersion()) } if !hasVersionName { - aaptFlags = append(aaptFlags, - "--version-name "+ctx.AConfig().PlatformVersion()+"-"+ctx.AConfig().BuildNumber()) + versionName := proptools.NinjaEscape([]string{ctx.AConfig().AppsDefaultVersionName()})[0] + linkFlags = append(linkFlags, "--version-name ", versionName) + } + + if String(a.appProperties.Instrumentation_for) != "" { + linkFlags = append(linkFlags, + "--rename-instrumentation-target-package", + String(a.appProperties.Instrumentation_for)) } // TODO: LOCAL_PACKAGE_OVERRIDES // $(addprefix --rename-manifest-package , $(PRIVATE_MANIFEST_PACKAGE_NAME)) \ - // TODO: LOCAL_INSTRUMENTATION_FOR - // $(addprefix --rename-instrumentation-target-package , $(PRIVATE_MANIFEST_INSTRUMENTATION_FOR)) - - return aaptFlags, aaptDeps, hasResources + return linkFlags, linkDeps, resDirs, overlayDirs } func AndroidAppFactory() android.Module { @@ -287,3 +290,76 @@ func AndroidAppFactory() android.Module { android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) return module } + +func resourceGlob(ctx android.ModuleContext, dir android.Path) android.Paths { + var ret android.Paths + files := ctx.Glob(filepath.Join(dir.String(), "**/*"), aaptIgnoreFilenames) + for _, f := range files { + if isDir, err := ctx.Fs().IsDir(f.String()); err != nil { + ctx.ModuleErrorf("error in IsDir(%s): %s", f.String(), err.Error()) + return nil + } else if !isDir { + ret = append(ret, f) + } + } + return ret +} + +type overlayGlobResult struct { + dir string + paths android.DirectorySortedPaths +} + +const overlayDataKey = "overlayDataKey" + +func overlayResourceGlob(ctx android.ModuleContext, dir android.Path) []globbedResourceDir { + overlayData := ctx.AConfig().Get(overlayDataKey).([]overlayGlobResult) + + var ret []globbedResourceDir + + for _, data := range overlayData { + files := data.paths.PathsInDirectory(filepath.Join(data.dir, dir.String())) + if len(files) > 0 { + ret = append(ret, globbedResourceDir{ + dir: android.PathForSource(ctx, data.dir, dir.String()), + files: files, + }) + } + } + + return ret +} + +func OverlaySingletonFactory() android.Singleton { + return overlaySingleton{} +} + +type overlaySingleton struct{} + +func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) { + var overlayData []overlayGlobResult + for _, overlay := range ctx.Config().(android.Config).ResourceOverlays() { + var result overlayGlobResult + result.dir = overlay + files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), aaptIgnoreFilenames) + if err != nil { + ctx.Errorf("failed to glob resource dir %q: %s", overlay, err.Error()) + continue + } + var paths android.Paths + for _, f := range files { + if isDir, err := ctx.Fs().IsDir(f); err != nil { + ctx.Errorf("error in IsDir(%s): %s", f, err.Error()) + return + } else if !isDir { + paths = append(paths, android.PathForSource(ctx, f)) + } + } + result.paths = android.PathsToDirectorySortedPaths(paths) + overlayData = append(overlayData, result) + } + + ctx.Config().(android.Config).Once(overlayDataKey, func() interface{} { + return overlayData + }) +} |