Is it possible to use the type "apklib" for an Ivy dependency?
In my project I'm using the ActionBarSherlock lib and I want to use Ivy for retrieving the dependency.
Here is my not working xml:
<dependency
name="actionbarsherlock"
conf="binaries"
org="com.actionbarsherlock"
rev="4.2.0"
transitive="true"
type="apklib" />
Thank you for your help!
In this case, all that's needed is a simple dependency declaration as follows:
<dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.2.0" conf="default"/>
Why? This Maven module is special, the Maven POM has been configured with a packaging set to the value "apklib". This means the module's main file is "actionbarsherlock-4.2.0.apklib" instead of the default .jar file.
What's confusing is that there is also a jar file published.......To retrieve this, you can add the special artifact tag:
<dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.2.0" conf="default">
<artifact name="actionbarsherlock" type="jar"/>
</dependency>
To see all the files published by this module I'd recommend Maven search.
You can have for example in ivy.xml:
<configurations>
<conf name="compiling"/>
</configurations>
<dependencies>
<dependency org="com.actionbarsherlock" name="actionbarsherlock" rev="4.3.1" conf="compiling->master"/>
Then if you use ant, in build.xml you could have a target which prepares these "apklib" files for you:
<target name="ivy">
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="ivy-2.3.0.jar"/>
<ivy:retrieve conf="compiling" type="apklib" pattern="libs/[artifact].apklib"/>
<!-- For each apklib artifact you need to unpack it so you can use it. -->
<unzip src="libs/actionbarsherlock.apklib" dest="apklibs/action-bar-sherlock"/>
Now you have src/, res/, etc of the library project in apklibs/action-bar-sherlock.
Here is a full build.xml example of how to build an APK of an Android app which depends on multiple Android library projects:
<?xml version="1.0" encoding="utf-8"?>
<project name="dev" default="release" xmlns:ivy="antlib:org.apache.ivy.ant">
<!-- According to http://developer.android.com/sdk/requirements.html -->
<property name="ant.build.javac.source" value="1.6"/>
<property name="ant.build.javac.target" value="1.6"/>
<property file="local.properties"/>
<property file="project.properties" prefix="android.project"/>
<property name="android.target.dir" value="${sdk.dir}/platforms/${android.project.target}"/>
<property name="android.jar" value="${android.target.dir}/android.jar"/>
<property name="apk.name" value="YOUR_APP.apk"/>
<property name="out.dir" value="build/compiled"/>
<property name="out.test-classes.dir" value="build/compiled-test"/>
<property name="test.libs.dir" value="libs/test"/>
<target name="clean">
<delete dir="build"/>
<delete dir="gen"/>
<delete dir="apklibs"/>
<delete file="${apk.name}"/>
</target>
<target name="ivy">
<taskdef resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" classpath="ivy-2.3.0.jar"/>
<ivy:retrieve conf="compiling" type="bundle,jar" pattern="libs/[artifact].[ext]"/>
<ivy:retrieve conf="compiling" type="apklib" pattern="libs/[artifact].apklib"/>
<unzip src="libs/actionbarsherlock.apklib" dest="apklibs/action-bar-sherlock"/>
<unzip src="libs/library.apklib" dest="apklibs/view-pager-indicator"/>
<path id="lib.path.id">
<fileset dir="libs" includes="*.jar"/>
</path>
<ivy:retrieve conf="compiling" type="source" pattern="sources/[artifact].[ext]" sync="true"/>
<ivy:retrieve conf="packaging" type="bundle,jar" pattern="[artifact]-[revision].[ext]"/>
<ivy:retrieve conf="testing" type="bundle,jar" pattern="libs/test/[artifact].[ext]"/>
</target>
<target name="-check-properties" unless="sdk.dir">
<echo>
You need to create a local.properties file with:
storepass=...the password...
sdk.dir=...path to Android SDK...
</echo>
</target>
<target name="generate" depends="-check-properties">
<mkdir dir="gen"/>
<mkdir dir="build"/>
<condition property="debug.mode" value="--debug-mode" else="">
<istrue value="${debug}"/>
</condition>
<echo>debug=${debug}</echo>
<echo>debug.mode=${debug.mode}</echo>
<exec executable="${sdk.dir}/platform-tools/aapt" failonerror="true">
<arg value="package"/>
<arg line="${debug.mode}"/>
<arg value="-f"/>
<arg value="-m"/>
<arg value="--auto-add-overlay"/>
<arg value="-M"/>
<arg file="AndroidManifest.xml"/>
<arg value="-F"/>
<arg file="build/resources.arsc"/>
<arg value="-I"/>
<arg file="${android.jar}"/>
<arg value="-J"/>
<arg file="gen"/>
<arg value="-S"/>
<arg file="facebook-android-sdk/facebook/res"/>
<arg value="-S"/>
<arg file="apklibs/view-pager-indicator/res"/>
<arg value="-S"/>
<arg file="barone/res"/>
<arg value="-S"/>
<arg file="apklibs/action-bar-sherlock/res"/>
<arg value="-S"/>
<arg file="res"/>
<arg value="--extra-packages"/>
<arg value="com.facebook.android:com.viewpagerindicator:com.triposo.barone:com.actionbarsherlock"/>
<arg value="-A"/>
<arg file="assets"/>
</exec>
<taskdef name="buildconfig" classname="com.android.ant.BuildConfigTask"
classpath="${sdk.dir}/tools/lib/anttasks.jar"/>
<buildconfig
genFolder="gen"
package="com.actionbarsherlock"
buildType="${debug}"
previousBuildType=""/>
<buildconfig
genFolder="gen"
package="COM.YOUR.PACKAGE"
buildType="${debug}"
previousBuildType=""/>
</target>
<target name="compile" depends="clean, ivy, generate">
<mkdir dir="${out.dir}"/>
<javac destdir="${out.dir}" debug="true" includeantruntime="false">
<src path="src"/>
<src path="facebook-android-sdk/facebook/src"/>
<src path="apklibs/view-pager-indicator/src"/>
<src path="barone/src"/>
<src path="apklibs/action-bar-sherlock/src"/>
<src path="gen"/>
<classpath>
<path refid="lib.path.id"/>
<pathelement path="${android.jar}"/>
</classpath>
</javac>
<copy todir="${out.dir}">
<fileset dir="src" excludes="**/*.java"/>
<fileset dir="gen" excludes="**/*.java"/>
</copy>
</target>
<target name="apk-unsigned" depends="compile">
<!-- Prepare the .class files and the .properties files. -->
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask"
classpath="jarjar-1.1.jar"/>
<jarjar jarfile="build/app.jar" duplicate="preserve">
<fileset dir="${out.dir}"/>
<zipgroupfileset dir="libs" includes="*.jar"/>
<keep pattern="COM.YOUR.PACKAGE.**"/>
<keep pattern="com.amazonaws.**"/>
<keep pattern="com.facebook.android.**"/>
<keep pattern="com.google.android.apps.analytics.**"/>
<keep pattern="com.google.gson.GsonBuilder"/>
<keep pattern="com.google.common.base.Splitter"/>
<keep pattern="com.google.common.io.Files"/>
<keep pattern="com.google.common.base.Charsets"/>
<keep pattern="javax.annotation.Nullable"/>
<keep pattern="org.apache.commons.lang3.**"/>
<keep pattern="android.support.v4.**"/>
<!-- Required because these seem to be missing from the phone JVM
and they are used by our CursorMapper. -->
<keep pattern="javax.annotation.**"/>
<!-- From http://actionbarsherlock.com/faq.html -->
<keep pattern="com.actionbarsherlock.**"/>
<keep pattern="*Annotation*"/>
<rule pattern="com.google.common.**" result="COM.YOUR.PACKAGE.vendor.com.google.common.@1"/>
<!-- We rename this because at least "HTC Sensation XL with Beats Audio"
has a bad Gson library which we don't want to use. -->
<rule pattern="com.google.gson.**" result="COM.YOUR.PACKAGE.vendor.com.google.gson.@1"/>
</jarjar>
<!-- Convert the .class files to Dalvik byte code. -->
<exec executable="${sdk.dir}/platform-tools/dx" failonerror="true">
<arg value="--dex"/>
<arg value="--output=build/classes.dex"/>
<arg file="build/app.jar"/>
</exec>
<!-- Package the resources and the classes into an apk. -->
<taskdef name="apkbuilder" classname="com.android.ant.ApkBuilderTask"
classpath="${sdk.dir}/tools/lib/anttasks.jar"/>
<apkbuilder outfolder="."
resourcefile="build/resources.arsc"
apkfilepath="build/unsigned.apk"
verbose="false">
<dex path="build/classes.dex"/>
<sourcefolder path="${out.dir}"/>
</apkbuilder>
</target>
<!-- We need this because I use JDK 7, see the Caution in:
http://developer.android.com/guide/publishing/app-signing.html#signapp
Ant 1.8.3 allows specifying a sigalg and a digestalg, but
I don't have it yet, so we have this macro instead. -->
<macrodef name="signjarjdk7">
<attribute name="jar" />
<attribute name="signedjar" />
<attribute name="keystore" />
<attribute name="storepass" />
<attribute name="alias" />
<sequential>
<exec executable="jarsigner" failonerror="true">
<arg line="-digestalg SHA1 -sigalg MD5withRSA" />
<arg line="-keystore @{keystore} -storepass @{storepass}" />
<arg line="-signedjar "@{signedjar}"" />
<arg line=""@{jar}" @{alias}" />
</exec>
</sequential>
</macrodef>
<macrodef name="zipalign">
<attribute name="apk" />
<attribute name="optimizedapk" />
<sequential>
<exec executable="${sdk.dir}/tools/zipalign" failonerror="true">
<arg value="-f"/>
<arg value="4"/>
<arg file="@{apk}"/>
<arg file="@{optimizedapk}"/>
</exec>
</sequential>
</macrodef>
<!-- Make an apk.
See http://developer.android.com/guide/developing/building/index.html -->
<macrodef name="apk">
<attribute name="keystore"/>
<attribute name="storepass"/>
<attribute name="alias"/>
<sequential>
<antcall target="apk-unsigned"/>
<!-- Sign the apk for release. -->
<signjarjdk7
keystore="@{keystore}" storepass="@{storepass}" alias="@{alias}"
jar="build/unsigned.apk" signedjar="build/unaligned.apk"/>
<!-- Optimize the apk to improve speed. -->
<zipalign apk="build/unaligned.apk" optimizedapk="${apk.name}"/>
</sequential>
</macrodef>
<target name="release">
<property name="debug" value="false"/>
<apk keystore="keystore" storepass="${storepass}" alias="YOUR ALIAS"/>
</target>
<target name="debug">
<property name="debug" value="true"/>
<apk keystore="debug.keystore" storepass="android" alias="androiddebugkey"/>
</target>
<target name="compile.tests" depends="compile">
<mkdir dir="${out.test-classes.dir}"/>
<javac encoding="ascii" source="1.6" target="1.6" debug="true" extdirs=""
includeantruntime="false"
destdir="${out.test-classes.dir}">
<src path="test"/>
<classpath>
<pathelement path="${out.dir}"/>
<path refid="lib.path.id"/>
<fileset dir="${test.libs.dir}" includes="*.jar"/>
<pathelement path="${android.jar}"/>
</classpath>
</javac>
</target>
<target name="test" depends="compile.tests">
<mkdir dir="${basedir}/out/reports/tests"/>
<junit showoutput="true" failureproperty="junit.failure">
<formatter type="plain" usefile="false"/>
<formatter type="xml"/>
<batchtest todir="${basedir}/out/reports/tests">
<fileset dir="test">
<include name="**/*Test.java"/>
</fileset>
</batchtest>
<classpath>
<pathelement path="${out.dir}"/>
<path refid="lib.path.id"/>
<fileset dir="${test.libs.dir}" includes="*.jar"/>
<pathelement path="${android.jar}"/>
<pathelement path="${out.test-classes.dir}"/>
</classpath>
</junit>
<fail if="junit.failure" message="Unit test(s) failed. See reports!"/>
</target>
</project>