diff options
author | Xavier Ducrohet <xav@android.com> | 2012-03-07 19:56:17 -0800 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2012-03-07 20:25:29 -0800 |
commit | a08befd52438d523cb2cd41b53f961785d3872fd (patch) | |
tree | 782b1febe0eb57200ef9af545380848ade67da4a | |
parent | 7d2737e54866f33553ee85c546dcea197bffd130 (diff) | |
download | sdk-a08befd52438d523cb2cd41b53f961785d3872fd.zip sdk-a08befd52438d523cb2cd41b53f961785d3872fd.tar.gz sdk-a08befd52438d523cb2cd41b53f961785d3872fd.tar.bz2 |
Ant build now sanitize jar files in setup task.
Previously the list of jar files was sanitized (to remove
duplicates) in the dex task, but this meant the full list
(with duplicates) was passed to proguard when building in release
mode.
This changeset move the sanitization of the jar files in the
Setup Task so that the script later only deals with a sanitized
list. The means the content of libs/*.jar for the current project
must be looked at in the task instead of later in the XML script.
Change-Id: Ib5253b80ee7c1ded004bcdad6184e0900b7a7543
-rw-r--r-- | anttasks/src/com/android/ant/ApkBuilderTask.java | 9 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/DexExecTask.java | 48 | ||||
-rw-r--r-- | anttasks/src/com/android/ant/NewSetupTask.java | 103 | ||||
-rw-r--r-- | files/ant/build.xml | 28 | ||||
-rw-r--r-- | sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java | 12 |
5 files changed, 123 insertions, 77 deletions
diff --git a/anttasks/src/com/android/ant/ApkBuilderTask.java b/anttasks/src/com/android/ant/ApkBuilderTask.java index 14b0678..8997ad1 100644 --- a/anttasks/src/com/android/ant/ApkBuilderTask.java +++ b/anttasks/src/com/android/ant/ApkBuilderTask.java @@ -342,16 +342,25 @@ public class ApkBuilderTask extends SingleDependencyTask { // add the content of the zip files. for (File f : zipFiles) { + if (mVerbose) { + System.out.println("Zip Input: " + f.getAbsolutePath()); + } apkBuilder.addZipFile(f); } // now go through the list of file to directly add the to the list. for (File f : sourceFolderList) { + if (mVerbose) { + System.out.println("Source Folder Input: " + f.getAbsolutePath()); + } apkBuilder.addSourceFolder(f); } // now go through the list of jar files. for (File f : jarFileList) { + if (mVerbose) { + System.out.println("Jar Input: " + f.getAbsolutePath()); + } apkBuilder.addResourcesFromJar(f); } diff --git a/anttasks/src/com/android/ant/DexExecTask.java b/anttasks/src/com/android/ant/DexExecTask.java index 085e924..a2b2b07 100644 --- a/anttasks/src/com/android/ant/DexExecTask.java +++ b/anttasks/src/com/android/ant/DexExecTask.java @@ -16,10 +16,6 @@ package com.android.ant; -import com.android.sdklib.build.JarListSanitizer; -import com.android.sdklib.build.JarListSanitizer.DifferentLibException; -import com.android.sdklib.build.JarListSanitizer.Sha1Exception; - import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.ExecTask; import org.apache.tools.ant.types.FileSet; @@ -165,12 +161,11 @@ public class DexExecTask extends SingleDependencyTask { task.createArg().setValue("--output"); task.createArg().setValue(mOutput); - - paths = sanitizePaths(paths); - for (File f : paths) { String absPath = f.getAbsolutePath(); - System.out.println("Input: " + absPath); + if (mVerbose) { + System.out.println("Input: " + absPath); + } task.createArg().setValue(absPath); } @@ -185,41 +180,4 @@ public class DexExecTask extends SingleDependencyTask { protected String getExecTaskName() { return "dx"; } - - // private helper methods. - - private List<File> sanitizePaths(List<File> paths) { - // first get the non-files. - List<File> results = new ArrayList<File>(); - for (int i = 0 ; i < paths.size() ;) { - File f = paths.get(i); - // TEMP WORKAROUND: ignore classes.jar as all the output of libraries are - // called the same (in Ant) but are not actually the same jar file. - // TODO: Be aware of library output vs. regular jar dependency. - if (f.isFile() && f.getName().equals("classes.jar") == false) { - i++; - } else { - results.add(f); - paths.remove(i); - } - } - - File outputFile = new File(mOutput); - JarListSanitizer sanitizer = new JarListSanitizer(outputFile.getParentFile()); - - try { - results.addAll(sanitizer.sanitize(paths)); - } catch (DifferentLibException e) { - String[] details = e.getDetails(); - for (String s : details) { - System.err.println(s); - } - throw new BuildException(e.getMessage(), e); - } catch (Sha1Exception e) { - throw new BuildException( - "Failed to compute sha1 for " + e.getJarFile().getAbsolutePath(), e); - } - - return results; - } } diff --git a/anttasks/src/com/android/ant/NewSetupTask.java b/anttasks/src/com/android/ant/NewSetupTask.java index 1f29d17..f2f365a 100644 --- a/anttasks/src/com/android/ant/NewSetupTask.java +++ b/anttasks/src/com/android/ant/NewSetupTask.java @@ -24,6 +24,9 @@ import com.android.sdklib.IAndroidTarget.IOptionalLibrary; import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; +import com.android.sdklib.build.JarListSanitizer; +import com.android.sdklib.build.JarListSanitizer.DifferentLibException; +import com.android.sdklib.build.JarListSanitizer.Sha1Exception; import com.android.sdklib.internal.project.ProjectProperties; import com.android.sdklib.internal.project.ProjectProperties.PropertyType; import com.android.sdklib.xml.AndroidManifest; @@ -83,6 +86,7 @@ public class NewSetupTask extends Task { private String mProjectLibrariesJarsOut; private String mProjectLibrariesLibsOut; private String mTargetApiOut; + private boolean mVerbose = false; public void setProjectTypeOut(String projectTypeOut) { mProjectTypeOut = projectTypeOut; @@ -132,6 +136,14 @@ public class NewSetupTask extends Task { mTargetApiOut = targetApiOut; } + /** + * Sets the value of the "verbose" attribute. + * @param verbose the value. + */ + public void setVerbose(boolean verbose) { + mVerbose = verbose; + } + @Override public void execute() throws BuildException { if (mProjectTypeOut == null) { @@ -440,9 +452,12 @@ public class NewSetupTask extends Task { Path rootPath = new Path(antProject); Path resPath = new Path(antProject); Path libsPath = new Path(antProject); - Path jarsPath = new Path(antProject); StringBuilder packageStrBuilder = new StringBuilder(); + // list of all the jars that are on the classpath. This will receive the + // project's libs/*.jar files, the Library Projects output and their own libs/*.jar + List<File> jars = new ArrayList<File>(); + FilenameFilter filter = new FilenameFilter() { @Override public boolean accept(File dir, String name) { @@ -477,17 +492,15 @@ public class NewSetupTask extends Task { // get the jars from it too. // 1. the library code jar - element = jarsPath.createPathElement(); - element.setPath(libRootPath + "/" + SdkConstants.FD_OUTPUT + - "/" + SdkConstants.FN_CLASSES_JAR); + jars.add(new File(libRootPath + "/" + SdkConstants.FD_OUTPUT + + "/" + SdkConstants.FN_CLASSES_JAR)); // 2. the 3rd party jar files File libsFolder = new File(library, SdkConstants.FD_NATIVE_LIBS); File[] jarFiles = libsFolder.listFiles(filter); if (jarFiles != null) { for (File jarFile : jarFiles) { - element = jarsPath.createPathElement(); - element.setPath(jarFile.getAbsolutePath()); + jars.add(jarFile); } } @@ -516,29 +529,28 @@ public class NewSetupTask extends Task { PathElement element = rootPath.createPathElement(); element.setPath(library.getAbsolutePath()); } + System.out.println(); } else { System.out.println("No library dependencies.\n"); } - System.out.println("------------------\n"); + System.out.println("------------------"); - boolean hasLibraries = jarsPath.list().length > 0; + boolean hasLibraries = jars.size() > 0; if (androidTarget.getVersion().getApiLevel() <= 15) { System.out.println("API<=15: Adding annotations.jar to the classpath.\n"); - PathElement element = jarsPath.createPathElement(); - element.setPath(sdkLocation + "/" + SdkConstants.FD_TOOLS + + jars.add(new File(sdkLocation + "/" + SdkConstants.FD_TOOLS + "/" + SdkConstants.FD_SUPPORT + - "/" + SdkConstants.FN_ANNOTATIONS_JAR); + "/" + SdkConstants.FN_ANNOTATIONS_JAR)); - System.out.println("------------------\n"); + System.out.println("------------------"); } // even with no libraries, always setup these so that various tasks in Ant don't complain // (the task themselves can handle a ref to an empty Path) - antProject.addReference(mProjectLibrariesJarsOut, jarsPath); antProject.addReference(mProjectLibrariesLibsOut, libsPath); // the rest is done only if there's a library. @@ -547,6 +559,36 @@ public class NewSetupTask extends Task { antProject.addReference(mProjectLibrariesResOut, resPath); antProject.setProperty(mProjectLibrariesPackageOut, packageStrBuilder.toString()); } + + // add the project's own content of libs/*.jar + File libsFolder = new File(SdkConstants.FD_NATIVE_LIBS); + File[] jarFiles = libsFolder.listFiles(filter); + if (jarFiles != null) { + for (File jarFile : jarFiles) { + jars.add(jarFile); + } + } + + // now sanitize the path to remove dups + jars = sanitizePaths(antProject, jars); + + // and create a Path object for them + Path jarsPath = new Path(antProject); + if (mVerbose) { + System.out.println("Sanitized jar list:"); + } + for (File f : jars) { + if (mVerbose) { + System.out.println("- " + f.getAbsolutePath()); + } + PathElement element = jarsPath.createPathElement(); + element.setPath(f.getAbsolutePath()); + } + antProject.addReference(mProjectLibrariesJarsOut, jarsPath); + + if (mVerbose) { + System.out.println(); + } } /** @@ -683,4 +725,39 @@ public class NewSetupTask extends Task { } return new DeweyDecimal(sb.toString()); } + + private List<File> sanitizePaths(Project antProject, List<File> paths) { + // first get the non-files. + List<File> results = new ArrayList<File>(); + for (int i = 0 ; i < paths.size() ;) { + File f = paths.get(i); + // TEMP WORKAROUND: ignore classes.jar as all the output of libraries are + // called the same (in Ant) but are not actually the same jar file. + // TODO: Be aware of library output vs. regular jar dependency. + if (f.isFile() && f.getName().equals(SdkConstants.FN_CLASSES_JAR) == false) { + i++; + } else { + results.add(f); + paths.remove(i); + } + } + + File outputFile = new File(antProject.getProperty("out.absolute.dir")); + JarListSanitizer sanitizer = new JarListSanitizer(outputFile); + + try { + results.addAll(sanitizer.sanitize(paths)); + } catch (DifferentLibException e) { + String[] details = e.getDetails(); + for (String s : details) { + System.err.println(s); + } + throw new BuildException(e.getMessage(), e); + } catch (Sha1Exception e) { + throw new BuildException( + "Failed to compute sha1 for " + e.getJarFile().getAbsolutePath(), e); + } + + return results; + } } diff --git a/files/ant/build.xml b/files/ant/build.xml index d68b56b..77f9a16 100644 --- a/files/ant/build.xml +++ b/files/ant/build.xml @@ -267,7 +267,7 @@ </condition> <else> <path id="out.dex.jar.input.ref"> - <path refid="jar.libs.ref" /> + <path refid="project.libraries.jars" /> </path> </else> </if> @@ -307,7 +307,7 @@ buildType="${build.is.packaging.debug}/${build.is.signing.debug}"> <dex path="${intermediate.dex.file}"/> <sourcefolder path="${source.absolute.dir}"/> - <jarfile refid="jar.libs.ref" /> + <jarfile refid="project.libraries.jars" /> <nativefolder path="${native.libs.absolute.dir}" /> <nativefolder refid="project.libraries.libs" /> <extra-jars/> @@ -442,6 +442,12 @@ <not><isset property="setup.done" /></not> </condition> <then> + <echo>Creating output directories if needed...</echo> + <mkdir dir="${resource.absolute.dir}" /> + <mkdir dir="${jar.libs.absolute.dir}" /> + <mkdir dir="${out.absolute.dir}" /> + <mkdir dir="${out.res.absolute.dir}" /> + <property name="setup.done" value="true" /> <echo>Gathering info for ${ant.project.name}...</echo> <!-- load project properties, resolve Android target, library dependencies @@ -460,6 +466,7 @@ projectLibrariesPackageOut="project.libraries.package" projectLibrariesLibsOut="project.libraries.libs" targetApiOut="target.api" + verbose="${verbose}" /> <!-- sets a few boolean based on android.project.type @@ -540,13 +547,6 @@ <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode" output="manifest.hasCode" default="true"/> - <!-- create a path with all the jar files, from the main project and the - libraries --> - <path id="jar.libs.ref"> - <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" /> - <path refid="project.libraries.jars" /> - </path> - <!-- If the "debug" build type changed, clear out the compiled code. This is to make sure the new BuildConfig.DEBUG value is picked up as javac can't deal with this type of change in its dependency computation. --> @@ -582,11 +582,6 @@ </else> </if> - <echo>Creating output directories if needed...</echo> - <mkdir dir="${resource.absolute.dir}" /> - <mkdir dir="${jar.libs.absolute.dir}" /> - <mkdir dir="${out.absolute.dir}" /> - <mkdir dir="${out.res.absolute.dir}" /> <do-only-if-manifest-hasCode> <mkdir dir="${gen.absolute.dir}" /> <mkdir dir="${out.classes.absolute.dir}" /> @@ -673,7 +668,7 @@ bootclasspathref="android.target.classpath" verbose="${verbose}" classpath="${extensible.classpath}" - classpathref="jar.libs.ref" + classpathref="project.libraries.jars" fork="${need.javac.fork}"> <src path="${source.absolute.dir}" /> <src path="${gen.absolute.dir}" /> @@ -700,6 +695,7 @@ <jar destfile="${out.library.jar.file}"> <fileset dir="${out.classes.absolute.dir}" + includes="**/*.class" excludes="${manifest.package.path}/R.class ${manifest.package.path}/R$*.class ${manifest.package.path}/Manifest.class ${manifest.package.path}/Manifest$*.class ${manifest.package.path}/BuildConfig.class"/> <fileset dir="${source.absolute.dir}" excludes="**/*.java ${android.package.excludes}" /> </jar> @@ -774,7 +770,7 @@ files. --> <path id="project.jars.ref"> <pathelement location="${preobfuscate.jar.file}" /> - <path refid="jar.libs.ref" /> + <path refid="project.libraries.jars" /> </path> <!-- Set the project jar files Path object into a single property. It'll be all the jar files separated by a platform path-separator. diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java index c6c0c22..fa7b00b 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java @@ -364,8 +364,9 @@ public class JarListSanitizer { private void writeJarList(Map<String, List<JarEntity>> nameMap) { File cacheFile = new File(mOut, CACHE_FILENAME); + OutputStreamWriter writer = null; try { - OutputStreamWriter writer = new OutputStreamWriter( + writer = new OutputStreamWriter( new FileOutputStream(cacheFile), "UTF-8"); writer.write("# cache for current jar dependecy. DO NOT EDIT.\n"); @@ -393,14 +394,19 @@ public class JarListSanitizer { } } } - - writer.close(); } catch (IOException e) { mOutStream.println("WARNING: unable to write jarlist cache file " + cacheFile.getAbsolutePath()); } catch (Sha1Exception e) { // shouldn't happen here since we check that the sha1 is present first, meaning it's // already been computing. + } finally { + if (writer != null) { + try { + writer.close(); + } catch (IOException e) { + } + } } } |