1<?xml version="1.0" encoding="UTF-8"?> 2<project name="" default="debug"> 3 4 <!-- 5 This build file is imported by the project build file. It contains 6 all the targets and tasks necessary to build Android projects, be they 7 regular projects, library projects, or test projects. 8 9 At the beginning of the file is a list of properties that can be overridden 10 by adding them to your build.properties (properties are immutable, so their 11 first definition sticks and is never changed). 12 13 Follows: 14 - custom task definitions, 15 - more properties (do not override those unless the whole build system is modified). 16 - macros used throughout the build, 17 - base build targets, 18 - debug-specific build targets, 19 - release-specific build targets, 20 - instrument-specific build targets, 21 - test project-specific build targets, 22 - install targets, 23 - help target 24 --> 25 26 <!-- ********** Overrideable Properties ********** --> 27 28 <!-- You can override these values in your build.xml or build.properties. 29 Overriding any other properties may result in broken build. --> 30 31 <!-- Tells adb which device to target. You can change this from the command line 32 by invoking "ant -Dadb.device.arg=-d" for device "ant -Dadb.device.arg=-e" for 33 the emulator. --> 34 <property name="adb.device.arg" value="" /> 35 36 <!-- fileset exclude patterns (space separated) to prevent 37 files inside src/ from being packaged. --> 38 <property name="android.package.excludes" value="" /> 39 40 <!-- set some properties used for filtering/override. If those weren't defined 41 before, then this will create them with empty values, which are then ignored 42 by the custom tasks receiving them. --> 43 <property name="version.code" value="" /> 44 <property name="version.name" value="" /> 45 <property name="aapt.resource.filter" value="" /> 46 47 <!-- compilation options --> 48 <property name="java.encoding" value="UTF-8" /> 49 <property name="java.target" value="1.5" /> 50 <property name="java.source" value="1.5" /> 51 52 <!-- Verbosity --> 53 <property name="verbose" value="false" /> 54 55 <!-- ********** Custom Tasks ********** --> 56 57 <!-- jar file from where the tasks are loaded --> 58 <path id="android.antlibs"> 59 <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" /> 60 </path> 61 62 <!-- Custom tasks --> 63 <taskdef name="setup" 64 classname="com.android.ant.NewSetupTask" 65 classpathref="android.antlibs" /> 66 67 <taskdef name="aapt" 68 classname="com.android.ant.AaptExecTask" 69 classpathref="android.antlibs" /> 70 71 <taskdef name="aidl" 72 classname="com.android.ant.AidlExecTask" 73 classpathref="android.antlibs" /> 74 75 <taskdef name="renderscript" 76 classname="com.android.ant.RenderScriptTask" 77 classpathref="android.antlibs" /> 78 79 <taskdef name="dex" 80 classname="com.android.ant.DexExecTask" 81 classpathref="android.antlibs" /> 82 83 <taskdef name="apkbuilder" 84 classname="com.android.ant.ApkBuilderTask" 85 classpathref="android.antlibs" /> 86 87 <taskdef name="zipalign" 88 classname="com.android.ant.ZipAlignTask" 89 classpathref="android.antlibs" /> 90 91 <taskdef name="xpath" 92 classname="com.android.ant.XPathTask" 93 classpathref="android.antlibs" /> 94 95 <taskdef name="if" 96 classname="com.android.ant.IfElseTask" 97 classpathref="android.antlibs" /> 98 99 <!-- Emma configuration --> 100 <property name="emma.dir" value="${sdk.dir}/tools/lib" /> 101 <path id="emma.lib"> 102 <pathelement location="${emma.dir}/emma.jar" /> 103 <pathelement location="${emma.dir}/emma_ant.jar" /> 104 </path> 105 <taskdef resource="emma_ant.properties" classpathref="emma.lib" /> 106 <!-- End of emma configuration --> 107 108 109 <!-- ********** Other Properties ********** --> 110 <!-- overriding these properties may break the build 111 unless the whole file is updated --> 112 113 <!-- Input directories --> 114 <property name="source.dir" value="src" /> 115 <property name="source.absolute.dir" location="${source.dir}" /> 116 <property name="gen.absolute.dir" location="gen" /> 117 <property name="resource.absolute.dir" location="res" /> 118 <property name="asset.absolute.dir" location="assets" /> 119 <property name="jar.libs.dir" value="libs" /> 120 <property name="jar.libs.absolute.dir" location="${jar.libs.dir}" /> 121 <property name="native.libs.absolute.dir" location="libs" /> 122 123 <!-- Output directories --> 124 <property name="out.dir" value="bin" /> 125 <property name="out.absolute.dir" location="${out.dir}" /> 126 <property name="out.classes.absolute.dir" location="${out.dir}/classes" /> 127 <property name="out.res.absolute.dir" location="${out.dir}/res" /> 128 129 <!-- tools location --> 130 <property name="android.tools.dir" location="${sdk.dir}/tools" /> 131 <property name="android.platform.tools.dir" location="${sdk.dir}/platform-tools" /> 132 <condition property="exe" value=".exe" else=""><os family="windows" /></condition> 133 <condition property="bat" value=".bat" else=""><os family="windows" /></condition> 134 <property name="adb" location="${android.platform.tools.dir}/adb${exe}" /> 135 <property name="zipalign" location="${android.tools.dir}/zipalign${exe}" /> 136 <property name="aidl" location="${android.platform.tools.dir}/aidl${exe}" /> 137 <property name="aapt" location="${android.platform.tools.dir}/aapt${exe}" /> 138 <property name="dx" location="${android.platform.tools.dir}/dx${bat}" /> 139 <!-- renderscript location is set by NewSetupTask since we have a choice of 140 several executables based on minSdkVersion --> 141 142 <!-- Intermediate files --> 143 <property name="dex.file.name" value="classes.dex" /> 144 <property name="intermediate.dex.file" location="${out.absolute.dir}/${dex.file.name}" /> 145 <property name="resource.package.file.name" value="${ant.project.name}.ap_" /> 146 147 <!-- Build property file --> 148 <property name="out.build.prop.file" location="${out.absolute.dir}/build.prop" /> 149 150 151 <!-- This is needed by emma as it uses multilevel verbosity instead of simple 'true' or 'false' 152 The property 'verbosity' is not user configurable and depends exclusively on 'verbose' 153 value.--> 154 <condition property="verbosity" value="verbose" else="quiet"> 155 <istrue value="${verbose}" /> 156 </condition> 157 158 <!-- properties for signing in release mode --> 159 <condition property="has.keystore"> 160 <and> 161 <isset property="key.store" /> 162 <length string="${key.store}" when="greater" length="0" /> 163 <isset property="key.alias" /> 164 </and> 165 </condition> 166 <condition property="has.password"> 167 <and> 168 <isset property="has.keystore" /> 169 <isset property="key.store.password" /> 170 <isset property="key.alias.password" /> 171 </and> 172 </condition> 173 174 <!-- properties for packaging --> 175 <property name="build.packaging.nocrunch" value="true" /> 176 177 <!-- ********** Macros ********** --> 178 179 <!-- macro to do a task on if project.is.library is false. 180 elseText attribute is displayed otherwise --> 181 <macrodef name="do-only-if-not-library"> 182 <attribute name="elseText" /> 183 <element name="task-to-do" implicit="yes" /> 184 <sequential> 185 <if condition="${project.is.library}"> 186 <else> 187 <task-to-do /> 188 </else> 189 <then> 190 <echo>@{elseText}</echo> 191 </then> 192 </if> 193 </sequential> 194 </macrodef> 195 196 <!-- macro to do a task on if manifest.hasCode is true. 197 elseText attribute is displayed otherwise --> 198 <macrodef name="do-only-if-manifest-hasCode"> 199 <attribute name="elseText" default=""/> 200 <element name="task-to-do" implicit="yes" /> 201 <sequential> 202 <if condition="${manifest.hasCode}"> 203 <then> 204 <task-to-do /> 205 </then> 206 <else> 207 <if> 208 <condition> 209 <length string="@{elseText}" trim="true" when="greater" length="0" /> 210 </condition> 211 <then> 212 <echo>@{elseText}</echo> 213 </then> 214 </if> 215 </else> 216 </if> 217 </sequential> 218 </macrodef> 219 220 221 <!-- Configurable macro, which allows to pass as parameters output directory, 222 output dex filename and external libraries to dex (optional) --> 223 <macrodef name="dex-helper"> 224 <element name="external-libs" optional="yes" /> 225 <attribute name="nolocals" default="false" /> 226 <sequential> 227 <!-- sets the primary input for dex. If a pre-dex task sets it to 228 something else this has no effect --> 229 <property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" /> 230 231 <!-- set the secondary dx input: the project (and library) jar files 232 If a pre-dex task sets it to something else this has no effect --> 233 <if> 234 <condition> 235 <isreference refid="out.dex.jar.input.ref" /> 236 </condition> 237 <else> 238 <path id="out.dex.jar.input.ref"> 239 <path refid="jar.libs.ref" /> 240 </path> 241 </else> 242 </if> 243 244 <dex executable="${dx}" 245 output="${intermediate.dex.file}" 246 nolocals="@{nolocals}" 247 verbose="${verbose}" 248 previousBuildType="${build.last.target}" 249 buildType="${build.target}"> 250 <path path="${out.dex.input.absolute.dir}"/> 251 <path refid="out.dex.jar.input.ref" /> 252 <external-libs /> 253 </dex> 254 </sequential> 255 </macrodef> 256 257 <!-- This is macro that enable passing variable list of external jar files to ApkBuilder 258 Example of use: 259 <package-helper> 260 <extra-jars> 261 <jarfolder path="my_jars" /> 262 <jarfile path="foo/bar.jar" /> 263 <jarfolder path="your_jars" /> 264 </extra-jars> 265 </package-helper> --> 266 <macrodef name="package-helper"> 267 <element name="extra-jars" optional="yes" /> 268 <sequential> 269 <apkbuilder 270 outfolder="${out.absolute.dir}" 271 resourcefile="${resource.package.file.name}" 272 apkfilepath="${out.packaged.file}" 273 debugpackaging="${build.is.packaging.debug}" 274 debugsigning="${build.is.signing.debug}" 275 verbose="${verbose}" 276 hascode="${manifest.hasCode}" 277 previousBuildType="${build.last.is.packaging.debug}/${build.last.is.signing.debug}" 278 buildType="${build.is.packaging.debug}/${build.is.signing.debug}"> 279 <dex path="${intermediate.dex.file}"/> 280 <sourcefolder path="${source.absolute.dir}"/> 281 <jarfile refid="jar.libs.ref" /> 282 <nativefolder path="${native.libs.absolute.dir}" /> 283 <nativefolder refid="project.libraries.libs" /> 284 <extra-jars/> 285 </apkbuilder> 286 </sequential> 287 </macrodef> 288 289 <!-- This is macro which zipaligns in.package and outputs it to out.package. Used by targets 290 debug, -debug-with-emma and release.--> 291 <macrodef name="zipalign-helper"> 292 <attribute name="in.package" /> 293 <attribute name="out.package" /> 294 <sequential> 295 <zipalign 296 executable="${zipalign}" 297 input="@{in.package}" 298 output="@{out.package}" 299 verbose="${verbose}" /> 300 </sequential> 301 </macrodef> 302 303 <macrodef name="run-tests-helper"> 304 <attribute name="emma.enabled" default="false" /> 305 <element name="extra-instrument-args" optional="yes" /> 306 <sequential> 307 <echo>Running tests ...</echo> 308 <exec executable="${adb}" failonerror="true"> 309 <arg line="${adb.device.arg}" /> 310 <arg value="shell" /> 311 <arg value="am" /> 312 <arg value="instrument" /> 313 <arg value="-w" /> 314 <arg value="-e" /> 315 <arg value="coverage" /> 316 <arg value="@{emma.enabled}" /> 317 <extra-instrument-args /> 318 <arg value="${manifest.package}/${test.runner}" /> 319 </exec> 320 </sequential> 321 </macrodef> 322 323 <macrodef name="record-build-key"> 324 <attribute name="key" default="false" /> 325 <attribute name="value" default="false" /> 326 <sequential> 327 <propertyfile file="${out.build.prop.file}" comment="Last build type"> 328 <entry key="@{key}" value="@{value}"/> 329 </propertyfile> 330 </sequential> 331 </macrodef> 332 333 <macrodef name="record-build-info"> 334 <sequential> 335 <record-build-key key="build.last.target" value="${build.target}" /> 336 <record-build-key key="build.last.is.instrumented" value="${build.is.instrumented}" /> 337 <record-build-key key="build.last.is.packaging.debug" value="${build.is.packaging.debug}" /> 338 <record-build-key key="build.last.is.signing.debug" value="${build.is.signing.debug}" /> 339 </sequential> 340 </macrodef> 341 342 <macrodef name="uninstall-helper"> 343 <attribute name="app.package" default="false" /> 344 <sequential> 345 <echo>Uninstalling @{app.package} from the default emulator or device...</echo> 346 <exec executable="${adb}" failonerror="true"> 347 <arg line="${adb.device.arg}" /> 348 <arg value="uninstall" /> 349 <arg value="@{app.package}" /> 350 </exec> 351 </sequential> 352 </macrodef> 353 354 <!-- ********** Build Targets ********** --> 355 356 <!-- this target simply force running -setup making 357 the project info be read. To be used as 358 ant all clean 359 to clean the main project as well as the libraries and tested project --> 360 <target name="all" depends="-setup"/> 361 362 <!-- clean target --> 363 <target name="clean" description="Removes output files created by other targets."> 364 <delete dir="${out.absolute.dir}" verbose="${verbose}" /> 365 <delete dir="${gen.absolute.dir}" verbose="${verbose}" /> 366 367 <!-- if we know about a tested project or libraries, we clean them too. This 368 will only work if the target 'all' was called first --> 369 <if condition="${project.is.test}"> 370 <then> 371 <property name="tested.project.absolute.dir" location="${tested.project.dir}" /> 372 <subant failonerror="true"> 373 <fileset dir="${tested.project.absolute.dir}" includes="build.xml" /> 374 <target name="all" /> 375 <target name="clean" /> 376 </subant> 377 </then> 378 </if> 379 380 <if> 381 <condition> 382 <isreference refid="project.libraries" /> 383 </condition> 384 <then> 385 <subant 386 buildpathref="project.libraries" 387 antfile="build.xml" 388 failonerror="true"> 389 <target name="all" /> 390 <target name="clean" /> 391 </subant> 392 </then> 393 </if> 394 </target> 395 396 <!-- generic setup --> 397 <target name="-setup"> 398 <if> 399 <condition> 400 <not><isset property="setup.done" /></not> 401 </condition> 402 <then> 403 <property name="setup.done" value="true" /> 404 <echo>Gathering info for ${ant.project.name}...</echo> 405 <!-- load project properties, resolve Android target, library dependencies 406 and set some properties with the results. 407 All property names are passed as parameters ending in -Out --> 408 <setup 409 projectTypeOut="android.project.type" 410 androidJarFileOut="android.jar" 411 androidAidlFileOut="android.aidl" 412 renderScriptExeOut="renderscript" 413 renderScriptIncludeDirOut="android.rs" 414 bootclasspathrefOut="android.target.classpath" 415 projectLibrariesRootOut="project.libraries" 416 projectLibrariesJarsOut="project.libraries.jars" 417 projectLibrariesResOut="project.libraries.res" 418 projectLibrariesPackageOut="project.libraries.package" 419 projectLibrariesLibsOut="project.libraries.libs" 420 targetApiOut="target.api" 421 /> 422 423 <!-- sets a few boolean based on android.project.type 424 to make the if task easier --> 425 <condition property="project.is.library" else="false"> 426 <equals arg1="${android.project.type}" arg2="library" /> 427 </condition> 428 <condition property="project.is.test" else="false"> 429 <equals arg1="${android.project.type}" arg2="test" /> 430 </condition> 431 432 <!-- If a test project, resolve absolute path to tested project. --> 433 <if condition="${project.is.test}"> 434 <then> 435 <property name="tested.project.absolute.dir" location="${tested.project.dir}" /> 436 </then> 437 </if> 438 </then> 439 </if> 440 </target> 441 442 <!-- Pre build setup --> 443 <target name="-build-setup" depends="-setup"> 444 445 <!-- read the previous build mode --> 446 <property file="${out.build.prop.file}" /> 447 <!-- if empty the prop won't be set, so set it to the current target 448 to provide a default value equal to the current build --> 449 <property name="build.last.target" value="${build.target}" /> 450 <!-- also set the default value for whether the build is instrumented --> 451 <property name="build.last.is.instrumented" value="${build.is.instrumented}" /> 452 <property name="build.last.is.packaging.debug" value="${build.is.packaging.debug}" /> 453 <property name="build.last.is.signing.debug" value="${build.is.signing.debug}" /> 454 455 <!-- compile the libraries if any --> 456 <if> 457 <condition> 458 <isreference refid="project.libraries" /> 459 </condition> 460 <then> 461 <echo>Building Libraries</echo> 462 <subant 463 buildpathref="project.libraries" 464 antfile="build.xml" 465 target="${build.target}" 466 failonerror="true"/> 467 <echo></echo> 468 <echo>############################################</echo> 469 <echo>**** Back to project ${ant.project.name} ****</echo> 470 <echo>############################################</echo> 471 </then> 472 </if> 473 474 <!-- compile the main project if this is a test project --> 475 <if condition="${project.is.test}"> 476 <then> 477 <!-- figure out which target must be used to build the tested project. 478 If emma is enabled, then use 'instrument' otherwise, use 'debug' --> 479 <condition property="tested.project.target" value="instrument" else="debug"> 480 <isset property="emma.enabled" /> 481 </condition> 482 483 <echo>Building tested project at ${tested.project.absolute.dir}</echo> 484 <subant target="${tested.project.target}" failonerror="true"> 485 <fileset dir="${tested.project.absolute.dir}" includes="build.xml" /> 486 </subant> 487 <echo></echo> 488 <echo>############################################</echo> 489 <echo>**** Back to project ${ant.project.name} ****</echo> 490 <echo>############################################</echo> 491 </then> 492 </if> 493 494 <!-- Value of the hasCode attribute (Application node) extracted from manifest file --> 495 <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode" 496 output="manifest.hasCode" default="true"/> 497 498 <!-- create a path with all the jar files, from the main project and the 499 libraries --> 500 <path id="jar.libs.ref"> 501 <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" /> 502 <path refid="project.libraries.jars" /> 503 </path> 504 505 <!-- special case for instrumented: if the previous build was 506 instrumented but not this one, clear out the compiled code --> 507 <if> 508 <condition> 509 <and> 510 <istrue value="${build.last.is.instrumented}" /> 511 <isfalse value="${build.is.instrumented}" /> 512 </and> 513 </condition> 514 <then> 515 <echo>Switching from instrumented to non-instrumented build.</echo> 516 <echo>Deleting previous compilation output:</echo> 517 <delete dir="${out.classes.absolute.dir}" verbose="${verbose}" /> 518 </then> 519 </if> 520 521 <echo>Creating output directories if needed...</echo> 522 <mkdir dir="${resource.absolute.dir}" /> 523 <mkdir dir="${jar.libs.absolute.dir}" /> 524 <mkdir dir="${out.absolute.dir}" /> 525 <mkdir dir="${out.res.absolute.dir}" /> 526 <do-only-if-manifest-hasCode> 527 <mkdir dir="${gen.absolute.dir}" /> 528 <mkdir dir="${out.classes.absolute.dir}" /> 529 </do-only-if-manifest-hasCode> 530 </target> 531 532 <!-- empty default pre-build target. Create a similar target in 533 your build.xml and it'll be called instead of this one. --> 534 <target name="-pre-build"/> 535 536 <!-- Code Generation: compile resources (aapt -> R.java), aidl, renderscript --> 537 <target name="-code-gen"> 538 <do-only-if-manifest-hasCode 539 elseText="hasCode = false. Skipping aidl/renderscript/R.java"> 540 <echo>----------</echo> 541 <echo>Handling aidl files...</echo> 542 <aidl executable="${aidl}" framework="${android.aidl}" 543 genFolder="${gen.absolute.dir}"> 544 <source path="${source.absolute.dir}"/> 545 </aidl> 546 547 <!-- renderscript generates resources so it must be called before aapt --> 548 <echo>----------</echo> 549 <echo>Handling RenderScript files...</echo> 550 <renderscript executable="${renderscript}" 551 framework="${android.rs}" 552 genFolder="${gen.absolute.dir}" 553 resFolder="${resource.absolute.dir}/raw" 554 targetApi="${target.api}"> 555 <source path="${source.absolute.dir}"/> 556 </renderscript> 557 558 <echo>----------</echo> 559 <echo>Handling Resources...</echo> 560 <aapt executable="${aapt}" 561 command="package" 562 verbose="${verbose}" 563 manifest="AndroidManifest.xml" 564 androidjar="${android.jar}" 565 rfolder="${gen.absolute.dir}" 566 nonConstantId="${android.library}" 567 projectLibrariesResName="project.libraries.res" 568 projectLibrariesPackageName="project.libraries.package"> 569 <res path="${resource.absolute.dir}" /> 570 </aapt> 571 </do-only-if-manifest-hasCode> 572 </target> 573 574 <!-- empty default pre-compile target. Create a similar target in 575 your build.xml and it'll be called instead of this one. --> 576 <target name="-pre-compile"/> 577 578 <!-- Compiles this project's .java files into .class files. --> 579 <target name="-compile" depends="-build-setup, -pre-build, -code-gen, -pre-compile"> 580 <do-only-if-manifest-hasCode elseText="hasCode = false. Skipping..."> 581 <!-- If android rules are used for a test project, its classpath should include 582 tested project's location --> 583 <condition property="extensible.classpath" 584 value="${tested.project.absolute.dir}/bin/classes" 585 else="."> 586 <isset property="tested.project.absolute.dir" /> 587 </condition> 588 <condition property="extensible.libs.classpath" 589 value="${tested.project.absolute.dir}/${jar.libs.dir}" 590 else="${jar.libs.dir}"> 591 <isset property="tested.project.absolute.dir" /> 592 </condition> 593 <javac encoding="${java.encoding}" 594 source="${java.source}" target="${java.target}" 595 debug="true" extdirs="" 596 destdir="${out.classes.absolute.dir}" 597 bootclasspathref="android.target.classpath" 598 verbose="${verbose}" 599 classpath="${extensible.classpath}" 600 classpathref="jar.libs.ref"> 601 <src path="${source.absolute.dir}" /> 602 <src path="${gen.absolute.dir}" /> 603 <classpath> 604 <fileset dir="${extensible.libs.classpath}" includes="*.jar" /> 605 </classpath> 606 </javac> 607 <!-- if the project is a library then we generate a jar file --> 608 <if condition="${project.is.library}"> 609 <then> 610 <echo>Creating library output jar file...</echo> 611 <property name="out.library.jar.file" location="${out.absolute.dir}/classes.jar" /> 612 <if> 613 <condition> 614 <length string="${android.package.excludes}" trim="true" when="greater" length="0" /> 615 </condition> 616 <then> 617 <echo>Custom jar packaging exclusion: ${android.package.excludes}</echo> 618 </then> 619 </if> 620 <jar destfile="${out.library.jar.file}"> 621 <fileset dir="${out.classes.absolute.dir}" excludes="**/R.class **/R$*.class"/> 622 <fileset dir="${source.absolute.dir}" excludes="**/*.java ${android.package.excludes}" /> 623 </jar> 624 </then> 625 </if> 626 627 <!-- if the project is instrumented, intrument the classes --> 628 <if condition="${build.is.instrumented}"> 629 <then> 630 <echo>Instrumenting classes from ${out.absolute.dir}/classes...</echo> 631 <!-- It only instruments class files, not any external libs --> 632 <emma enabled="true"> 633 <instr verbosity="${verbosity}" 634 mode="overwrite" 635 instrpath="${out.absolute.dir}/classes" 636 outdir="${out.absolute.dir}/classes"> 637 </instr> 638 <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from 639 user defined file --> 640 </emma> 641 </then> 642 </if> 643 </do-only-if-manifest-hasCode> 644 </target> 645 646 <!-- empty default post-compile target. Create a similar target in 647 your build.xml and it'll be called instead of this one. --> 648 <target name="-post-compile"/> 649 650 <!-- Obfuscate target 651 This is only active in release builds when proguard.config is defined 652 in default.properties. 653 654 To replace Proguard with a different obfuscation engine: 655 Override the following targets in your build.xml, before the call to <setup> 656 -release-obfuscation-check 657 Check whether obfuscation should happen, and put the result in a property. 658 -debug-obfuscation-check 659 Obfuscation should not happen. Set the same property to false. 660 -obfuscate 661 check if the property set in -debug/release-obfuscation-check is set to true. 662 If true: 663 Perform obfuscation 664 Set property out.dex.input.absolute.dir to be the output of the obfuscation 665 --> 666 <target name="-obfuscate"> 667 <if condition="${proguard.enabled}"> 668 <then> 669 <property name="obfuscate.absolute.dir" location="${out.absolute.dir}/proguard" /> 670 <property name="preobfuscate.jar.file" value="${obfuscate.absolute.dir}/original.jar" /> 671 <property name="obfuscated.jar.file" value="${obfuscate.absolute.dir}/obfuscated.jar" /> 672 <!-- input for dex will be proguard's output --> 673 <property name="out.dex.input.absolute.dir" value="${obfuscated.jar.file}" /> 674 675 <!-- Add Proguard Tasks --> 676 <property name="proguard.jar" location="${android.tools.dir}/proguard/lib/proguard.jar" /> 677 <taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="${proguard.jar}" /> 678 679 <!-- Set the android classpath Path object into a single property. It'll be 680 all the jar files separated by a platform path-separator. 681 Each path must be quoted if it contains spaces. 682 --> 683 <pathconvert property="android.libraryjars" refid="android.target.classpath"> 684 <firstmatchmapper> 685 <regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/> 686 <identitymapper/> 687 </firstmatchmapper> 688 </pathconvert> 689 690 <!-- Build a path object with all the jar files that must be obfuscated. 691 This include the project compiled source code and any 3rd party jar 692 files. --> 693 <path id="project.jars.ref"> 694 <pathelement location="${preobfuscate.jar.file}" /> 695 <path refid="jar.libs.ref" /> 696 </path> 697 <!-- Set the project jar files Path object into a single property. It'll be 698 all the jar files separated by a platform path-separator. 699 Each path must be quoted if it contains spaces. 700 --> 701 <pathconvert property="project.jars" refid="project.jars.ref"> 702 <firstmatchmapper> 703 <regexpmapper from='^([^ ]*)( .*)$$' to='"\1\2"'/> 704 <identitymapper/> 705 </firstmatchmapper> 706 </pathconvert> 707 708 <mkdir dir="${obfuscate.absolute.dir}" /> 709 <delete file="${preobfuscate.jar.file}"/> 710 <delete file="${obfuscated.jar.file}"/> 711 <jar basedir="${out.classes.absolute.dir}" 712 destfile="${preobfuscate.jar.file}" /> 713 <proguard> 714 @${proguard.config} 715 -injars ${project.jars} 716 -outjars "${obfuscated.jar.file}" 717 -libraryjars ${android.libraryjars} 718 -dump "${obfuscate.absolute.dir}/dump.txt" 719 -printseeds "${obfuscate.absolute.dir}/seeds.txt" 720 -printusage "${obfuscate.absolute.dir}/usage.txt" 721 -printmapping "${obfuscate.absolute.dir}/mapping.txt" 722 </proguard> 723 </then> 724 </if> 725 </target> 726 727 <!-- Converts this project's .class files into .dex files --> 728 <target name="-dex" depends="-compile, -post-compile, -obfuscate"> 729 <do-only-if-manifest-hasCode elseText="hasCode = false. Skipping..."> 730 <!-- only convert to dalvik bytecode is *not* a library --> 731 <do-only-if-not-library elseText="Library project: do not convert bytecode..." > 732 <!-- special case for instrumented builds: need to use no-locals and need 733 to pass in the emma jar. --> 734 <if condition="${build.is.instrumented}"> 735 <then> 736 <dex-helper nolocals="true"> 737 <external-libs> 738 <fileset file="${emma.dir}/emma_device.jar" /> 739 </external-libs> 740 </dex-helper> 741 </then> 742 <else> 743 <dex-helper /> 744 </else> 745 </if> 746 </do-only-if-not-library> 747 </do-only-if-manifest-hasCode> 748 </target> 749 750<!-- Updates the pre-processed PNG cache --> 751 <target name="-crunch"> 752 <exec executable="${aapt}" taskName="crunch"> 753 <arg value="crunch" /> 754 <arg value="-v" /> 755 <arg value="-S" /> 756 <arg path="${resource.absolute.dir}" /> 757 <arg value="-C" /> 758 <arg path="${out.res.absolute.dir}" /> 759 </exec> 760 </target> 761 762 <!-- Puts the project's resources into the output package file 763 This actually can create multiple resource package in case 764 Some custom apk with specific configuration have been 765 declared in default.properties. 766 --> 767 <target name="-package-resources" depends="-crunch"> 768 <!-- only package resources if *not* a library project --> 769 <do-only-if-not-library elseText="Library project: do not package resources..." > 770 <aapt executable="${aapt}" 771 command="package" 772 versioncode="${version.code}" 773 versionname="${version.name}" 774 debug="${build.is.packaging.debug}" 775 manifest="AndroidManifest.xml" 776 assets="${asset.absolute.dir}" 777 androidjar="${android.jar}" 778 apkfolder="${out.absolute.dir}" 779 nocrunch="${build.packaging.nocrunch}" 780 resourcefilename="${resource.package.file.name}" 781 resourcefilter="${aapt.resource.filter}" 782 projectLibrariesResName="project.libraries.res" 783 projectLibrariesPackageName="project.libraries.package" 784 previousBuildType="${build.last.target}" 785 buildType="${build.target}"> 786 <res path="${out.res.absolute.dir}" /> 787 <res path="${resource.absolute.dir}" /> 788 <!-- <nocompress /> forces no compression on any files in assets or res/raw --> 789 <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw --> 790 </aapt> 791 </do-only-if-not-library> 792 </target> 793 794 <!-- Packages the application. --> 795 <target name="-package" depends="-dex, -package-resources"> 796 <!-- only package apk if *not* a library project --> 797 <do-only-if-not-library elseText="Library project: do not package apk..." > 798 <if condition="${build.is.instrumented}"> 799 <then> 800 <package-helper> 801 <extra-jars> 802 <!-- Injected from external file --> 803 <jarfile path="${emma.dir}/emma_device.jar" /> 804 </extra-jars> 805 </package-helper> 806 </then> 807 <else> 808 <package-helper /> 809 </else> 810 </if> 811 </do-only-if-not-library> 812 </target> 813 814 <target name="-set-mode-check"> 815 <fail if="out.final.file" 816 message="Cannot run two different modes at the same time. If you are running more than one debug/release/instrument type targets, call them from different Ant calls." /> 817 </target> 818 819 <!-- ********** Debug specific targets ********** --> 820 821 <target name="-set-debug-files" depends="-set-mode-check"> 822 823 <property name="out.packaged.file" location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" /> 824 <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-debug.apk" /> 825 </target> 826 827 828 <target name="-set-debug-mode"> 829 <!-- record the current build target --> 830 <property name="build.target" value="debug" /> 831 832 <property name="build.is.instrumented" value="false" /> 833 834 <!-- whether the build is a debug build. always set. --> 835 <property name="build.is.packaging.debug" value="true" /> 836 837 <!-- signing mode: debug --> 838 <property name="build.is.signing.debug" value="true" /> 839 840 </target> 841 842 <target name="-debug-obfuscation-check"> 843 <!-- proguard is never enabled in debug mode --> 844 <property name="proguard.enabled" value="false"/> 845 </target> 846 847 <!-- Builds debug output package --> 848 <target name="-do-debug" depends="-set-debug-mode, -debug-obfuscation-check, -package"> 849 <!-- only create apk if *not* a library project --> 850 <do-only-if-not-library elseText="Library project: do not create apk..." > 851 <sequential> 852 <zipalign-helper in.package="${out.packaged.file}" out.package="${out.final.file}" /> 853 <echo>Debug Package: ${out.final.file}</echo> 854 </sequential> 855 </do-only-if-not-library> 856 </target> 857 858 <!-- Builds debug output package --> 859 <target name="debug" depends="-set-debug-files, -do-debug" 860 description="Builds the application and signs it with a debug key."> 861 <record-build-info /> 862 </target> 863 864 865 <!-- ********** Release specific targets ********** --> 866 867 <!-- called through target 'release'. Only executed if the keystore and 868 key alias are known but not their password. --> 869 <target name="-release-prompt-for-password" if="has.keystore" unless="has.password"> 870 <!-- Gets passwords --> 871 <input 872 message="Please enter keystore password (store:${key.store}):" 873 addproperty="key.store.password" /> 874 <input 875 message="Please enter password for alias '${key.alias}':" 876 addproperty="key.alias.password" /> 877 </target> 878 879 <!-- called through target 'release'. Only executed if there's no 880 keystore/key alias set --> 881 <target name="-release-nosign" unless="has.keystore"> 882 <!-- no release builds for library project --> 883 <do-only-if-not-library elseText="" > 884 <sequential> 885 <echo>No key.store and key.alias properties found in build.properties.</echo> 886 <echo>Please sign ${out.packaged.file} manually</echo> 887 <echo>and run zipalign from the Android SDK tools.</echo> 888 </sequential> 889 </do-only-if-not-library> 890 <record-build-info /> 891 </target> 892 893 <target name="-release-obfuscation-check"> 894 <condition property="proguard.enabled" value="true" else="false"> 895 <and> 896 <isset property="build.is.mode.release" /> 897 <isset property="proguard.config" /> 898 </and> 899 </condition> 900 <if condition="${proguard.enabled}"> 901 <then> 902 <!-- Secondary dx input (jar files) is empty since all the 903 jar files will be in the obfuscated jar --> 904 <path id="out.dex.jar.input.ref" /> 905 </then> 906 </if> 907 </target> 908 909 <target name="-set-release-mode" depends="-set-mode-check"> 910 <property name="out.packaged.file" location="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk" /> 911 <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-release.apk" /> 912 913 <!-- record the current build target --> 914 <property name="build.target" value="release" /> 915 916 <property name="build.is.instrumented" value="false" /> 917 918 <!-- release mode is only valid if the manifest does not explicitly 919 set debuggable to true. default is false. --> 920 <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable" 921 output="build.is.packaging.debug" default="false"/> 922 923 <!-- signing mode: release --> 924 <property name="build.is.signing.debug" value="false" /> 925 926 <if condition="${build.is.packaging.debug}"> 927 <then> 928 <echo>*************************************************</echo> 929 <echo>**** Android Manifest has debuggable=true ****</echo> 930 <echo>**** Doing DEBUG packaging with RELEASE keys ****</echo> 931 <echo>*************************************************</echo> 932 </then> 933 <else> 934 <!-- property only set in release mode. 935 Useful for if/unless attributes in target node 936 when using Ant before 1.8 --> 937 <property name="build.is.mode.release" value="true"/> 938 </else> 939 </if> 940 </target> 941 942 <!-- This runs -package-release and -release-nosign first and then runs 943 only if release-sign is true (set in -release-check, 944 called by -release-no-sign)--> 945 <target name="release" 946 depends="-set-release-mode, -release-obfuscation-check, -package, -release-prompt-for-password, -release-nosign" 947 if="has.keystore" 948 description="Builds the application. The generated apk file must be signed before 949 it is published."> 950 951 <!-- only create apk if *not* a library project --> 952 <do-only-if-not-library elseText="Library project: do not create apk..." > 953 <sequential> 954 <property name="out.unaligned.file" location="${out.absolute.dir}/${ant.project.name}-release-unaligned.apk" /> 955 956 <!-- Signs the APK --> 957 <echo>Signing final apk...</echo> 958 <signjar 959 jar="${out.packaged.file}" 960 signedjar="${out.unaligned.file}" 961 keystore="${key.store}" 962 storepass="${key.store.password}" 963 alias="${key.alias}" 964 keypass="${key.alias.password}" 965 verbose="${verbose}" /> 966 967 <!-- Zip aligns the APK --> 968 <zipalign-helper in.package="${out.unaligned.file}" 969 out.package="${out.final.file}" /> 970 <echo>Release Package: ${out.final.file}</echo> 971 </sequential> 972 </do-only-if-not-library> 973 <record-build-info /> 974 </target> 975 976 <!-- ********** Instrumented specific targets ********** --> 977 978 <!-- These targets are specific for the project under test when it 979 gets compiled by the test projects in a way that will make it 980 support emma code coverage --> 981 982 <target name="-set-instrumented-mode" depends="-set-mode-check"> 983 <property name="out.packaged.file" location="${out.absolute.dir}/${ant.project.name}-instrumented-unaligned.apk" /> 984 <property name="out.final.file" location="${out.absolute.dir}/${ant.project.name}-instrumented.apk" /> 985 986 <!-- whether the build is an instrumented build. --> 987 <property name="build.is.instrumented" value="true" /> 988 </target> 989 990 <!-- Builds instrumented output package --> 991 <target name="instrument" depends="-set-instrumented-mode, -do-debug" 992 description="Builds an instrumented packaged."> 993 <!-- only create apk if *not* a library project --> 994 <do-only-if-not-library elseText="Library project: do not create apk..." > 995 <sequential> 996 <zipalign-helper in.package="${out.packaged.file}" out.package="${out.final.file}" /> 997 <echo>Instrumented Package: ${out.final.file}</echo> 998 </sequential> 999 </do-only-if-not-library> 1000 <record-build-info /> 1001 </target> 1002 1003 <!-- ********** Test project specific targets ********** --> 1004 1005 <!-- enable code coverage --> 1006 <target name="emma"> 1007 <property name="emma.enabled" value="true" /> 1008 </target> 1009 1010 <!-- fails if the project is not a test project --> 1011 <target name="-test-project-check"> 1012 <!-- can't use project.is.test since the setup target is not run --> 1013 <if> 1014 <condition> 1015 <isset property="tested.project.dir" /> 1016 </condition> 1017 <else> 1018 <fail message="Project is not a test project." /> 1019 </else> 1020 </if> 1021 </target> 1022 1023 <!-- Installs the tested project. This make sure to install the proper package based on 1024 the value of emma.enabled --> 1025 <target name="-install-tested-project" depends="-test-project-check, -setup"> 1026 <!-- figure out which tested package to install based on emma.enabled --> 1027 <condition property="tested.project.install.target" value="installi" else="installd"> 1028 <isset property="emma.enabled" /> 1029 </condition> 1030 <subant target="${tested.project.install.target}" failonerror="true"> 1031 <fileset dir="${tested.project.absolute.dir}" includes="build.xml" /> 1032 </subant> 1033 </target> 1034 1035 <target name="test" depends="-test-project-check" 1036 description="Runs tests from the package defined in test.package property"> 1037 1038 <property name="tested.project.absolute.dir" location="${tested.project.dir}" /> 1039 1040 <property name="test.runner" value="android.test.InstrumentationTestRunner" /> 1041 1042 <!-- Application package of the tested project extracted from its manifest file --> 1043 <xpath input="${tested.project.absolute.dir}/AndroidManifest.xml" 1044 expression="/manifest/@package" output="tested.manifest.package" /> 1045 1046 <property name="emma.dump.file" 1047 value="/data/data/${tested.manifest.package}/coverage.ec" /> 1048 1049 <if condition="${emma.enabled}"> 1050 <then> 1051 <echo>WARNING: Code Coverage is currently only supported on the emulator and rooted devices.</echo> 1052 <run-tests-helper emma.enabled="true"> 1053 <extra-instrument-args> 1054 <arg value="-e" /> 1055 <arg value="coverageFile" /> 1056 <arg value="${emma.dump.file}" /> 1057 </extra-instrument-args> 1058 </run-tests-helper> 1059 <echo>Downloading coverage file into project directory...</echo> 1060 <exec executable="${adb}" failonerror="true"> 1061 <arg line="${adb.device.arg}" /> 1062 <arg value="pull" /> 1063 <arg value="${emma.dump.file}" /> 1064 <arg value="coverage.ec" /> 1065 </exec> 1066 <echo>Extracting coverage report...</echo> 1067 <emma> 1068 <report sourcepath="${tested.project.absolute.dir}/${source.dir}" 1069 verbosity="${verbosity}"> 1070 <!-- TODO: report.dir or something like should be introduced if necessary --> 1071 <infileset dir="."> 1072 <include name="coverage.ec" /> 1073 <include name="coverage.em" /> 1074 </infileset> 1075 <!-- TODO: reports in other, indicated by user formats --> 1076 <html outfile="coverage.html" /> 1077 </report> 1078 </emma> 1079 <echo>Cleaning up temporary files...</echo> 1080 <delete file="coverage.ec" /> 1081 <delete file="coverage.em" /> 1082 <echo>Saving the report file in ${basedir}/coverage/coverage.html</echo> 1083 </then> 1084 <else> 1085 <run-tests-helper /> 1086 </else> 1087 </if> 1088 </target> 1089 1090 1091 <!-- ********** Install/uninstall specific targets ********** --> 1092 1093 <target name="install" 1094 description="Installs the newly build package. Must be used in conjunction with a build target 1095 (debug/release/instrument). If the application was previously installed, the application 1096 is reinstalled if the signature matches." > 1097 <!-- only do install if *not* a library project --> 1098 <do-only-if-not-library elseText="Library project: nothing to install!" > 1099 <if> 1100 <condition> 1101 <isset property="out.final.file" /> 1102 </condition> 1103 <then> 1104 <if> 1105 <condition> 1106 <resourceexists> 1107 <file file="${out.final.file}"/> 1108 </resourceexists> 1109 </condition> 1110 <then> 1111 <echo>Installing ${out.final.file} onto default emulator or device...</echo> 1112 <exec executable="${adb}" failonerror="true"> 1113 <arg line="${adb.device.arg}" /> 1114 <arg value="install" /> 1115 <arg value="-r" /> 1116 <arg path="${out.final.file}" /> 1117 </exec> 1118 </then> 1119 <else> 1120 <fail message="File {out.final.file} does not exist." /> 1121 </else> 1122 </if> 1123 </then> 1124 <else> 1125 <echo>Install file not specified.</echo> 1126 <echo></echo> 1127 <echo>'ant install' now requires the build target to be specified as well.</echo> 1128 <echo></echo> 1129 <echo></echo> 1130 <echo> ant debug install</echo> 1131 <echo> ant release install</echo> 1132 <echo> ant instrument install</echo> 1133 <echo>This will build the given package and install it.</echo> 1134 <echo></echo> 1135 <echo>Alternatively, you can use</echo> 1136 <echo> ant installd</echo> 1137 <echo> ant installr</echo> 1138 <echo> ant installi</echo> 1139 <echo> ant installt</echo> 1140 <echo>to only install an existing package (this will not rebuild the package.)</echo> 1141 <fail /> 1142 </else> 1143 </if> 1144 </do-only-if-not-library> 1145 </target> 1146 1147 <target name="installd" depends="-set-debug-files, install" 1148 description="Installs (only) the debug package." /> 1149 <target name="installr" depends="-set-release-mode, install" 1150 description="Installs (only) the release package." /> 1151 <target name="installi" depends="-set-instrumented-mode, install" 1152 description="Installs (only) the instrumented package." /> 1153 <target name="installt" depends="-install-tested-project, installd" 1154 description="Installs (only) the test and tested packages." /> 1155 1156 1157 <!-- Uninstalls the package from the default emulator/device --> 1158 <target name="uninstall" 1159 description="Uninstalls the application from a running emulator or device."> 1160 <!-- Name of the application package extracted from manifest file --> 1161 <xpath input="AndroidManifest.xml" expression="/manifest/@package" 1162 output="manifest.package" /> 1163 1164 <if> 1165 <condition> 1166 <isset property="manifest.package" /> 1167 </condition> 1168 <then> 1169 <uninstall-helper app.package="${manifest.package}" /> 1170 </then> 1171 <else> 1172 <echo>Could not find application package in manifest. Cannot run 'adb uninstall'.</echo> 1173 </else> 1174 </if> 1175 1176 <if condition="${project.is.test}"> 1177 <then> 1178 <property name="tested.project.absolute.dir" location="${tested.project.dir}" /> 1179 1180 <!-- Application package of the tested project extracted from its manifest file --> 1181 <xpath input="${tested.project.absolute.dir}/AndroidManifest.xml" 1182 expression="/manifest/@package" output="tested.manifest.package" /> 1183 <if> 1184 <condition> 1185 <isset property="tested.manifest.package" /> 1186 </condition> 1187 <then> 1188 <uninstall-helper app.package="${tested.manifest.package}" /> 1189 </then> 1190 <else> 1191 <echo>Could not find tested application package in manifest. Cannot run 'adb uninstall'.</echo> 1192 </else> 1193 </if> 1194 </then> 1195 </if> 1196 1197 </target> 1198 1199 1200 <target name="help"> 1201 <!-- displays starts at col 13 1202 |13 80| --> 1203 <echo>Android Ant Build. Available targets:</echo> 1204 <echo> help: Displays this help.</echo> 1205 <echo> clean: Removes output files created by other targets.</echo> 1206 <echo> The 'all' target can be used to clean dependencies</echo> 1207 <echo> (tested projects and libraries)at the same time</echo> 1208 <echo> using: 'ant all clean'</echo> 1209 <echo> debug: Builds the application and signs it with a debug key.</echo> 1210 <echo> release: Builds the application. The generated apk file must be</echo> 1211 <echo> signed before it is published.</echo> 1212 <echo> instrument:Builds an instrumented package and signs it with a</echo> 1213 <echo> debug key.</echo> 1214 <echo> test: Runs the tests. Project must be a test project and</echo> 1215 <echo> must have been built. Typical usage would be:</echo> 1216 <echo> ant [emma] debug installt test</echo> 1217 <echo> emma: Transiently enables code coverage for subsequent</echo> 1218 <echo> targets.</echo> 1219 <echo> install: Installs the newly build package. Must either be used</echo> 1220 <echo> in conjunction with a build target (debug/release/</echo> 1221 <echo> instrument) or with the proper suffix indicating</echo> 1222 <echo> which package to install (see below).</echo> 1223 <echo> If the application was previously installed, the</echo> 1224 <echo> application is reinstalled if the signature matches.</echo> 1225 <echo> installd: Installs (only) the debug package.</echo> 1226 <echo> installr: Installs (only) the release package.</echo> 1227 <echo> installi: Installs (only) the instrumented package.</echo> 1228 <echo> installt: Installs (only) the test and tested packages.</echo> 1229 <echo> uninstall: Uninstalls the application from a running emulator or</echo> 1230 <echo> device.</echo> 1231 </target> 1232</project> 1233