How to BUILD a 4K game.

I thought it might be helpful to people who have never used Ant before to show a build script that can make shrinking your jar much easier. With the click of a button, you can compile, obfuscate, unzip and rezip from an Ant build file. This will also make it easier to experiment better with each option.


<project name="Asteroids4k" default="compile" basedir=".">
    <taskdef resource="proguard/ant/task.properties" classpath="C:/Apps/Programming/Java/proguard3.4/lib/proguard.jar" />
    <taskdef name="jarg" classname="jarg.JargTask" classpath="C:/Apps/Programming/Java/jarg/jarg.jar" />

    <description>
        Ant build script for Asteroids, Java 4K entry
    </description>

    <!-- Global properties for this script -->
    <property environment="env" />
    <property name="j4k.root" location="${basedir}" />
    <property name="j4k.src" location="${j4k.root}/src" />
    <property name="j4k.bin" location="${j4k.root}/bin" />
    <property name="j4k.dist" location="${j4k.root}/dist" />

    <target name="init">
        <echo>${ant.version}</echo>
        <!-- Creates a time stamp -->
        <tstamp>
            <format property="timestamp" pattern="yyyyMMddHHmmss" />
        </tstamp>
        <!-- Create the classes directory structure -->
        <mkdir dir="${j4k.bin}" />
        <mkdir dir="${j4k.dist}" />
    </target>

    <target name="compile" depends="init" description="compiles all source files">
        <!-- Compile the java code from ${j4k.src} into ${bin} -->
        <javac destdir="${j4k.bin}" debug="off" deprecation="off">
            <src path="${j4k.src}" />
            <include name="**/*.java" />
        </javac>
    </target>

    <target name="recompile" depends="clean, compile" description="rebuilds the project" />

    <target name="clean" description="deletes classes and archive directories">
        <!-- Delete the output directory trees -->
        <delete dir="${j4k.bin}" />
        <delete dir="${j4k.dist}" />
    </target>

    <target name="build" depends="_rezip" description="deletes classes and archive directories">
    </target>

    <target name="build_2" depends="_obfuscate" description="deletes classes and archive directories">
    </target>

    <target name="rebuild" depends="clean, build" description="rebuilds the project" />

    <target name="_package_jar" depends="compile" description="generate the jar file">
        <zip destfile="${j4k.dist}/Asteroids4Kpre.jar" compress="yes">
            <fileset dir="${j4k.bin}">
                <include name="*.*" />
                <include name="*" />
            </fileset>
        </zip>
    </target>

    <target name="_re_package_jar" depends="clean, _package_jar" description="generate the jar file">
        <zip destfile="${j4k.dist}/Asteroids4Kpre.jar">
            <fileset dir="${j4k.bin}">
                <include name="*.*" />
                <include name="*" />
            </fileset>
        </zip>
    </target>

    <target name="_obfuscate" depends="_rezip" description="obfuscate/compress classes">
        <proguard verbose="true">
			-keep public class A {
				public static void main(java.lang.String[]);
			}
			<injar path="${j4k.dist}/Asteroids4Kpre.jar" />
            <outjar path="${j4k.dist}/Asteroids4K.jar" />
            <libraryjar path="C:/Apps/Programming/Java/j2sdk1.4.2_10/jre/lib/rt.jar" />
        </proguard>
    </target>

    <target name="_obfuscate_2" depends="_package_jar" description="obfuscate/compress classes">
        <jarg jarfile="${j4k.dist}/Asteroids4Kpre.jar" verbose="true" rnlog="rnlog.txt" />
    </target>

    <target name="_unzip" depends="_obfuscate_2" description="obfuscate/compress classes">
        <unzip src="${j4k.dist}/Asteroids4Kpre_s.jar" dest="${j4k.dist}" />
    </target>

    <target name="_rezip" depends="_unzip" description="obfuscate/compress classes" >
        <exec executable="7z" output="error.log" dir="${j4k.dist}">
            <arg value="a" />
            <arg value="Asteroids.jar" />
            <arg value="A.class" />
        </exec>
    </target>
</project>

Very useful. I’ve been meaning to get to grip with ant for some time, but have to confess to using .bat files. Does “output=error.log” put the output in a file or in the compilation message window. It would be nice to display the final size of the compressed jar. If necessary I could write a small java program to determine the file size & write the output, which somehow needs to end up in the compilation message window, rather than on the console.

Alan

Everytimes I see XML used in a way it wasn’t meant to be, I get the shivers.

I too make a batch-file to compile, zip and show the final file-size. I can hardly believe Ant makes that easier.

(not that I ever used Ant, scripting in XML scares the crap out of me)

That was my attempt to get 7-Zip to output something useful. It doesn’t work yet. Still trying to figure out how to get it to display a message.

Aye, I’m still very much this way. XML and scripting doesn’t make sense in my head (though the BPEL standard seems to be proving otherwise). However, where ANT is concerned I’ll make an exception. There is something wonderful about having a script that does everything for me and is integrated into my IDE. Click Button -> Package in My Bespoke and Convoluted Way.

My script to build, package, sign and upload the appropriate jars to webstart website has saved me tonnes of time on this last project.

Kev

[quote=“Riven,post:3,topic:25560”]
That’s just because everyone always show complex ANT scripts. A basic ANT script is easy to write and pick up. I used to use nothing but batch scripts myself, right up until I started noticing that every program that had an ANT script was easy to build. Considering that batch/shell scripts tended to be environment dependent, I found myself wishing that more programmers used ANT (even though I was avoiding it). Finally, I bit the bullet and realized that it’s actually very easy, and is a good way to handle complex builds. :slight_smile:

See if you can figure out this script. The section named “compile”, for example, simply calls JavaC, then copies the final files to other directories.

Takes a while to master their use, but used in conjunction with eclipse - ant scripts are truely fantastic!

Netbeans has always been ahead on ANT support. :wink:

realy?? what does netbeans do that eclipse doesn’t?

[quote=“Anon666,post:9,topic:25560”]
The entire build system is now ANT. If you create a new project, Netbeans creates ANT scripts behind the scenes that it uses to store all its project data. Those scripts can then be taken to any other IDE and reused. If you already have a handcrafted script (my preference), Netbeans will import all the settings from the file and work directly from that build file for your project.

It’s nice. ;D

eclipse can do the same… yay :slight_smile:

[quote=“Honk,post:11,topic:25560”]
At least the last time I checked, Eclipse’s project system wasn’t based entirely around ANT. It has ANT support, yes, but that’s not the same thing. Also, Netbeans has autocomplete for ANT files, and can integrate with the ANT documentation via a plugin from the Update Center. :slight_smile:

I like that Netbeans has Ant as the “project” file. But that said, it is a poor system to use during development compared to Eclipse. It is just so much slower to run an Ant script to to a build, run an Ant script to start debugging, etc…

Eclipse’s method of compiling each class instantly when you save the file (with no perceivable delay) make my work flow go much faster. There is basically no compile step ever while doing general work, the .class files are just always there and up to date. That’s sweet.

Then I looked at the Ant build files used by Netbeans… sort of icky… I see what they are doing, trying to abstract everything out and stick in hooks all over the place… basically to overcome what would otherwise be a sort of limited project file. It gets the job done, that’s cool. And it is nice to have an Ant script that is updated automatically with the project. If only it didn’t slow me down. I use Eclipse and it’s built in compiling, along side my own hand made Ant file for “production” builds.

If Netbeans went for a hybrid approach where they had an integrated compiler like Eclipse, didn’t use Ant to do EVERYTHING, like launch the debugger… yet kept and maintained the Ant file as well… that would be great.

In terms of a 4k game where you generally only have a single source file… Ant is overkill. A batch file is way smaller, simpler, and easier to deal with.

Indeed. A lot of developers swear up and down by this. My only issue with it is that it can encourage developers to work from a “dirty” build. The next time a full compile is run, nothing builds because the files were all out of date. (I’ve been biten by this from Eclipse users a few times.) Thankfully, a good build process can make up for this problem. :slight_smile:

[quote]In terms of a 4k game where you generally only have a single source file… Ant is overkill. A batch file is way smaller, simpler, and easier to deal with.
[/quote]
Agreed. I use Unix shell scripts for every stage of the build. :slight_smile:

Who cares if eclipse is not built around ant? You can create ant files from your project and you can create projects from ant files. What else do you need? :slight_smile:

Agreed, I don’t see a reason why you would want your system built on it if it already fully supports it. At least in my experience with Ant in working on the JRPG, running a project or building it with Ant seemed clunky and slow. Doing a regular eclipse build and eclipse run without getting Ant involved is nicer in my opinion.