FDT 3: You’re Gonna Need Some Ant With That Sauce
FDT 3 is almost here - fans of FDT 1.5 know how awesome that is. I've been fortunate enough to be involved in the private beta, so I have had my hands on it for some time now. I must say, I like it better than version 1.5 for sure (and not just because it supports AS3 now). I'll save the review for another time though; this long post is all about Ant support in Eclipse and how you can use it to compile your AS3 projects. Though I am using FDT 3 for this tutorial, if you aren't in the private beta group you can still follow along using Flex Builder. If you are using the standalone version, you will need to use the 'Software Updates > Find and Install' tool to get 'Eclipse Java Development Tools' downloaded and installed so that you can use the Ant panel which I speak of throughout this article.
Moving along, you will need to download a copy of the Flex 3 SDK to your machine. It contains everything you will need to compile, test, and document your various AS3 projects. Also, the examples below are for Windows users, however the same rules apply for Mac users, you will simply need to change some file extensions and so forth.
Setting Up Eclipse
If the Ant panel is not already open, you can find it here:
Window > Show View > Ant
This is what you should see if it is open:

With the Ant panel open, it is time to create a build file.
Constructing An Ant Build File
First off, you will need to create a 'build.xml' file which Ant will use to automate your build. At it's simplest form, it should look something like this:
-
<project name="FDT3ExampleTasks" default="compileAllAndLaunch" basedir=".">
-
-
</project>
Breaking down the project node attributes, 'name' is the name that will appear in the Ant panel of Eclipse. The 'default' attribute is a reference to the target in which Ant will run by default, say if you double-click the build file in the Ant panel for instance. Finally, there is the 'basedir' attribute which basically tells Ant what directory the property 'basedir' should represent. If you are going to store your build file(s) in a directory other than the root directory of your project, then you will want to change that path to reflect this. For instance, if you created a directory called 'build' and stored your build file(s) in there, you would want to make your basedir point towards '../' and so forth.
Before moving on - now that you have a 'build.xml' file in the works, you can go ahead and add it to the Ant panel. The simplest way to do this is by dragging the build file from the Flash Explorer panel down into the Ant panel. Upon dropping the file it should become listed in the panel. As tasks get added they will show up listed under that particular file like so:

Double-clicking the tasks is how you will run them.
Ok, so now that we have a foundation for our build file, we need to add some properties so that we can easily reference commonly used paths and whatnot. You can define properties directly inside the 'build.xml' file or create a separate 'build.properties' file to store them externally from the build file itself. Below are demonstrations of both practices. Also note that once you define a property, you call upon it using the following notation: ${propertyname}.
Defining properties inside the build file:
-
<project name="FDT3ExampleTasks" default="compileAllAndLaunch" basedir=".">
-
-
<property name="flex3dir" value="C:/flash_tools/flex_3_sdk/" />
-
<property name="flex3bindir" value="${flex3dir}/bin" />
-
<property name="flex3libsdir" value="${flex3dir}/frameworks/libs" />
-
<property name="mxmlc" value="${flex3bindir}/mxmlc.exe" />
-
<property name="asdoc" value="${flex3bindir}/asdoc.exe" />
-
<property name="flashplayer" value="${flex3dir}/runtimes/player/win/FlashPlayer.exe" />
-
<property name="bindir" value="${basedir}/bin" />
-
<property name="classesdir" value="${basedir}/src/classes" />
-
<property name="deploydir" value="${basedir}/deploy" />
-
<property name="docsdir" value="${basedir}/docs" />
-
<property name="framerate" value="31" />
-
<property name="bgcolor" value="0xFFFFFF" />
-
<property name="width" value="550" />
-
<property name="height" value="400" />
-
-
</project>
Defining properties inside a separate build properties file (name it 'build.properties' and save it in the same directory as the build file(s):
-
flex3dir = "C:/flash_tools/flex_3_sdk/"
-
flex3bindir = "${flex3dir}/bin"
-
flex3libsdir = "${flex3dir}/frameworks/libs"
-
mxmlc = "${flex3bindir}/mxmlc.exe"
-
asdoc = "${flex3bindir}/asdoc.exe"
-
flashplayer = "${flex3dir}/runtimes/player/win/FlashPlayer.exe"
-
bindir = "${basedir}/bin"
-
classesdir = "${basedir}/src/classes"
-
deploydir = "${basedir}/deploy"
-
docsdir = "${basedir}/docs"
-
framerate = "31"
-
bgcolor = "0xFFFFFF"
-
width = "550"
-
height = "400"
As shown above, build.properties files are very simple and easy to create. The advantage to using one is basically the same as using a config XML file in a Flash project to prevent needing to make changes directly in Flash (but in this case the build file).
Ok, so now on to the good stuff. Let's create a simple task to compile our 'main.swf' file.
-
<target name="compileMain">
-
<exec executable="${mxmlc}">
-
<arg line="-source-path '${classesdir}' -library-path '${flex3libsdir}' -default-frame-rate=${framerate} -default-background-color=${bgcolor} -default-size ${width} ${height} -strict=true '${classesdir}/com/boostworthy/Main.as' -output '${deploydir}/main.swf'"/>
-
</exec>
-
</target>
Each target needs to have a unique name which represents that task. Using an 'exec' node, you can specify an executable to call. In our case, we pass it the property we created which points to the mxmlc compiler. Last but not least we have an 'arg' node which is used to pass arguments to the executable just like we would in the command-line. Note that you can create a separate 'arg' node for each argument if you wish. I prefer keeping everything on one line to prevent the document from being super long, however it can make things a little less readable if that is a concern.
You will want to create a task like this one for each SWF you need to compile. I usually just copy and paste one to a new line, give it a new name, and change the SWF file name and document class. As your application grows, you will likely want to create a 'compileAll' task for compiling each SWF instead of having to run each task on it's own. Fortunately, there is a very nice way we can reuse all of our existing tasks. Here is an example of how you could run three different tasks with ease:
-
<target name="compileAll" depends="compileMain, compileNavigation, compileAbout"/>
The 'depends' attribute is very handy. It simply states that Ant must do each task listed prior to running that task. In this case, we just simply list out each compile task we would like it to run, then never specify any actions to be taken for the 'compileAll' task itself.
Ok, so now that we have SWF files compiling, how can we launch our app to see it in action? Again, we will need to create a new task.
-
<target name="launch">
-
<exec executable="${flashplayer}" spawn="false">
-
<arg line="'${deploydir}/main.swf'" />
-
</exec>
-
</target>
Very similar to the task we created for compiling, however this time we are launching Flash Player and passing the SWF file we would like to open as an argument. The 'spawn' attribute of the 'exec' node is set to 'false' by default (meaning if you do not list it), however I wanted to show it here because flipping it to 'true' will disable trace outputs in the console which may be desirable.
So far so good. Currently, to build and test our app we must first run the task 'compileAll' then 'launch'. This is ok, but we could easily reduce this to one step.
-
<target name="compileAllAndLaunch" depends="compileAll, launch"/>
Again, using the beautiful 'depends' attribute, we simply specify to run the task 'compileAll' followed by 'launch'.
At this point, Ant is saving us a ton of time. We can easily compile each SWF file individually or all of them at once. We can also launch the app to see it in action and choose to receive trace outputs in the console. One additional task that I always use is a task for generating documentation. If you have been using JavaDoc commenting throughout your code, you can use the Adobe ASDoc tool that is supplied with the Flex 3 SDK.
-
<target name="generateDocs">
-
<delete includeemptydirs="true">
-
<fileset dir="${docsdir}" includes="**/*" />
-
</delete>
-
<exec executable="${asdoc}" spawn="true">
-
<arg line="-doc-sources '${classesdir}' -output '${docsdir}' -main-title 'Your App API' -window-title 'Your App API'" />
-
</exec>
-
</target>
This task simply goes into the specified source directory and outputs html documentation. You can specify the title that appears on the top of the documents as well. The 'delete' node at the beginning simply clears the docs directory prior to generating the new documentation.
Before moving on to the next section, I also wanted to mention that you can just as easily use these same techniques to compile, test, and deploy AIR applications. You will need to create some additional properties that point towards the necessary directories and command-line tools. Some sample AIR properties:
-
<property name="airlibsdir" value="${flex3libsdir}/air" />
-
<property name="adl" value="${flex3bindir}/adl.exe" />
-
<property name="adt" value="${flex3bindir}/adt.bat" />
-
<property name="appxml" value="${basedir}/application.xml" />
-
<property name="icondir" value="${basedir}/icon" />
Instead of mxmlc and Flash Player, you will want to compile and test your app using 'adl'. When it comes time to package your application as an AIR file, something like this will suffice using 'adt':
-
<target name="deploy" depends="generateDocs">
-
<exec executable="${adt}" spawn="true">
-
<arg line="-package '${deploydir}/${appname}' '${appxml}' '${icondir}' '${mainswf}'" />
-
</exec>
-
</target>
That pretty much covers most of the basics for compiling your AS3 with Ant. Now let's move on to some lesser-known things you can do (in the Flash world at least).
Advanced Ant
Ant can do more than just compile and launch your projects. You can even use it to handle SVN requests, FTP files to a server, and package your applications for hand-off to a client. One of my favorites is that last one - packaging up your goods for a client hand-off. What I like to do is create an empty directory, copy only certain file types and directories into it, then zip it up so I can email it or whatever.
-
<target name="package" depends="generateDocs">
-
<copy overwrite="true" todir="../my_app_for_client">
-
<fileset dir="../my_app">
-
<exclude name="**/.settings/**" />
-
<exclude name="**/*.as3_classpath"/>
-
<exclude name="**/*.project"/>
-
<exclude name="**/.svn/**" />
-
</fileset>
-
</copy>
-
<zip file="../my_app_for_client.zip">
-
<fileset dir="..">
-
<include name="**/my_app_for_client/**" />
-
</fileset>
-
</zip>
-
</target>
By using 'fileset' nodes, a collection of directories/files can be specified and filters can be put in place using 'include' and 'exclude' nodes. In the example above, I am copying all files over except for the FDT project files and SVN databases.
Another cool thing that you can do is check to ensure that certain properties have been set prior to running a task to prevent unwanted bad happenings.
-
<target name="checkForASDoc">
-
<fail unless="asdoc">The 'asdoc' property has not been set. Please set this property with a reference to 'asdoc.exe' on your hard drive.</fail>
-
</target>
-
-
<target name="generateDocs" depends="checkForASDoc">
-
<delete includeemptydirs="true">
-
<fileset dir="${docsdir}" includes="**/*" />
-
</delete>
-
<exec executable="${asdoc}" spawn="true">
-
<arg line="-doc-sources '${classesdir}' -output '${docsdir}' -main-title 'Your App API' -window-title 'Your App API'" />
-
</exec>
-
</target>
Now, thanks to the 'depends' attribute, 'checkForASDoc' will be called prior to the 'generateDocs' task taking action. If the 'asdoc' property has not been set, the specified message will be output to the console.
We can go one step further and create actual conditionals as well. Let's say we created a property named 'createdocs' and we wanted to be able to set it to 'true' or 'false'; the intent being to create docs or not create docs based on the value that is set.
-
<target name="checkForDocs">
-
<condition property="docstarget" value="generateDocs">
-
<equals arg1="${createdocs}" arg2="true" />
-
</condition>
-
<condition property="docstarget" value="noDocs">
-
<equals arg1="${createdocs}" arg2="false" />
-
</condition>
-
-
<antcall target="${docstarget}" />
-
</target>
It's a little weird how it reads, but essentially you create a 'condition' node and it's child nodes specify the comparisons. In this case, we use an 'equals' node to compare 'arg1' to 'arg2'. If the statement is true, the specified local property 'docstarget' is set to the value specified by the 'value' attribute in the 'condition' node.
Final Word
This post could go on forever discussing the cool stuff you can do with Ant, but I think you get the idea. Complete documentation for Ant and it's many tasks can be found here.
On a final note, if you run into any problems while running mxmlc, specifically ones complaining about 'jvm.dll', you most likely have JRE 6+ installed. Uninstall it and grab JRE 5 from the archive located on the Java site. Hopefully Adobe will address this in the months to come.
If any of you have additional tasks that you find especially useful that I didn't cover in this post, feel free to post away in the comments.
15 Comments so far
Leave a reply

Thanks for the thorough rundown! I've been using ANT + Eclipse for ActionScript development for a few years now, but I'm now testing out Sprouts: http://code.google.com/p/projectsprouts/.
This is the latest incarnation of Luke Bayes and Ali Mills ASProject (also of ASUnit fame). Its Rails-inspired approach is really refreshing: once you download Sprouts using Gems it automatically downloads all the required files for either as2 or as3 projects, (swfmill, mtasc, mxmlc etc). If you're gravitating towards Test-Driven Development an added bonus is the automatic creation of test classes.
Instead of Ant Build scripts you use Rake build files (exact same concepts), and you can create classes on the command-line, which can be generated off templates you can customise. There's still a bit of work to be done to add features you have in Rails, but it's almost to the point that you can type in script/generate controller method1 method2 method3 and the like to speed up your development. Well worth keeping an eye on!
Another tip is to set up your ant targets as an "External tool". Right click on a target in the Ant panel and choose "Run as... > Open External Tools Dialog". You can pick the actual targets within the ant file you want to run under the relevant tab.
Now, under "Preferences > General > Keys" tick "Include unbound commands" and type "external" into the filter text. You should be able to find "Run Last Launched External Tool" in the list and assign a keyboard shortcut to it (I use Ctrl+Enter cos I'm oldschool!).
Now your target is triggered when you press your keyboard shortcut. In my case my target compiles (with incremental=true) and then launches my swf. Not as fast as Flex Builder or fsch would but still perfectly usable. And you get the advantages of FDT 3 to edit your ActionScript in
btw - all menu paths etc were for Eclipse 3.3 - not sure if it's in the same places in other versions of Eclipse...
@Justin - I checked out AsProject awhile back, but I wasn't familiar with Sprouts. Thanks for the heads up on that!
@Kelvin - That's awesome. Big thanks for sharing that tip!
[...] After getting setup, you may find my tutorial on AS3 Ant builds useful for optimizing your AS3 workflow in FDT 3. Happy coding! [...]
[...] Also, Ryan Taylor has a tutorial on using Ant with FDT 3. [...]
Thanks Ryan!! This was greatly helpful in getting me started with FDT3 and Ant. Any way we can use fsch with Ant to speed up the compiling? I am still trying to understand the whole compiling without mtasc in fdt 3 beta...I am going to give kelvin luck's method a try now..
I had to set incremental argument for mxmlc to true and that helped
thanks kelvin!!
Thanks for the great introduction. Works fine on my mac - except the flash player part. It's pretty stupid that *.app are folders
Any workaround ideas?
how can i use fcsh with ant?
best regards
SABAN
Hi,
we have create a eclipse plugIn to use fcsh with ant.
http://ifac-plugin.com/
Best regards
SABAN
Great tutorial Ryan, this real got me started with FDT3. Thanks a lot
Hello!
iFac is made to be used exclusively with eclipse and when i try to reuse their code for my needs, i found that is not opensource. The license does not permit code modifications. So i created another wrapper over the fcsh that, this time, is available to be customized to meet your needs, so you not start from zero.
The project is available on sourceforge: http://sourceforge.net/projects/fcshwrapper/
and some details are available at: http://fcshwrapper.blogspot.com/
First of all, thanks for this great introduction to ANT FDT Eclipse!!
As steffen already said Mac users will have problems with the launch target. I found a solution for this:
You just have to use the shell command open with the path to the Flash Player.app and the deployed SWF:
If is possible to create air install package in run time of program(for example on button click). If yes than help if no than say no.