Home | History | Annotate | Download | only in ant
      1 <?xml version="1.0" encoding="UTF-8"?>
      2 <project name="android_rules" default="debug">
      3 
      4     <!--
      5         This rules file is meant to be imported by the custom Ant task:
      6             com.android.ant.SetupTask
      7 
      8         The following properties are put in place by the importing task:
      9             android.jar, android.aidl, aapt, aidl, and dx
     10 
     11         Additionnaly, the task sets up the following classpath reference:
     12             android.target.classpath
     13         This is used by the compiler task as the boot classpath.
     14     -->
     15 
     16     <!-- Custom tasks -->
     17     <taskdef name="aapt"
     18         classname="com.android.ant.AaptExecLoopTask"
     19         classpathref="android.antlibs" />
     20 
     21     <taskdef name="aidl"
     22         classname="com.android.ant.AidlExecTask"
     23         classpathref="android.antlibs" />
     24 
     25     <taskdef name="apkbuilder"
     26         classname="com.android.ant.ApkBuilderTask"
     27         classpathref="android.antlibs" />
     28 
     29     <taskdef name="xpath"
     30         classname="com.android.ant.XPathTask"
     31         classpathref="android.antlibs" />
     32 
     33     <taskdef name="if"
     34         classname="com.android.ant.IfElseTask"
     35         classpathref="android.antlibs" />
     36 
     37     <!-- Properties -->
     38 
     39     <!-- Tells adb which device to target. You can change this from the command line
     40          by invoking "ant -Dadb.device.arg=-d" for device "ant -Dadb.device.arg=-e" for
     41          the emulator. -->
     42     <property name="adb.device.arg" value="" />
     43 
     44     <property name="android.tools.dir" location="${sdk.dir}/tools" />
     45     <!-- Name of the application package extracted from manifest file -->
     46     <xpath input="AndroidManifest.xml" expression="/manifest/@package"
     47                 output="manifest.package" />
     48     <!-- Value of the debuggable attribute (Application node) extracted from manifest file -->
     49     <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable"
     50                 output="manifest.debuggable" default="false"/>
     51     <!-- Value of the debuggable attribute (Application node) extracted from manifest file -->
     52     <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode"
     53                 output="manifest.hasCode" default="true"/>
     54 
     55     <!-- Input directories -->
     56     <property name="source.dir" value="src" />
     57     <property name="source.absolute.dir" location="${source.dir}" />
     58     <property name="gen.dir" value="gen" />
     59     <property name="gen.absolute.dir" location="${gen.dir}" />
     60     <property name="resource.dir" value="res" />
     61     <property name="resource.absolute.dir" location="${resource.dir}" />
     62     <property name="asset.dir" value="assets" />
     63     <property name="asset.absolute.dir" location="${asset.dir}" />
     64 
     65     <!-- Directory for the third party java libraries -->
     66     <property name="external.libs.dir" value="libs" />
     67     <property name="external.libs.absolute.dir" location="${external.libs.dir}" />
     68 
     69     <!-- Directory for the native libraries -->
     70     <property name="native.libs.dir" value="libs" />
     71     <property name="native.libs.absolute.dir" location="${native.libs.dir}" />
     72 
     73     <!-- Output directories -->
     74     <property name="out.dir" value="bin" />
     75     <property name="out.absolute.dir" location="${out.dir}" />
     76     <property name="out.classes.dir" value="${out.absolute.dir}/classes" />
     77     <property name="out.classes.absolute.dir" location="${out.classes.dir}" />
     78     <property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />
     79 
     80     <!-- Intermediate files -->
     81     <property name="dex.file.name" value="classes.dex" />
     82     <property name="intermediate.dex.file"
     83                   location="${out.absolute.dir}/${dex.file.name}" />
     84     <property name="resource.package.file.name"
     85                   value="${ant.project.name}.ap_" />
     86 
     87     <!-- The final package file to generate
     88          These can be overridden by setting them earlier to
     89          different values -->
     90     <property name="out.debug.unaligned.file"
     91                   location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" />
     92     <property name="out.debug.file"
     93                   location="${out.absolute.dir}/${ant.project.name}-debug.apk" />
     94 
     95     <property name="out.unsigned.file.name"
     96                   value="${ant.project.name}-unsigned.apk" />
     97     <property name="out.unsigned.file"
     98                   location="${out.absolute.dir}/${out.unsigned.file.name}" />
     99 
    100     <property name="out.unaligned.file.name"
    101                   value="${ant.project.name}-unaligned.apk" />
    102     <property name="out.unaligned.file"
    103                   location="${out.absolute.dir}/${out.unaligned.file.name}" />
    104 
    105     <property name="out.release.file.name"
    106                   value="${ant.project.name}-release.apk" />
    107     <property name="out.release.file"
    108                   location="${out.absolute.dir}/${out.release.file.name}" />
    109 
    110     <!-- set some properties used for filtering/override. If those weren't defined
    111          before, then this will create them with empty values, which are then ignored
    112          by the custom tasks receiving them. -->
    113     <property name="version.code" value="" />
    114     <property name="aapt.resource.filter" value="" />
    115     <property name="filter.abi" value="" />
    116 
    117     <!-- Verbosity -->
    118     <property name="verbose" value="false" />
    119     <!-- This is needed by emma as it uses multilevel verbosity instead of simple 'true' or 'false'
    120          The property 'verbosity' is not user configurable and depends exclusively on 'verbose'
    121          value.-->
    122     <condition property="verbosity" value="verbose" else="quiet">
    123         <istrue value="${verbose}" />
    124     </condition>
    125     <!-- This is needed to switch verbosity of zipalign. Depends exclusively on 'verbose'
    126          -->
    127     <condition property="v.option" value="-v" else="">
    128         <istrue value="${verbose}" />
    129     </condition>
    130     <!-- This is needed to switch verbosity of dx. Depends exclusively on 'verbose' -->
    131     <condition property="verbose.option" value="--verbose" else="">
    132         <istrue value="${verbose}" />
    133     </condition>
    134 
    135     <!-- properties for signing in release mode -->
    136     <condition property="has.keystore">
    137         <and>
    138             <isset property="key.store" />
    139             <length string="${key.store}" when="greater" length="0" />
    140             <isset property="key.alias" />
    141         </and>
    142     </condition>
    143     <condition property="has.password">
    144         <and>
    145             <isset property="has.keystore" />
    146             <isset property="key.store.password" />
    147             <isset property="key.alias.password" />
    148         </and>
    149     </condition>
    150 
    151     <!-- Tools -->
    152     <condition property="exe" value=".exe" else=""><os family="windows" /></condition>
    153     <property name="adb" location="${android.tools.dir}/adb${exe}" />
    154     <property name="zipalign" location="${android.tools.dir}/zipalign${exe}" />
    155 
    156     <!-- Emma configuration -->
    157     <property name="emma.dir" value="${sdk.dir}/tools/lib" />
    158         <path id="emma.lib">
    159             <pathelement location="${emma.dir}/emma.jar" />
    160             <pathelement location="${emma.dir}/emma_ant.jar" />
    161         </path>
    162     <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
    163     <!-- End of emma configuration -->
    164 
    165     <!-- Macros -->
    166 
    167     <!-- Configurable macro, which allows to pass as parameters output directory,
    168          output dex filename and external libraries to dex (optional) -->
    169     <macrodef name="dex-helper">
    170        <element name="external-libs" optional="yes" />
    171        <element name="extra-parameters" optional="yes" />
    172        <sequential>
    173          <echo>Converting compiled files and external libraries into ${intermediate.dex.file}...</echo>
    174          <apply executable="${dx}" failonerror="true" parallel="true">
    175              <arg value="--dex" />
    176              <arg value="--output=${intermediate.dex.file}" />
    177              <extra-parameters />
    178              <arg line="${verbose.option}" />
    179              <arg path="${out.dex.input.absolute.dir}" />
    180              <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
    181              <path refid="android.libraries.jars" />
    182              <external-libs />
    183          </apply>
    184        </sequential>
    185     </macrodef>
    186 
    187     <!-- This is macro that enable passing variable list of external jar files to ApkBuilder
    188          Example of use:
    189          <package-helper sign.package="true" output.filepath="/path/to/foo.apk">
    190              <extra-jars>
    191                 <jarfolder path="my_jars" />
    192                 <jarfile path="foo/bar.jar" />
    193                 <jarfolder path="your_jars" />
    194              </extra-jars>
    195          </package-helper> -->
    196     <macrodef name="package-helper">
    197         <attribute name="sign.package" />
    198         <attribute name="output.filepath" />
    199         <element name="extra-jars" optional="yes" />
    200         <sequential>
    201             <apkbuilder
    202                     outfolder="${out.absolute.dir}"
    203                     resourcefile="${resource.package.file.name}"
    204                     apkfilepath="@{output.filepath}"
    205                     signed="@{sign.package}"
    206                     debug="${manifest.debuggable}"
    207                     abifilter="${filter.abi}"
    208                     verbose="${verbose}"
    209                     hascode="${manifest.hasCode}">
    210                 <dex path="${intermediate.dex.file}"/>
    211                 <sourcefolder path="${source.absolute.dir}"/>
    212                 <sourcefolder refid="android.libraries.src"/>
    213                 <jarfolder path="${external.libs.absolute.dir}" />
    214                 <jarfolder refid="android.libraries.libs" />
    215                 <nativefolder path="${native.libs.absolute.dir}" />
    216                 <nativefolder refid="android.libraries.libs" />
    217                 <extra-jars/>
    218             </apkbuilder>
    219         </sequential>
    220     </macrodef>
    221 
    222     <!-- This is macro which zipaligns in.package and outputs it to out.package. Used by targets
    223          debug, -debug-with-emma and release.-->
    224     <macrodef name="zipalign-helper">
    225         <attribute name="in.package" />
    226         <attribute name="out.package" />
    227         <sequential>
    228             <echo>Running zip align on final apk...</echo>
    229             <exec executable="${zipalign}" failonerror="true">
    230                 <arg line="${v.option}" />
    231                 <arg value="-f" />
    232                 <arg value="4" />
    233                 <arg path="@{in.package}" />
    234                 <arg path="@{out.package}" />
    235             </exec>
    236         </sequential>
    237     </macrodef>
    238 
    239     <!-- This is macro used only for sharing code among two targets, -install and
    240          -install-with-emma which do exactly the same but differ in dependencies -->
    241     <macrodef name="install-helper">
    242         <sequential>
    243             <echo>Installing ${out.debug.file} onto default emulator or device...</echo>
    244             <exec executable="${adb}" failonerror="true">
    245                 <arg line="${adb.device.arg}" />
    246                 <arg value="install" />
    247                 <arg value="-r" />
    248                 <arg path="${out.debug.file}" />
    249             </exec>
    250         </sequential>
    251     </macrodef>
    252 
    253     <!-- Rules -->
    254 
    255     <!-- Creates the output directories if they don't exist yet. -->
    256     <target name="-dirs">
    257         <echo>Creating output directories if needed...</echo>
    258         <mkdir dir="${resource.absolute.dir}" />
    259         <mkdir dir="${external.libs.absolute.dir}" />
    260         <mkdir dir="${out.absolute.dir}" />
    261         <if condition="${manifest.hasCode}">
    262             <then>
    263                 <mkdir dir="${gen.absolute.dir}" />
    264                 <mkdir dir="${out.classes.absolute.dir}" />
    265             </then>
    266         </if>
    267     </target>
    268 
    269     <!-- empty default pre-build target. Create a similar target in
    270          your build.xml and it'll be called instead of this one. -->
    271     <target name="-pre-build"/>
    272 
    273     <!-- Generates the R.java file for this project's resources. -->
    274     <target name="-resource-src" depends="-dirs, -pre-build">
    275         <if condition="${manifest.hasCode}">
    276             <then>
    277                 <echo>Generating R.java / Manifest.java from the resources...</echo>
    278                 <aapt executable="${aapt}"
    279                         command="package"
    280                         verbose="${verbose}"
    281                         manifest="AndroidManifest.xml"
    282                         androidjar="${android.jar}"
    283                         rfolder="${gen.absolute.dir}">
    284                     <res path="${resource.absolute.dir}" />
    285                 </aapt>
    286             </then>
    287             <else>
    288                 <echo>hasCode = false. Skipping...</echo>
    289             </else>
    290         </if>
    291     </target>
    292 
    293     <!-- Generates java classes from .aidl files. -->
    294     <target name="-aidl" depends="-dirs">
    295         <if condition="${manifest.hasCode}">
    296             <then>
    297                 <echo>Compiling aidl files into Java classes...</echo>
    298                 <aidl executable="${aidl}" framework="${android.aidl}"
    299                         genFolder="${gen.absolute.dir}">
    300                     <source path="${source.absolute.dir}"/>
    301                     <source refid="android.libraries.src"/>
    302                 </aidl>
    303             </then>
    304             <else>
    305                 <echo>hasCode = false. Skipping...</echo>
    306             </else>
    307         </if>
    308     </target>
    309 
    310     <!-- empty default pre-compile target. Create a similar target in
    311          your build.xml and it'll be called instead of this one. -->
    312     <target name="-pre-compile"/>
    313 
    314     <!-- Compiles this project's .java files into .class files. -->
    315     <target name="compile" depends="-resource-src, -aidl, -pre-compile"
    316                 description="Compiles project's .java files into .class files">
    317         <if condition="${manifest.hasCode}">
    318             <then>
    319                 <!-- If android rules are used for a test project, its classpath should include
    320                      tested project's location -->
    321                 <condition property="extensible.classpath"
    322                         value="${tested.project.absolute.dir}/bin/classes"
    323                         else=".">
    324                     <isset property="tested.project.absolute.dir" />
    325                 </condition>
    326                 <condition property="extensible.libs.classpath"
    327                         value="${tested.project.absolute.dir}/libs"
    328                         else="./libs">
    329                     <isset property="tested.project.absolute.dir" />
    330                 </condition>
    331                 <javac encoding="ascii" target="1.5" debug="true" extdirs=""
    332                         destdir="${out.classes.absolute.dir}"
    333                         bootclasspathref="android.target.classpath"
    334                         verbose="${verbose}"
    335                         classpath="${extensible.classpath}"
    336                         classpathref="android.libraries.jars">
    337                     <src path="${source.absolute.dir}" />
    338                     <src path="${gen.absolute.dir}" />
    339                     <src refid="android.libraries.src" />
    340                     <classpath>
    341                         <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
    342                         <fileset dir="${extensible.libs.classpath}" includes="*.jar" />
    343                     </classpath>
    344                 </javac>
    345             </then>
    346             <else>
    347                 <echo>hasCode = false. Skipping...</echo>
    348             </else>
    349         </if>
    350     </target>
    351 
    352     <!-- empty default post-compile target. Create a similar target in
    353          your build.xml and it'll be called instead of this one. -->
    354     <target name="-post-compile"/>
    355 
    356     <!-- Converts this project's .class files into .dex files -->
    357     <target name="-dex" depends="compile, -post-compile"
    358             unless="do.not.compile">
    359         <if condition="${manifest.hasCode}">
    360             <then>
    361                 <dex-helper />
    362             </then>
    363             <else>
    364                 <echo>hasCode = false. Skipping...</echo>
    365             </else>
    366         </if>
    367     </target>
    368 
    369     <!-- Puts the project's resources into the output package file
    370          This actually can create multiple resource package in case
    371          Some custom apk with specific configuration have been
    372          declared in default.properties.
    373          -->
    374     <target name="-package-resources">
    375         <echo>Packaging resources</echo>
    376         <aapt executable="${aapt}"
    377                 command="package"
    378                 versioncode="${version.code}"
    379                 manifest="AndroidManifest.xml"
    380                 assets="${asset.absolute.dir}"
    381                 androidjar="${android.jar}"
    382                 apkfolder="${out.absolute.dir}"
    383                 resourcefilename="${resource.package.file.name}"
    384                 resourcefilter="${aapt.resource.filter}">
    385             <res path="${resource.absolute.dir}" />
    386             <!-- <nocompress /> forces no compression on any files in assets or res/raw -->
    387             <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
    388         </aapt>
    389     </target>
    390 
    391     <!-- Packages the application and sign it with a debug key. -->
    392     <target name="-package-debug-sign" depends="-dex, -package-resources">
    393         <package-helper
    394                 sign.package="true"
    395                 output.filepath="${out.debug.unaligned.file}" />
    396     </target>
    397 
    398     <!-- Packages the application without signing it. -->
    399     <target name="-package-release" depends="-dex, -package-resources">
    400         <package-helper
    401                 sign.package="false"
    402                 output.filepath="${out.unsigned.file}"/>
    403     </target>
    404 
    405     <target name="-compile-tested-if-test" if="tested.project.dir" unless="do.not.compile.again">
    406        <subant target="compile">
    407             <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
    408        </subant>
    409     </target>
    410 
    411     <!-- Builds debug output package, provided all the necessary files are already dexed -->
    412     <target name="debug" depends="-compile-tested-if-test, -package-debug-sign"
    413                 description="Builds the application and signs it with a debug key.">
    414         <zipalign-helper in.package="${out.debug.unaligned.file}"
    415                                    out.package="${out.debug.file}" />
    416         <echo>Debug Package: ${out.debug.file}</echo>
    417     </target>
    418 
    419     <!-- called through target 'release'. Only executed if the keystore and
    420          key alias are known but not their password. -->
    421     <target name="-release-prompt-for-password" if="has.keystore" unless="has.password">
    422         <!-- Gets passwords -->
    423         <input
    424                 message="Please enter keystore password (store:${key.store}):"
    425                 addproperty="key.store.password" />
    426         <input
    427                 message="Please enter password for alias '${key.alias}':"
    428                 addproperty="key.alias.password" />
    429     </target>
    430 
    431     <!-- called through target 'release'. Only executed if there's no
    432          keystore/key alias set -->
    433     <target name="-release-nosign" unless="has.keystore">
    434         <echo>No key.store and key.alias properties found in build.properties.</echo>
    435         <echo>Please sign ${out.unsigned.file} manually</echo>
    436         <echo>and run zipalign from the Android SDK tools.</echo>
    437     </target>
    438 
    439     <target name="-set-release-mode">
    440         <property name="build.mode.release" value="true"/>
    441     </target>
    442 
    443     <!-- This runs -package-release and -release-nosign first and then runs
    444          only if release-sign is true (set in -release-check,
    445          called by -release-no-sign)-->
    446     <target name="release"
    447                 depends="-set-release-mode, -package-release, -release-prompt-for-password, -release-nosign"
    448                 if="has.keystore"
    449                 description="Builds the application. The generated apk file must be signed before
    450                             it is published.">
    451         <!-- Signs the APK -->
    452         <echo>Signing final apk...</echo>
    453         <signjar
    454                 jar="${out.unsigned.file}"
    455                 signedjar="${out.unaligned.file}"
    456                 keystore="${key.store}"
    457                 storepass="${key.store.password}"
    458                 alias="${key.alias}"
    459                 keypass="${key.alias.password}"
    460                 verbose="${verbose}" />
    461 
    462         <!-- Zip aligns the APK -->
    463         <zipalign-helper in.package="${out.unaligned.file}"
    464                                    out.package="${out.release.file}" />
    465         <echo>Release Package: ${out.release.file}</echo>
    466     </target>
    467 
    468     <target name="install" depends="debug"
    469                 description="Installs/reinstalls the debug package onto a running
    470                             emulator or device. If the application was previously installed,
    471                             the signatures must match." >
    472         <install-helper />
    473     </target>
    474 
    475     <target name="-uninstall-check">
    476         <condition property="uninstall.run">
    477            <isset property="manifest.package" />
    478         </condition>
    479     </target>
    480 
    481     <target name="-uninstall-error" depends="-uninstall-check" unless="uninstall.run">
    482         <echo>Unable to run 'ant uninstall', manifest.package property is not defined.
    483         </echo>
    484     </target>
    485 
    486     <!-- Uninstalls the package from the default emulator/device -->
    487     <target name="uninstall" depends="-uninstall-error" if="uninstall.run"
    488                 description="Uninstalls the application from a running emulator or device.">
    489         <echo>Uninstalling ${manifest.package} from the default emulator or device...</echo>
    490         <exec executable="${adb}" failonerror="true">
    491             <arg line="${adb.device.arg}" />
    492             <arg value="uninstall" />
    493             <arg value="${manifest.package}" />
    494         </exec>
    495     </target>
    496 
    497     <target name="clean" description="Removes output files created by other targets.">
    498         <delete dir="${out.absolute.dir}" verbose="${verbose}" />
    499         <delete dir="${gen.absolute.dir}" verbose="${verbose}" />
    500     </target>
    501 
    502     <!-- Targets for code-coverage measurement purposes, invoked from external file -->
    503 
    504     <!-- Emma-instruments tested project classes (compiles the tested project if necessary)
    505              and writes instrumented classes to ${instrumentation.absolute.dir}/classes -->
    506     <target name="-emma-instrument" depends="compile">
    507         <echo>Instrumenting classes from ${out.absolute.dir}/classes...</echo>
    508         <!-- It only instruments class files, not any external libs -->
    509         <emma enabled="true">
    510             <instr verbosity="${verbosity}"
    511                    mode="overwrite"
    512                    instrpath="${out.absolute.dir}/classes"
    513                    outdir="${out.absolute.dir}/classes">
    514             </instr>
    515             <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from
    516                  user defined file -->
    517         </emma>
    518     </target>
    519 
    520     <target name="-dex-instrumented" depends="-emma-instrument">
    521        <dex-helper>
    522           <extra-parameters>
    523             <arg value="--no-locals" />
    524           </extra-parameters>
    525           <external-libs>
    526             <fileset file="${emma.dir}/emma_device.jar" />
    527           </external-libs>
    528        </dex-helper>
    529     </target>
    530 
    531     <!-- Invoked from external files for code coverage purposes -->
    532     <target name="-package-with-emma" depends="-dex-instrumented, -package-resources">
    533         <package-helper
    534                 sign.package="true"
    535                 output.filepath="${out.debug.unaligned.file}">
    536             <extra-jars>
    537                 <!-- Injected from external file -->
    538                 <jarfile path="${emma.dir}/emma_device.jar" />
    539             </extra-jars>
    540         </package-helper>
    541     </target>
    542 
    543     <target name="-debug-with-emma" depends="-package-with-emma">
    544         <zipalign-helper in.package="${out.debug.unaligned.file}"
    545                                    out.package="${out.debug.file}" />
    546     </target>
    547 
    548     <target name="-install-with-emma" depends="-debug-with-emma">
    549         <install-helper />
    550     </target>
    551 
    552     <!-- End of targets for code-coverage measurement purposes -->
    553 
    554     <target name="help">
    555         <!-- displays starts at col 13
    556               |13                                                              80| -->
    557         <echo>Android Ant Build. Available targets:</echo>
    558         <echo>   help:      Displays this help.</echo>
    559         <echo>   clean:     Removes output files created by other targets.</echo>
    560         <echo>   compile:   Compiles project's .java files into .class files.</echo>
    561         <echo>   debug:     Builds the application and signs it with a debug key.</echo>
    562         <echo>   release:   Builds the application. The generated apk file must be</echo>
    563         <echo>              signed before it is published.</echo>
    564         <echo>   install:   Installs/reinstalls the debug package onto a running</echo>
    565         <echo>              emulator or device.</echo>
    566         <echo>              If the application was previously installed, the</echo>
    567         <echo>              signatures must match.</echo>
    568         <echo>   uninstall: Uninstalls the application from a running emulator or</echo>
    569         <echo>              device.</echo>
    570     </target>
    571 </project>
    572