From dc1e829b59fe97489180e38d8d8783468a3b9453 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 17 Oct 2018 15:05:56 -0700 Subject: [PATCH 1/4] Always allow duplicates with identical CRC32 and size Don't warn on duplicate files in merge_zips if they have identical CRC32 and size values. Test: m checkbuild Test: merge_zips_test.go Change-Id: I61336ca4d4d3b7402c24a7abd337bd350fe10930 --- cmd/merge_zips/merge_zips.go | 31 +++++++++++++++++++++---------- cmd/merge_zips/merge_zips_test.go | 8 ++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go index f383de90a..8e71a9784 100644 --- a/cmd/merge_zips/merge_zips.go +++ b/cmd/merge_zips/merge_zips.go @@ -173,6 +173,10 @@ func (ze zipEntry) CRC32() uint32 { return ze.content.FileHeader.CRC32 } +func (ze zipEntry) Size() uint64 { + return ze.content.FileHeader.UncompressedSize64 +} + func (ze zipEntry) WriteToZip(dest string, zw *zip.Writer) error { return zw.CopyFrom(ze.content, dest) } @@ -195,6 +199,10 @@ func (be bufferEntry) CRC32() uint32 { return crc32.ChecksumIEEE(be.content) } +func (be bufferEntry) Size() uint64 { + return uint64(len(be.content)) +} + func (be bufferEntry) WriteToZip(dest string, zw *zip.Writer) error { w, err := zw.CreateHeader(be.fh) if err != nil { @@ -215,6 +223,7 @@ type zipSource interface { String() string IsDir() bool CRC32() uint32 + Size() uint64 WriteToZip(dest string, zw *zip.Writer) error } @@ -369,25 +378,27 @@ func mergeZips(readers []namedZipReader, writer *zip.Writer, manifest, entrypoin return fmt.Errorf("Directory/file mismatch at %v from %v and %v\n", dest, existingSource, source) } + if ignoreDuplicates { continue } + if emulateJar && file.Name == jar.ManifestFile || file.Name == jar.ModuleInfoClass { // Skip manifest and module info files that are not from the first input file continue } - if !source.IsDir() { - if emulateJar { - if existingSource.CRC32() != source.CRC32() { - fmt.Fprintf(os.Stdout, "WARNING: Duplicate path %v found in %v and %v\n", - dest, existingSource, source) - } - } else { - return fmt.Errorf("Duplicate path %v found in %v and %v\n", - dest, existingSource, source) - } + + if source.IsDir() { + continue } + + if existingSource.CRC32() == source.CRC32() && existingSource.Size() == source.Size() { + continue + } + + return fmt.Errorf("Duplicate path %v found in %v and %v\n", + dest, existingSource, source) } } } diff --git a/cmd/merge_zips/merge_zips_test.go b/cmd/merge_zips/merge_zips_test.go index f91111f14..19fa5edd3 100644 --- a/cmd/merge_zips/merge_zips_test.go +++ b/cmd/merge_zips/merge_zips_test.go @@ -87,6 +87,14 @@ func TestMergeZips(t *testing.T) { ignoreDuplicates: true, }, + { + name: "duplicates identical", + in: [][]testZipEntry{ + {a}, + {a}, + }, + out: []testZipEntry{a}, + }, { name: "sort", in: [][]testZipEntry{ From 094054ab0761903626f27d32781dc64b67534219 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 17 Oct 2018 15:10:48 -0700 Subject: [PATCH 2/4] Support main_class property in java_binary modules Add a main_class property that will be used to generate a manifest containing a Main-Class entry. Test: m checkbuild Change-Id: I0a59bb2b93cad915afd82fba708fa0f7eda2fe7a --- java/builder.go | 11 +++++++++++ java/java.go | 19 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/java/builder.go b/java/builder.go index f55a7c796..cefb916df 100644 --- a/java/builder.go +++ b/java/builder.go @@ -399,6 +399,17 @@ func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePat }) } +func GenerateMainClassManifest(ctx android.ModuleContext, outputFile android.WritablePath, mainClass string) { + ctx.Build(pctx, android.BuildParams{ + Rule: android.WriteFile, + Description: "manifest", + Output: outputFile, + Args: map[string]string{ + "content": "Main-Class: " + mainClass + "\n", + }, + }) +} + type classpath []android.Path func (x *classpath) FormJavaClassPath(optName string) string { diff --git a/java/java.go b/java/java.go index e5218bb76..c15a62b24 100644 --- a/java/java.go +++ b/java/java.go @@ -309,6 +309,9 @@ type Module struct { // list of extra progurad flag files extraProguardFlagFiles android.Paths + // manifest file to use instead of properties.Manifest + overrideManifest android.OptionalPath + // list of SDK lib names that this java moudule is exporting exportedSdkLibs []string @@ -1193,8 +1196,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars ...android.Path jars = append(jars, deps.staticJars...) jars = append(jars, deps.staticResourceJars...) - var manifest android.OptionalPath - if j.properties.Manifest != nil { + manifest := j.overrideManifest + if !manifest.Valid() && j.properties.Manifest != nil { manifest = android.OptionalPathForPath(ctx.ExpandSource(*j.properties.Manifest, "manifest")) } @@ -1536,6 +1539,9 @@ func TestHostFactory() android.Module { type binaryProperties struct { // installable script to execute the resulting jar Wrapper *string + + // Name of the class containing main to be inserted into the manifest as Main-Class. + Main_class *string } type Binary struct { @@ -1556,6 +1562,15 @@ func (j *Binary) HostToolPath() android.OptionalPath { func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { if ctx.Arch().ArchType == android.Common { // Compile the jar + if j.binaryProperties.Main_class != nil { + if j.properties.Manifest != nil { + ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") + } + manifestFile := android.PathForModuleOut(ctx, "manifest.txt") + GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) + j.overrideManifest = android.OptionalPathForPath(manifestFile) + } + j.Library.GenerateAndroidBuildActions(ctx) } else { // Handle the binary wrapper From 78e3cb096bc82bc5a92eb112faf6c0f5411431d2 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 17 Oct 2018 15:42:59 -0700 Subject: [PATCH 3/4] Fix incremental build issue in aapt2 Clear the directory with generated java files before generating new files into the directory. Fixes an issue where old, no longer generated files could remain and end up in R.jar. Test: m checkbuild Change-Id: I174030c336c5b7e6fe1198a43714af565babd7e6 --- java/aapt2.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/aapt2.go b/java/aapt2.go index 70c750716..5553bfdf8 100644 --- a/java/aapt2.go +++ b/java/aapt2.go @@ -111,7 +111,8 @@ func aapt2CompileDirs(ctx android.ModuleContext, flata android.WritablePath, dir var aapt2LinkRule = pctx.AndroidStaticRule("aapt2Link", blueprint.RuleParams{ - Command: `${config.Aapt2Cmd} link -o $out $flags --java $genDir --proguard $proguardOptions ` + + Command: `rm -rf $genDir && ` + + `${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.ExtractJarPackagesCmd} -i $genJar -o $extraPackages --prefix '--extra-packages '`, From 4b964c00a6f114a85cf13ef825e72df25985f8e6 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Mon, 15 Oct 2018 16:18:06 -0700 Subject: [PATCH 4/4] Fix instrumentation_for to match LOCAL_INSTRUMENTATION_FOR The value from instrumentation_for should not go to aapt2 link --rename-instrumentation-target-package, that should be the equivalent of LOCAL_MANIFEST_INSTRUMENTATION_FOR. That property is never used in Make, so it is left unimplemented in Soong. Add the module listed in instrumentation_for as a shared library for javac, but don't import its resources. Bug: 117804211 Test: m checkbuild Change-Id: I7f035dc0ecb964a3ca391ae1ca2b87cb0f6a7cec --- java/aar.go | 2 ++ java/app.go | 12 ++++++------ java/dex.go | 4 ++-- java/java.go | 23 ++++++++++++----------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/java/aar.go b/java/aar.go index 35fb96f78..a06d19164 100644 --- a/java/aar.go +++ b/java/aar.go @@ -250,6 +250,8 @@ 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: if exportPackage != nil { sharedLibs = append(sharedLibs, exportPackage) diff --git a/java/app.go b/java/app.go index d21b62aec..5d25dcf17 100644 --- a/java/app.go +++ b/java/app.go @@ -318,12 +318,6 @@ type AndroidTest struct { } func (a *AndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { - if String(a.appTestProperties.Instrumentation_for) != "" { - a.AndroidApp.extraLinkFlags = append(a.AndroidApp.extraLinkFlags, - "--rename-instrumentation-target-package", - String(a.appTestProperties.Instrumentation_for)) - } - a.generateAndroidBuildActions(ctx) a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath) @@ -335,6 +329,12 @@ func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) { android.ExtractSourceDeps(ctx, a.testProperties.Test_config_template) android.ExtractSourcesDeps(ctx, a.testProperties.Data) a.AndroidApp.DepsMutator(ctx) + if a.appTestProperties.Instrumentation_for != nil { + // The android_app dependency listed in instrumentation_for needs to be added to the classpath for javac, + // but not added to the aapt2 link includes like a normal android_app or android_library dependency, so + // use instrumentationForTag instead of libTag. + ctx.AddVariationDependencies(nil, instrumentationForTag, String(a.appTestProperties.Instrumentation_for)) + } } func AndroidTestFactory() android.Module { diff --git a/java/dex.go b/java/dex.go index ce0c18e66..625fb83cc 100644 --- a/java/dex.go +++ b/java/dex.go @@ -157,6 +157,8 @@ func (j *Module) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8F if !Bool(opt.Obfuscate) { r8Flags = append(r8Flags, "-dontobfuscate") } + // TODO(ccross): if this is an instrumentation test of an obfuscated app, use the + // dictionary of the app and move the app from libraryjars to injars. return r8Flags, r8Deps } @@ -171,8 +173,6 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, outDir := android.PathForModuleOut(ctx, "dex") if useR8 { - // TODO(ccross): if this is an instrumentation test of an obfuscated app, use the - // dictionary of the app and move the app from libraryjars to injars. proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") j.proguardDictionary = proguardDictionary r8Flags, r8Deps := j.r8Flags(ctx, flags) diff --git a/java/java.go b/java/java.go index c15a62b24..d7068c6d9 100644 --- a/java/java.go +++ b/java/java.go @@ -371,16 +371,17 @@ type jniDependencyTag struct { } var ( - staticLibTag = dependencyTag{name: "staticlib"} - libTag = dependencyTag{name: "javalib"} - annoTag = dependencyTag{name: "annotation processor"} - bootClasspathTag = dependencyTag{name: "bootclasspath"} - systemModulesTag = dependencyTag{name: "system modules"} - frameworkResTag = dependencyTag{name: "framework-res"} - frameworkApkTag = dependencyTag{name: "framework-apk"} - kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} - proguardRaiseTag = dependencyTag{name: "proguard-raise"} - certificateTag = dependencyTag{name: "certificate"} + staticLibTag = dependencyTag{name: "staticlib"} + libTag = dependencyTag{name: "javalib"} + annoTag = dependencyTag{name: "annotation processor"} + bootClasspathTag = dependencyTag{name: "bootclasspath"} + systemModulesTag = dependencyTag{name: "system modules"} + frameworkResTag = dependencyTag{name: "framework-res"} + frameworkApkTag = dependencyTag{name: "framework-apk"} + kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} + proguardRaiseTag = dependencyTag{name: "proguard-raise"} + certificateTag = dependencyTag{name: "certificate"} + instrumentationForTag = dependencyTag{name: "instrumentation_for"} ) type sdkDep struct { @@ -820,7 +821,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { switch tag { case bootClasspathTag: deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...) - case libTag: + case libTag, instrumentationForTag: deps.classpath = append(deps.classpath, dep.HeaderJars()...) // sdk lib names from dependencies are re-exported j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...)