diff options
Diffstat (limited to 'java/aar.go')
| -rw-r--r-- | java/aar.go | 273 |
1 files changed, 197 insertions, 76 deletions
diff --git a/java/aar.go b/java/aar.go index 6273a9b50..8dd752f12 100644 --- a/java/aar.go +++ b/java/aar.go @@ -15,11 +15,12 @@ package java import ( - "android/soong/android" "fmt" "path/filepath" "strings" + "android/soong/android" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -30,12 +31,17 @@ type AndroidLibraryDependency interface { ExportedProguardFlagFiles() android.Paths ExportedRRODirs() []rroDir ExportedStaticPackages() android.Paths - ExportedManifest() android.Path + ExportedManifests() android.Paths + ExportedAssets() android.OptionalPath } func init() { - android.RegisterModuleType("android_library_import", AARImportFactory) - android.RegisterModuleType("android_library", AndroidLibraryFactory) + RegisterAARBuildComponents(android.InitRegistrationContext) +} + +func RegisterAARBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("android_library_import", AARImportFactory) + ctx.RegisterModuleType("android_library", AndroidLibraryFactory) } // @@ -69,21 +75,34 @@ type aaptProperties struct { // path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml". Manifest *string `android:"path"` + + // paths to additional manifest files to merge with main manifest. + Additional_manifests []string `android:"path"` + + // do not include AndroidManifest from dependent libraries + Dont_merge_manifests *bool } type aapt struct { - aaptSrcJar android.Path - exportPackage android.Path - manifestPath android.Path - proguardOptionsFile android.Path - rroDirs []rroDir - rTxt android.Path - extraAaptPackagesFile android.Path - noticeFile android.OptionalPath - isLibrary bool - uncompressedJNI bool - useEmbeddedDex bool - usesNonSdkApis bool + aaptSrcJar android.Path + exportPackage android.Path + manifestPath android.Path + transitiveManifestPaths android.Paths + proguardOptionsFile android.Path + rroDirs []rroDir + rTxt android.Path + extraAaptPackagesFile android.Path + mergedManifestFile android.Path + noticeFile android.OptionalPath + assetPackage android.OptionalPath + isLibrary bool + useEmbeddedNativeLibs bool + useEmbeddedDex bool + usesNonSdkApis bool + sdkLibraries []string + hasNoCode bool + LoggingParent string + resourceFiles android.Paths splitNames []string splits []split @@ -105,24 +124,20 @@ func (a *aapt) ExportedRRODirs() []rroDir { return a.rroDirs } -func (a *aapt) ExportedManifest() android.Path { - return a.manifestPath +func (a *aapt) ExportedManifests() android.Paths { + return a.transitiveManifestPaths } -func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (flags []string, - deps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) { +func (a *aapt) ExportedAssets() android.OptionalPath { + return a.assetPackage +} - 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 - } - } +func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, + manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths, + resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) { - var linkFlags []string + hasVersionCode := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-code") + hasVersionName := android.PrefixInList(a.aaptProperties.Aaptflags, "--version-name") // Flags specified in Android.bp linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...) @@ -134,8 +149,6 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, mani resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res") resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips) - var linkDeps android.Paths - // Glob directories into lists of paths for _, dir := range resourceDirs { resDirs = append(resDirs, globbedResourceDir{ @@ -165,7 +178,10 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, mani linkDeps = append(linkDeps, assetFiles...) // SDK version flags - minSdkVersion := sdkVersionOrDefault(ctx, sdkContext.minSdkVersion()) + minSdkVersion, err := sdkContext.minSdkVersion().effectiveVersionString(ctx) + if err != nil { + ctx.ModuleErrorf("invalid minSdkVersion: %s", err) + } linkFlags = append(linkFlags, "--min-sdk-version "+minSdkVersion) linkFlags = append(linkFlags, "--target-sdk-version "+minSdkVersion) @@ -189,27 +205,58 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, mani linkFlags = append(linkFlags, "--version-name ", versionName) } - return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips + linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"}) + + // Always set --pseudo-localize, it will be stripped out later for release + // builds that don't want it. + compileFlags = append(compileFlags, "--pseudo-localize") + + return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips } -func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) { - sdkDep := decodeSdkDep(ctx, sdkContext) +func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) { if sdkDep.frameworkResModule != "" { ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule) } } +var extractAssetsRule = pctx.AndroidStaticRule("extractAssets", + blueprint.RuleParams{ + Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} "assets/**/*"`, + CommandDeps: []string{"${config.Zip2ZipCmd}"}, + }) + func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, extraLinkFlags ...string) { - transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags := aaptLibs(ctx, sdkContext) + + transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assetPackages, libDeps, libFlags, sdkLibraries := + aaptLibs(ctx, sdkContext) // App manifest file manifestFile := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml") manifestSrcPath := android.PathForModuleSrc(ctx, manifestFile) - manifestPath := manifestMerger(ctx, manifestSrcPath, sdkContext, staticLibManifests, a.isLibrary, - a.uncompressedJNI, a.useEmbeddedDex, a.usesNonSdkApis) + manifestPath := manifestFixer(ctx, manifestSrcPath, sdkContext, sdkLibraries, + a.isLibrary, a.useEmbeddedNativeLibs, a.usesNonSdkApis, a.useEmbeddedDex, a.hasNoCode, + a.LoggingParent) + + // Add additional manifest files to transitive manifests. + additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests) + a.transitiveManifestPaths = append(android.Paths{manifestPath}, additionalManifests...) + a.transitiveManifestPaths = append(a.transitiveManifestPaths, transitiveStaticLibManifests...) + + if len(a.transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) { + a.mergedManifestFile = manifestMerger(ctx, a.transitiveManifestPaths[0], a.transitiveManifestPaths[1:], a.isLibrary) + if !a.isLibrary { + // Only use the merged manifest for applications. For libraries, the transitive closure of manifests + // will be propagated to the final application and merged there. The merged manifest for libraries is + // only passed to Make, which can't handle transitive dependencies. + manifestPath = a.mergedManifestFile + } + } else { + a.mergedManifestFile = manifestPath + } - linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath) + compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath) rroDirs = append(rroDirs, staticRRODirs...) linkFlags = append(linkFlags, libFlags...) @@ -220,7 +267,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } packageRes := android.PathForModuleOut(ctx, "package-res.apk") - srcJar := android.PathForModuleGen(ctx, "R.jar") + // the subdir "android" is required to be filtered by package names + srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar") proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") rTxt := android.PathForModuleOut(ctx, "R.txt") // This file isn't used by Soong, but is generated for exporting @@ -228,12 +276,13 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex var compiledResDirs []android.Paths for _, dir := range resDirs { - compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files).Paths()) + a.resourceFiles = append(a.resourceFiles, dir.files...) + compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()) } for i, zip := range resZips { flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i)) - aapt2CompileZip(ctx, flata, zip) + aapt2CompileZip(ctx, flata, zip, "", compileFlags) compiledResDirs = append(compiledResDirs, android.Paths{flata}) } @@ -262,7 +311,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } for _, dir := range overlayDirs { - compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...) + compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...) } var splitPackages android.WritablePaths @@ -281,7 +330,20 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, - linkFlags, linkDeps, compiledRes, compiledOverlay, splitPackages) + linkFlags, linkDeps, compiledRes, compiledOverlay, assetPackages, splitPackages) + + // Extract assets from the resource package output so that they can be used later in aapt2link + // for modules that depend on this one. + if android.PrefixInList(linkFlags, "-A ") || len(assetPackages) > 0 { + assets := android.PathForModuleOut(ctx, "assets.zip") + ctx.Build(pctx, android.BuildParams{ + Rule: extractAssetsRule, + Input: packageRes, + Output: assets, + Description: "extract assets from built resource file", + }) + a.assetPackage = android.OptionalPathForPath(assets) + } a.aaptSrcJar = srcJar a.exportPackage = packageRes @@ -294,8 +356,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkContext sdkContext, ex } // aaptLibs collects libraries from dependencies and sdk_version and converts them into paths -func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, staticLibManifests android.Paths, - staticRRODirs []rroDir, deps android.Paths, flags []string) { +func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStaticLibs, transitiveStaticLibManifests android.Paths, + staticRRODirs []rroDir, assets, deps android.Paths, flags []string, sdkLibraries []string) { var sharedLibs android.Paths @@ -314,7 +376,19 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati switch ctx.OtherModuleDependencyTag(module) { case instrumentationForTag: // Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2. - case libTag, frameworkResTag: + case libTag: + if exportPackage != nil { + sharedLibs = append(sharedLibs, exportPackage) + } + + // If the module is (or possibly could be) a component of a java_sdk_library + // (including the java_sdk_library) itself then append any implicit sdk library + // names to the list of sdk libraries to be added to the manifest. + if component, ok := module.(SdkLibraryComponentDependency); ok { + sdkLibraries = append(sdkLibraries, component.OptionalImplicitSdkLibrary()...) + } + + case frameworkResTag: if exportPackage != nil { sharedLibs = append(sharedLibs, exportPackage) } @@ -322,7 +396,11 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati if exportPackage != nil { transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) - staticLibManifests = append(staticLibManifests, aarDep.ExportedManifest()) + transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...) + sdkLibraries = append(sdkLibraries, aarDep.ExportedSdkLibs()...) + if aarDep.ExportedAssets().Valid() { + assets = append(assets, aarDep.ExportedAssets().Path()) + } outer: for _, d := range aarDep.ExportedRRODirs() { @@ -349,8 +427,10 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati } transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs) + transitiveStaticLibManifests = android.FirstUniquePaths(transitiveStaticLibManifests) + sdkLibraries = android.FirstUniqueStrings(sdkLibraries) - return transitiveStaticLibs, staticLibManifests, staticRRODirs, deps, flags + return transitiveStaticLibs, transitiveStaticLibManifests, staticRRODirs, assets, deps, flags, sdkLibraries } type AndroidLibrary struct { @@ -377,13 +457,15 @@ 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, sdkContext(a)) + sdkDep := decodeSdkDep(ctx, sdkContext(a)) + if sdkDep.hasFrameworkLibs() { + a.aapt.deps(ctx, sdkDep) } } func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.aapt.isLibrary = true + a.aapt.sdkLibraries = a.exportedSdkLibs a.aapt.buildActions(ctx, sdkContext(a)) ctx.CheckbuildFile(a.proguardOptionsFile) @@ -393,6 +475,10 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) // apps manifests are handled by aapt, don't let Module see them a.properties.Manifest = nil + a.linter.mergedManifest = a.aapt.mergedManifestFile + a.linter.manifest = a.aapt.manifestPath + a.linter.resources = a.aapt.resourceFiles + a.Module.extraProguardFlagFiles = append(a.Module.extraProguardFlagFiles, a.proguardOptionsFile) @@ -426,16 +512,15 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) func AndroidLibraryFactory() android.Module { module := &AndroidLibrary{} + module.Module.addHostAndDeviceProperties() module.AddProperties( - &module.Module.properties, - &module.Module.deviceProperties, - &module.Module.dexpreoptProperties, - &module.Module.protoProperties, &module.aaptProperties, &module.androidLibraryProperties) module.androidLibraryProperties.BuildAAR = true + module.Module.linter.library = true + android.InitApexModule(module) InitJavaModule(module, android.DeviceSupported) return module } @@ -460,8 +545,12 @@ type AARImportProperties struct { type AARImport struct { android.ModuleBase android.DefaultableModuleBase + android.ApexModuleBase prebuilt android.Prebuilt + // Functionality common to Module and Import. + embeddableInModuleAndImport + properties AARImportProperties classpathFile android.WritablePath @@ -473,21 +562,29 @@ type AARImport struct { exportedStaticPackages android.Paths } -func (a *AARImport) sdkVersion() string { - return String(a.properties.Sdk_version) +func (a *AARImport) sdkVersion() sdkSpec { + return sdkSpecFrom(String(a.properties.Sdk_version)) } -func (a *AARImport) minSdkVersion() string { +func (a *AARImport) systemModules() string { + return "" +} + +func (a *AARImport) minSdkVersion() sdkSpec { if a.properties.Min_sdk_version != nil { - return *a.properties.Min_sdk_version + return sdkSpecFrom(*a.properties.Min_sdk_version) } return a.sdkVersion() } -func (a *AARImport) targetSdkVersion() string { +func (a *AARImport) targetSdkVersion() sdkSpec { return a.sdkVersion() } +func (a *AARImport) javaVersion() string { + return "" +} + var _ AndroidLibraryDependency = (*AARImport)(nil) func (a *AARImport) ExportPackage() android.Path { @@ -506,8 +603,13 @@ func (a *AARImport) ExportedStaticPackages() android.Paths { return a.exportedStaticPackages } -func (a *AARImport) ExportedManifest() android.Path { - return a.manifest +func (a *AARImport) ExportedManifests() android.Paths { + return android.Paths{a.manifest} +} + +// TODO(jungjw): Decide whether we want to implement this. +func (a *AARImport) ExportedAssets() android.OptionalPath { + return android.OptionalPath{} } func (a *AARImport) Prebuilt() *android.Prebuilt { @@ -518,6 +620,10 @@ func (a *AARImport) Name() string { return a.prebuilt.Name(a.ModuleBase.Name()) } +func (a *AARImport) JacocoReportClassesFile() android.Path { + return nil +} + func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { if !ctx.Config().UnbundledBuildUsePrebuiltSdks() { sdkDep := decodeSdkDep(ctx, sdkContext(a)) @@ -531,13 +637,13 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { } // Unzip an AAR into its constituent files and directories. Any files in Outputs that don't exist in the AAR will be -// touched to create an empty file, and any directories in $expectedDirs will be created. +// touched to create an empty file. The res directory is not extracted, as it will be extracted in its own rule. var unzipAAR = pctx.AndroidStaticRule("unzipAAR", blueprint.RuleParams{ - Command: `rm -rf $outDir && mkdir -p $outDir $expectedDirs && ` + - `unzip -qo -d $outDir $in && touch $out`, + Command: `rm -rf $outDir && mkdir -p $outDir && ` + + `unzip -qoDD -d $outDir $in && rm -rf $outDir/res && touch $out`, }, - "expectedDirs", "outDir") + "outDir") func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { if len(a.properties.Aars) != 1 { @@ -555,7 +661,6 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } extractedAARDir := android.PathForModuleOut(ctx, "aar") - extractedResDir := extractedAARDir.Join(ctx, "res") a.classpathFile = extractedAARDir.Join(ctx, "classes.jar") a.proguardFlags = extractedAARDir.Join(ctx, "proguard.txt") a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml") @@ -566,19 +671,20 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest}, Description: "unzip AAR", Args: map[string]string{ - "expectedDirs": extractedResDir.String(), - "outDir": extractedAARDir.String(), + "outDir": extractedAARDir.String(), }, }) + // Always set --pseudo-localize, it will be stripped out later for release + // builds that don't want it. + compileFlags := []string{"--pseudo-localize"} compiledResDir := android.PathForModuleOut(ctx, "flat-res") - aaptCompileDeps := android.Paths{a.classpathFile} - aaptCompileDirs := android.Paths{extractedResDir} flata := compiledResDir.Join(ctx, "gen_res.flata") - aapt2CompileDirs(ctx, flata, aaptCompileDirs, aaptCompileDeps) + aapt2CompileZip(ctx, flata, aar, "res", compileFlags) a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk") - srcJar := android.PathForModuleGen(ctx, "R.jar") + // the subdir "android" is required to be filtered by package names + srcJar := android.PathForModuleGen(ctx, "android", "R.srcjar") proguardOptionsFile := android.PathForModuleGen(ctx, "proguard.options") rTxt := android.PathForModuleOut(ctx, "R.txt") a.extraAaptPackagesFile = android.PathForModuleOut(ctx, "extra_packages") @@ -594,10 +700,12 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+a.manifest.String()) linkDeps = append(linkDeps, a.manifest) - transitiveStaticLibs, staticLibManifests, staticRRODirs, libDeps, libFlags := aaptLibs(ctx, sdkContext(a)) + transitiveStaticLibs, staticLibManifests, staticRRODirs, transitiveAssets, libDeps, libFlags, sdkLibraries := + aaptLibs(ctx, sdkContext(a)) _ = staticLibManifests _ = staticRRODirs + _ = sdkLibraries linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) @@ -605,7 +713,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, - linkFlags, linkDeps, nil, overlayRes, nil) + linkFlags, linkDeps, nil, overlayRes, transitiveAssets, nil) } var _ Dependency = (*AARImport)(nil) @@ -638,6 +746,18 @@ func (a *AARImport) ExportedSdkLibs() []string { return nil } +func (d *AARImport) ExportedPlugins() (android.Paths, []string) { + return nil, nil +} + +func (a *AARImport) SrcJarArgs() ([]string, android.Paths) { + return nil, nil +} + +func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { + return a.depIsInSameApex(ctx, dep) +} + var _ android.PrebuiltInterface = (*Import)(nil) // android_library_import imports an `.aar` file into the build graph as if it was built with android_library. @@ -650,6 +770,7 @@ func AARImportFactory() android.Module { module.AddProperties(&module.properties) android.InitPrebuiltModule(module, &module.properties.Aars) + android.InitApexModule(module) InitJavaModule(module, android.DeviceSupported) return module } |