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.xml
which 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
includeAntRuntime
in yourjavac
Ant task. The Ant User Manual gives the following attribute description: "attributeincludeAntRuntime
defaults to yes, unlessbuild.sysclasspath
is 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
javac
crashes if the value of thejavac.args
property 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)