Building Scala applications targeted to the Android platform continously enrichs our developer's experience with the Android SDK. In this article we want to share a few changes we applied to the Ant build scripts in order to improve the default behavior of the build process of Android projects.
The following changes are independent from the Scala environment settings we described in our article "Targeting Scala to the Android platform".
main_rules.xml
The Ant rules file main_rules.xml is located in the
${sdk.dir}/tools/ant/ directory; it is imported by the
custom Ant task com.android.ant.SetupTask (see line 47
of file build.xml in your project directory).
Note: Android platforms prior to version 2.3 rely on the Ant rule file
ant_rules_r2.xmlwhich exists for each installed API level and is located in the${sdk.dir}/platforms/android-<X>/ant/directory.
Change 1: We set the system property
build.sysclasspath to
"ignore" in the property section of the
main_rules.xml file:
<!-- Properties --> <property name="build.sysclasspath" value="ignore" />
in order to discard the following (annoying) warning message which otherwise appears during every build:
compile:
[javac] /opt/android-sdk-linux_86/platforms/android-4/ant/ant_rules_r2.xml:265:
warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last;
set to false for repeatable builds
Note: You may alternatively set the attribue
includeAntRuntimein yourjavacAnt task. The Ant User Manual gives the following attribute description: "attributeincludeAntRuntimedefaults to yes, unlessbuild.sysclasspathis set. It is usually best to set this to false so the script's behavior is not sensitive to the environment in which it is run".
Change 2: We add the attribute
unless="rsrc.isuptodate"
to the compile target in order to prevent the
unnecessary generation of .java source files (keep in mind
that target "scala-compile"
depends on target "compile" as
described in our article "Targeting Scala to the Android platform"):
<uptodate property="rsrc.isuptodate" targetfile="${out.absolute.dir}/rsrc.complete"> <srcfiles dir="${resource.dir}" /> </uptodate> <!-- Generates the R.java file for this project's resources. --> <target name="-resource-src" depends="-dirs" unless="rsrc.isuptodate"> <echo>Generating R.java / Manifest.java from the resources...</echo> <aaptexec executable="${aapt}" command="package" verbose="${verbose}" manifest="AndroidManifest.xml" androidjar="${android.jar}" rfolder="${gen.absolute.dir}"> <res path="${resource.absolute.dir}" /> </aaptexec> <touch file="${out.absolute.dir}/rsrc.complete" verbose="false" /> </target>
Change 3: Finally, we add the element <compilerarg ..>
to the javac Ant task in
order pass additional compiler arguments:
<!-- noop argument (value may not be empty [javac bug]) --> <property name="javac.args" value="-nowarn" /> <!-- Compiles this project's .java files into .class files. --> <target name="compile" depends="-resource-src, -aidl" description="Compiles ..."> ... (skipped) <javac encoding="ascii" target="1.5" debug="true" extdirs="" destdir="${out.classes.absolute.dir}" bootclasspathref="android.target.classpath" verbose="${verbose}" classpath="${extensible.classpath}" classpathref="android.libraries.jars"> <compilerarg line="${javac.args}"/> <src path="${source.absolute.dir}" /> ... (skipped) </target>
You can then specify additional compiler arguments in your
build.properties file in order to generate detailed warning
messages, e.g.
javac.args=-deprecation -Xlint
Note: Sun's
javaccrashes if the value of thejavac.argsproperty is set to empty (that's the reason we use the default value"-nowarn"in our change); here is a simple demonstration of that issue:$ javac "" An exception has occurred in the compiler (1.6.0_20). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. java.lang.StringIndexOutOfBoundsException: String index out of range: 0 at java.lang.String.charAt(String.java:686) at com.sun.tools.javac.main.Main.processArgs(Main.java:180) at com.sun.tools.javac.main.Main.compile(Main.java:309) at com.sun.tools.javac.main.Main.compile(Main.java:279) at com.sun.tools.javac.main.Main.compile(Main.java:270) at com.sun.tools.javac.Main.compile(Main.java:69) at com.sun.tools.javac.Main.main(Main.java:54)