diff --git a/cmd/extract_jar_packages/Android.bp b/cmd/extract_jar_packages/Android.bp new file mode 100644 index 000000000..ea0cbbf8e --- /dev/null +++ b/cmd/extract_jar_packages/Android.bp @@ -0,0 +1,25 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +blueprint_go_binary { + name: "extract_jar_packages", + deps: [ + "android-archive-zip", + "blueprint-pathtools", + ], + srcs: [ + "extract_jar_packages.go", + ], +} + diff --git a/cmd/extract_jar_packages/extract_jar_packages.go b/cmd/extract_jar_packages/extract_jar_packages.go new file mode 100644 index 000000000..fca308ffc --- /dev/null +++ b/cmd/extract_jar_packages/extract_jar_packages.go @@ -0,0 +1,88 @@ +// Copyright 2018 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "archive/zip" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "sort" + "strings" +) + +var ( + outputFile = flag.String("o", "", "output file") + prefix = flag.String("prefix", "", "prefix for each entry in the output file") + inputFile = flag.String("i", "", "input jar or srcjar") +) + +func must(err error) { + if err != nil { + log.Fatal(err) + } +} + +func fileToPackage(file string) string { + dir := filepath.Dir(file) + return strings.Replace(dir, "/", ".", -1) +} + +func main() { + flag.Usage = func() { + fmt.Fprintln(os.Stderr, "usage: extract_jar_packages -i -o [-prefix ]") + flag.PrintDefaults() + } + + flag.Parse() + + if *outputFile == "" || *inputFile == "" { + flag.Usage() + os.Exit(1) + } + + pkgSet := make(map[string]bool) + + reader, err := zip.OpenReader(*inputFile) + if err != nil { + log.Fatal(err) + } + defer reader.Close() + + for _, f := range reader.File { + ext := filepath.Ext(f.Name) + if ext == ".java" || ext == ".class" { + pkgSet[fileToPackage(f.Name)] = true + } + } + + var pkgs []string + for k := range pkgSet { + pkgs = append(pkgs, k) + } + sort.Strings(pkgs) + + var data []byte + for _, pkg := range pkgs { + data = append(data, *prefix...) + data = append(data, pkg...) + data = append(data, "\n"...) + } + + must(ioutil.WriteFile(*outputFile, data, 0666)) +} diff --git a/java/aapt2.go b/java/aapt2.go index 61e9451c4..70c750716 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -113,14 +113,17 @@ var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link", blueprint.RuleParams{ Command: `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` + `--output-text-symbols ${rTxt} $inFlags && ` + - `${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir`, + `${config.SoongZipCmd} -write_if_changed -jar -o $genJar -C $genDir -D $genDir &&` + + `${config.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`, + CommandDeps: []string{ "${config.Aapt2Cmd}", "${config.SoongZipCmd}", + "${config.ExtractJarPackagesCmd}", }, Restat: true, }, - "flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt") + "flags", "inFlags", "proguardOptions", "genDir", "genJar", "rTxt", "extraPackages") var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile", blueprint.RuleParams{ @@ -130,7 +133,7 @@ var fileListToFileRule = pctx.AndroidStaticRule("fileListToFile", }) func aapt2Link(ctx android.ModuleContext, - packageRes, genJar, proguardOptions, rTxt android.WritablePath, + packageRes, genJar, proguardOptions, rTxt, extraPackages android.WritablePath, flags []string, deps android.Paths, compiledRes, compiledOverlay android.Paths) { @@ -172,7 +175,7 @@ func aapt2Link(ctx android.ModuleContext, Description: "aapt2 link", Implicits: deps, Output: packageRes, - ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt}, + ImplicitOutputs: android.WritablePaths{proguardOptions, genJar, rTxt, extraPackages}, Args: map[string]string{ "flags": strings.Join(flags, " "), "inFlags": strings.Join(inFlags, " "), @@ -180,6 +183,7 @@ func aapt2Link(ctx android.ModuleContext, "genDir": genDir.String(), "genJar": genJar.String(), "rTxt": rTxt.String(), + "extraPackages": extraPackages.String(), }, }) } diff --git a/java/aar.go b/java/aar.go index 47676fd9e..9e5cddb63 100644 --- a/java/aar.go +++ b/java/aar.go @@ -26,6 +26,7 @@ type AndroidLibraryDependency interface { Dependency ExportPackage() android.Path ExportedProguardFlagFiles() android.Paths + ExportedStaticPackages() android.Paths } func init() { @@ -58,12 +59,13 @@ type aaptProperties struct { } type aapt struct { - aaptSrcJar android.Path - exportPackage android.Path - manifestPath android.Path - proguardOptionsFile android.Path - rroDirs android.Paths - rTxt android.Path + aaptSrcJar android.Path + exportPackage android.Path + manifestPath android.Path + proguardOptionsFile android.Path + rroDirs android.Paths + rTxt android.Path + extraAaptPackagesFile android.Path aaptProperties aaptProperties } @@ -123,9 +125,9 @@ func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkVersion string) (flags [ linkFlags = append(linkFlags, android.JoinWithPrefix(assetDirs.Strings(), "-A ")) linkDeps = append(linkDeps, assetFiles...) - staticLibs, libDeps, libFlags := aaptLibs(ctx, sdkVersion) + transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, sdkVersion) - overlayFiles = append(overlayFiles, staticLibs...) + overlayFiles = append(overlayFiles, transitiveStaticLibs...) linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) @@ -178,6 +180,8 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraL 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 { @@ -189,7 +193,7 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraL compiledOverlay = append(compiledOverlay, overlayFiles...) - aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, + aapt2Link(ctx, packageRes, srcJar, proguardOptionsFile, rTxt, extraPackages, linkFlags, linkDeps, compiledRes, compiledOverlay) a.aaptSrcJar = srcJar @@ -197,11 +201,14 @@ func (a *aapt) buildActions(ctx android.ModuleContext, sdkVersion string, extraL 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) (staticLibs, deps android.Paths, flags []string) { +func aaptLibs(ctx android.ModuleContext, sdkVersion string) (transitiveStaticLibs, deps android.Paths, + flags []string) { + var sharedLibs android.Paths sdkDep := decodeSdkDep(ctx, sdkVersion) @@ -211,7 +218,8 @@ func aaptLibs(ctx android.ModuleContext, sdkVersion string) (staticLibs, deps an ctx.VisitDirectDeps(func(module android.Module) { var exportPackage android.Path - if aarDep, ok := module.(AndroidLibraryDependency); ok { + aarDep, _ := module.(AndroidLibraryDependency) + if aarDep != nil { exportPackage = aarDep.ExportPackage() } @@ -222,15 +230,16 @@ func aaptLibs(ctx android.ModuleContext, sdkVersion string) (staticLibs, deps an } case staticLibTag: if exportPackage != nil { - staticLibs = append(staticLibs, exportPackage) + transitiveStaticLibs = append(transitiveStaticLibs, exportPackage) + transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...) } } }) deps = append(deps, sharedLibs...) - deps = append(deps, staticLibs...) + deps = append(deps, transitiveStaticLibs...) - if len(staticLibs) > 0 { + if len(transitiveStaticLibs) > 0 { flags = append(flags, "--auto-add-overlay") } @@ -238,7 +247,9 @@ func aaptLibs(ctx android.ModuleContext, sdkVersion string) (staticLibs, deps an flags = append(flags, "-I "+sharedLib.String()) } - return staticLibs, deps, flags + transitiveStaticLibs = android.FirstUniquePaths(transitiveStaticLibs) + + return transitiveStaticLibs, deps, flags } type AndroidLibrary struct { @@ -250,12 +261,17 @@ type AndroidLibrary struct { 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) { @@ -290,10 +306,13 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) 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 { @@ -331,9 +350,12 @@ 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) @@ -346,6 +368,10 @@ 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 { return &a.prebuilt } @@ -362,7 +388,7 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { } } - ctx.AddDependency(ctx.Module(), staticLibTag, a.properties.Libs...) + ctx.AddDependency(ctx.Module(), libTag, a.properties.Libs...) ctx.AddDependency(ctx.Module(), staticLibTag, a.properties.Static_libs...) } @@ -410,6 +436,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 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 @@ -422,14 +449,14 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { linkFlags = append(linkFlags, "--manifest "+manifest.String()) linkDeps = append(linkDeps, manifest) - staticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version)) + transitiveStaticLibs, libDeps, libFlags := aaptLibs(ctx, String(a.properties.Sdk_version)) linkDeps = append(linkDeps, libDeps...) linkFlags = append(linkFlags, libFlags...) - overlayRes := append(android.Paths{flata}, staticLibs...) + overlayRes := append(android.Paths{flata}, transitiveStaticLibs...) - aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, + aapt2Link(ctx, a.exportPackage, srcJar, proguardOptionsFile, rTxt, a.extraAaptPackagesFile, linkFlags, linkDeps, nil, overlayRes) } diff --git a/java/androidmk.go b/java/androidmk.go index 1e77d05f8..b168f2c7c 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -135,6 +135,7 @@ func (prebuilt *AARImport) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", prebuilt.classpathFile.String()) fmt.Fprintln(w, "LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=", prebuilt.exportPackage.String()) fmt.Fprintln(w, "LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=", prebuilt.proguardFlags.String()) + fmt.Fprintln(w, "LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=", prebuilt.extraAaptPackagesFile.String()) fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", String(prebuilt.properties.Sdk_version)) }, }, @@ -243,6 +244,7 @@ func (a *AndroidLibrary) AndroidMk() android.AndroidMkData { } fmt.Fprintln(w, "LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE :=", a.exportPackage.String()) + fmt.Fprintln(w, "LOCAL_SOONG_STATIC_LIBRARY_EXTRA_PACKAGES :=", a.extraAaptPackagesFile.String()) fmt.Fprintln(w, "LOCAL_FULL_MANIFEST_FILE :=", a.manifestPath.String()) fmt.Fprintln(w, "LOCAL_SOONG_EXPORT_PROGUARD_FLAGS :=", strings.Join(a.exportedProguardFlagFiles.Strings(), " ")) diff --git a/java/app.go b/java/app.go index 1fdce129c..ae0592a6a 100644 --- a/java/app.go +++ b/java/app.go @@ -67,6 +67,10 @@ func (a *AndroidApp) ExportedProguardFlagFiles() android.Paths { return nil } +func (a *AndroidApp) ExportedStaticPackages() android.Paths { + return nil +} + var _ AndroidLibraryDependency = (*AndroidApp)(nil) type certificate struct { diff --git a/java/config/config.go b/java/config/config.go index 5587a16dc..980db3b0a 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -87,6 +87,7 @@ func init() { pctx.SourcePathVariable("GenKotlinBuildFileCmd", "build/soong/scripts/gen-kotlin-build-file.sh") pctx.SourcePathVariable("JarArgsCmd", "build/soong/scripts/jar-args.sh") + pctx.HostBinToolVariable("ExtractJarPackagesCmd", "extract_jar_packages") pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") pctx.HostBinToolVariable("MergeZipsCmd", "merge_zips") pctx.HostBinToolVariable("Zip2ZipCmd", "zip2zip") diff --git a/java/config/makevars.go b/java/config/makevars.go index 5210f2022..27c7daaa5 100644 --- a/java/config/makevars.go +++ b/java/config/makevars.go @@ -77,4 +77,6 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("JACOCO_CLI_JAR", "${JacocoCLIJar}") ctx.Strict("DEFAULT_JACOCO_EXCLUDE_FILTER", strings.Join(DefaultJacocoExcludeFilter, ",")) + + ctx.Strict("EXTRACT_JAR_PACKAGES", "${ExtractJarPackagesCmd}") }