diff options
-rw-r--r-- | anttasks/src/com/android/ant/ApkBuilderTask.java | 30 | ||||
-rw-r--r-- | scripts/android_rules.xml | 88 | ||||
-rw-r--r-- | sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java | 8 |
3 files changed, 101 insertions, 25 deletions
diff --git a/anttasks/src/com/android/ant/ApkBuilderTask.java b/anttasks/src/com/android/ant/ApkBuilderTask.java index af87c78..3a15368 100644 --- a/anttasks/src/com/android/ant/ApkBuilderTask.java +++ b/anttasks/src/com/android/ant/ApkBuilderTask.java @@ -28,6 +28,7 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Path.PathElement; import java.io.File; import java.io.FileInputStream; @@ -39,6 +40,9 @@ import java.util.Map.Entry; public class ApkBuilderTask extends Task { + // ref id to the <path> object containing all the boot classpaths. + private final static String REF_APK_PATH = "android.apks.path"; + /** * Class to represent nested elements. Since they all have only one attribute ('path'), the * same class can be used for all the nested elements (zip, file, sourcefolder, jarfolder, @@ -152,7 +156,7 @@ public class ApkBuilderTask extends Task { @Override public void execute() throws BuildException { - Project taskProject = getProject(); + Project antProject = getProject(); ApkBuilderImpl apkBuilder = new ApkBuilderImpl(); apkBuilder.setVerbose(mVerbose); @@ -197,13 +201,16 @@ public class ApkBuilderTask extends Task { ApkBuilderImpl.processNativeFolder(offset, f, mNativeLibraries); } + // create the Path item that will contain all the generated APKs + // for reuse by other targets (signing/zipaligning) + Path path = new Path(antProject); // first do a full resource package - createApk(apkBuilder, null /*configName*/, null /*resourceFilter*/); + createApk(apkBuilder, null /*configName*/, null /*resourceFilter*/, path); // now see if we need to create file with filtered resources. // Get the project base directory. - File baseDir = taskProject.getBaseDir(); + File baseDir = antProject.getBaseDir(); ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(), PropertyType.DEFAULT); @@ -211,9 +218,13 @@ public class ApkBuilderTask extends Task { if (apkConfigs.size() > 0) { Set<Entry<String, String>> entrySet = apkConfigs.entrySet(); for (Entry<String, String> entry : entrySet) { - createApk(apkBuilder, entry.getKey(), entry.getValue()); + createApk(apkBuilder, entry.getKey(), entry.getValue(), path); } } + + // finally sets the path in the project with a reference + antProject.addReference(REF_APK_PATH, path); + } catch (FileNotFoundException e) { throw new BuildException(e); } catch (IllegalArgumentException e) { @@ -230,10 +241,12 @@ public class ApkBuilderTask extends Task { * package will be generated. * @param resourceFilter the resource configuration filter to pass to aapt (if configName is * non null) + * @param path Ant {@link Path} to which add the generated APKs as {@link PathElement} * @throws FileNotFoundException * @throws ApkCreationException */ - private void createApk(ApkBuilderImpl apkBuilder, String configName, String resourceFilter) + private void createApk(ApkBuilderImpl apkBuilder, String configName, String resourceFilter, + Path path) throws FileNotFoundException, ApkCreationException { // All the files to be included in the archive have already been prep'ed up, except // the resource package. @@ -259,7 +272,7 @@ public class ApkBuilderTask extends Task { } if (mSigned) { - filename = filename + "-debug.apk"; + filename = filename + "-debug-unaligned.apk"; } else { filename = filename + "-unsigned.apk"; } @@ -284,8 +297,13 @@ public class ApkBuilderTask extends Task { } } + // out File File f = new File(mOutFolder, filename); + // add it to the Path object + PathElement element = path.createPathElement(); + element.setLocation(f); + // and generate the apk apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives, mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries); diff --git a/scripts/android_rules.xml b/scripts/android_rules.xml index be53264..c8880c8 100644 --- a/scripts/android_rules.xml +++ b/scripts/android_rules.xml @@ -61,11 +61,16 @@ </condition> <!-- The final package file to generate --> + <property name="out-debug-unaligned-package" value="${out-folder}/${ant.project.name}-debug-unaligned.apk"/> <property name="out-debug-package" value="${out-folder}/${ant.project.name}-debug.apk"/> + <property name="out-unsigned-package" value="${out-folder}/${ant.project.name}-unsigned.apk"/> + <property name="out-unaligned-package" value="${out-folder}/${ant.project.name}-unaligned.apk"/> + <property name="out-release-package" value="${out-folder}/${ant.project.name}-release.apk"/> <!-- Tools --> <condition property="exe" value=".exe" else=""><os family="windows"/></condition> <property name="adb" value="${android-tools}/adb${exe}"/> + <property name="zipalign" value="${android-tools}/zipalign${exe}" /> <!-- rules --> @@ -151,14 +156,14 @@ basename="${ant.project.name}" /> </target> - <!-- Package the application and sign it with a debug key. - This is the default target when building. It is used for debug. --> - <target name="debug" depends="dex, package-resources"> + <!-- Package the application and (maybe) sign it with a debug key. + This requires the property sign.package to be set to true or false. --> + <target name="package"> <apkbuilder outfolder="${out-folder}" basename="${ant.project.name}" - signed="true" - verbose="false"> + signed="${sign.package}" + verbose="true"> <file path="${intermediate-dex}" /> <sourcefolder path="${source-folder}" /> <jarfolder path="${external-libs-folder}" /> @@ -166,20 +171,65 @@ </apkbuilder> </target> - <!-- Package the application without signing it. - This allows for the application to be signed later with an official publishing key. --> - <target name="release" depends="dex, package-resources"> - <apkbuilder - outfolder="${out-folder}" - basename="${ant.project.name}" - signed="false" - verbose="false"> - <file path="${intermediate-dex}" /> - <sourcefolder path="${source-folder}" /> - <jarfolder path="${external-libs-folder}" /> - <nativefolder path="${native-libs-folder}" /> - </apkbuilder> - <echo>All generated packages need to be signed with jarsigner before they are published.</echo> + <target name="no-sign"> + <property name="sign.package" value="false" /> + </target> + + <target name="debug-sign"> + <property name="sign.package" value="true" /> + </target> + + <target name="debug" depends="dex, package-resources, debug-sign, package"> + <exec executable="${zipalign}" failonerror="true"> + <arg value="-f" /> + <arg value="4" /> + <arg path="${out-debug-unaligned-package}" /> + <arg path="${out-debug-package}" /> + </exec> + <echo>Debug Package: ${out-debug-package}</echo> + </target> + + <target name="release-package" depends="dex, package-resources, no-sign, package"> + </target> + + <target name="release.check"> + <condition property="release.sign"> + <and> + <isset property="key.store" /> + <isset property="key.alias" /> + </and> + </condition> + </target> + <target name="release.nosign" depends="release.check" unless="release.sign"> + <echo>No key.store and key.alias properties found in build.properties.</echo> + <echo>Please sign ${out-unsigned-package} manually</echo> + <echo>and run zipalign from the Android SDK tools.</echo> + </target> + + <target name="release" depends="release-package, release.nosign" if="release.sign"> + <!-- get passwords --> + <input + message="Please enter keystore password (store:${key.store}):" + addproperty="key.store.password"/> + <input + message="Please enter password for alias '${key.alias}':" + addproperty="key.alias.password"/> + <!-- sign the APK --> + <signjar + jar="${out-unsigned-package}" + signedjar="${out-unaligned-package}" + keystore="${key.store}" + storepass="${key.store.password}" + alias="${key.alias}" + keypass="${key.alias.password}"/> + <!-- zip align the APK --> + <exec executable="${zipalign}" failonerror="true"> + <arg value="-f" /> + <arg value="4" /> + <arg path="${out-unaligned-package}" /> + <arg path="${out-release-package}" /> + </exec> + <echo>Release Package: ${out-release-package}</echo> </target> <!-- Install the package on the default emulator --> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java index d71491c..f2b73c0 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java @@ -85,9 +85,17 @@ public final class ProjectProperties { "# This file must be checked in Version Control Systems, as it is\n" + "# integral to the build system of your project.\n" + "\n" + + "# This file is only used by the Ant script.\n" + + "\n" + "# You can use this to override default values such as\n" + "# 'source-folder' for the location of your java source folder and\n" + "# 'out-folder' for the location of your output folder.\n" + + "\n" + + "# You can also use it define how the release builds are signed by declaring\n" + + "# the following properties:\n" + + "# 'key.store' for the location of your keystore and\n" + + "# 'key.alias' for the name of the key to use.\n" + + "# The password will be asked during the build when you use the 'release' target.\n" + "\n"; private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>(); |