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