Make the Ant script sign and zipalign release builds.
It will also align debug builds. BUG: 2052744
This commit is contained in:
@@ -28,6 +28,7 @@ import org.apache.tools.ant.Project;
|
|||||||
import org.apache.tools.ant.ProjectComponent;
|
import org.apache.tools.ant.ProjectComponent;
|
||||||
import org.apache.tools.ant.Task;
|
import org.apache.tools.ant.Task;
|
||||||
import org.apache.tools.ant.types.Path;
|
import org.apache.tools.ant.types.Path;
|
||||||
|
import org.apache.tools.ant.types.Path.PathElement;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@@ -39,6 +40,9 @@ import java.util.Map.Entry;
|
|||||||
|
|
||||||
public class ApkBuilderTask extends Task {
|
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
|
* 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,
|
* same class can be used for all the nested elements (zip, file, sourcefolder, jarfolder,
|
||||||
@@ -152,7 +156,7 @@ public class ApkBuilderTask extends Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
Project taskProject = getProject();
|
Project antProject = getProject();
|
||||||
|
|
||||||
ApkBuilderImpl apkBuilder = new ApkBuilderImpl();
|
ApkBuilderImpl apkBuilder = new ApkBuilderImpl();
|
||||||
apkBuilder.setVerbose(mVerbose);
|
apkBuilder.setVerbose(mVerbose);
|
||||||
@@ -197,13 +201,16 @@ public class ApkBuilderTask extends Task {
|
|||||||
ApkBuilderImpl.processNativeFolder(offset, f, mNativeLibraries);
|
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
|
// 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.
|
// now see if we need to create file with filtered resources.
|
||||||
// Get the project base directory.
|
// Get the project base directory.
|
||||||
File baseDir = taskProject.getBaseDir();
|
File baseDir = antProject.getBaseDir();
|
||||||
ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
|
ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
|
||||||
PropertyType.DEFAULT);
|
PropertyType.DEFAULT);
|
||||||
|
|
||||||
@@ -211,9 +218,13 @@ public class ApkBuilderTask extends Task {
|
|||||||
if (apkConfigs.size() > 0) {
|
if (apkConfigs.size() > 0) {
|
||||||
Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
|
Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
|
||||||
for (Entry<String, String> entry : 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) {
|
} catch (FileNotFoundException e) {
|
||||||
throw new BuildException(e);
|
throw new BuildException(e);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
@@ -230,10 +241,12 @@ public class ApkBuilderTask extends Task {
|
|||||||
* package will be generated.
|
* package will be generated.
|
||||||
* @param resourceFilter the resource configuration filter to pass to aapt (if configName is
|
* @param resourceFilter the resource configuration filter to pass to aapt (if configName is
|
||||||
* non null)
|
* non null)
|
||||||
|
* @param path Ant {@link Path} to which add the generated APKs as {@link PathElement}
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
* @throws ApkCreationException
|
* @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 {
|
throws FileNotFoundException, ApkCreationException {
|
||||||
// All the files to be included in the archive have already been prep'ed up, except
|
// All the files to be included in the archive have already been prep'ed up, except
|
||||||
// the resource package.
|
// the resource package.
|
||||||
@@ -259,7 +272,7 @@ public class ApkBuilderTask extends Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mSigned) {
|
if (mSigned) {
|
||||||
filename = filename + "-debug.apk";
|
filename = filename + "-debug-unaligned.apk";
|
||||||
} else {
|
} else {
|
||||||
filename = filename + "-unsigned.apk";
|
filename = filename + "-unsigned.apk";
|
||||||
}
|
}
|
||||||
@@ -284,8 +297,13 @@ public class ApkBuilderTask extends Task {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// out File
|
||||||
File f = new File(mOutFolder, filename);
|
File f = new File(mOutFolder, filename);
|
||||||
|
|
||||||
|
// add it to the Path object
|
||||||
|
PathElement element = path.createPathElement();
|
||||||
|
element.setLocation(f);
|
||||||
|
|
||||||
// and generate the apk
|
// and generate the apk
|
||||||
apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives,
|
apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives,
|
||||||
mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries);
|
mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries);
|
||||||
|
|||||||
@@ -61,11 +61,16 @@
|
|||||||
</condition>
|
</condition>
|
||||||
|
|
||||||
<!-- The final package file to generate -->
|
<!-- 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-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 -->
|
<!-- Tools -->
|
||||||
<condition property="exe" value=".exe" else=""><os family="windows"/></condition>
|
<condition property="exe" value=".exe" else=""><os family="windows"/></condition>
|
||||||
<property name="adb" value="${android-tools}/adb${exe}"/>
|
<property name="adb" value="${android-tools}/adb${exe}"/>
|
||||||
|
<property name="zipalign" value="${android-tools}/zipalign${exe}" />
|
||||||
|
|
||||||
<!-- rules -->
|
<!-- rules -->
|
||||||
|
|
||||||
@@ -151,14 +156,14 @@
|
|||||||
basename="${ant.project.name}" />
|
basename="${ant.project.name}" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- Package the application and sign it with a debug key.
|
<!-- Package the application and (maybe) sign it with a debug key.
|
||||||
This is the default target when building. It is used for debug. -->
|
This requires the property sign.package to be set to true or false. -->
|
||||||
<target name="debug" depends="dex, package-resources">
|
<target name="package">
|
||||||
<apkbuilder
|
<apkbuilder
|
||||||
outfolder="${out-folder}"
|
outfolder="${out-folder}"
|
||||||
basename="${ant.project.name}"
|
basename="${ant.project.name}"
|
||||||
signed="true"
|
signed="${sign.package}"
|
||||||
verbose="false">
|
verbose="true">
|
||||||
<file path="${intermediate-dex}" />
|
<file path="${intermediate-dex}" />
|
||||||
<sourcefolder path="${source-folder}" />
|
<sourcefolder path="${source-folder}" />
|
||||||
<jarfolder path="${external-libs-folder}" />
|
<jarfolder path="${external-libs-folder}" />
|
||||||
@@ -166,20 +171,65 @@
|
|||||||
</apkbuilder>
|
</apkbuilder>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- Package the application without signing it.
|
<target name="no-sign">
|
||||||
This allows for the application to be signed later with an official publishing key. -->
|
<property name="sign.package" value="false" />
|
||||||
<target name="release" depends="dex, package-resources">
|
</target>
|
||||||
<apkbuilder
|
|
||||||
outfolder="${out-folder}"
|
<target name="debug-sign">
|
||||||
basename="${ant.project.name}"
|
<property name="sign.package" value="true" />
|
||||||
signed="false"
|
</target>
|
||||||
verbose="false">
|
|
||||||
<file path="${intermediate-dex}" />
|
<target name="debug" depends="dex, package-resources, debug-sign, package">
|
||||||
<sourcefolder path="${source-folder}" />
|
<exec executable="${zipalign}" failonerror="true">
|
||||||
<jarfolder path="${external-libs-folder}" />
|
<arg value="-f" />
|
||||||
<nativefolder path="${native-libs-folder}" />
|
<arg value="4" />
|
||||||
</apkbuilder>
|
<arg path="${out-debug-unaligned-package}" />
|
||||||
<echo>All generated packages need to be signed with jarsigner before they are published.</echo>
|
<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>
|
</target>
|
||||||
|
|
||||||
<!-- Install the package on the default emulator -->
|
<!-- Install the package on the default emulator -->
|
||||||
|
|||||||
@@ -85,9 +85,17 @@ public final class ProjectProperties {
|
|||||||
"# This file must be checked in Version Control Systems, as it is\n" +
|
"# This file must be checked in Version Control Systems, as it is\n" +
|
||||||
"# integral to the build system of your project.\n" +
|
"# integral to the build system of your project.\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
"# This file is only used by the Ant script.\n" +
|
||||||
|
"\n" +
|
||||||
"# You can use this to override default values such as\n" +
|
"# You can use this to override default values such as\n" +
|
||||||
"# 'source-folder' for the location of your java source folder and\n" +
|
"# 'source-folder' for the location of your java source folder and\n" +
|
||||||
"# 'out-folder' for the location of your output folder.\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";
|
"\n";
|
||||||
|
|
||||||
private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>();
|
private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>();
|
||||||
|
|||||||
Reference in New Issue
Block a user