Automating Flex Compilation Using ANT

When we first started developing Flex applications for clients when the time would come to send the SWF over, I would build the application in Flex Builder and send off the generated SWF. This got the job done, but it imposed a few limitations since I was the only Flex developer in our office:

  • I was the only one that knew how to compile the application
  • If someone else wanted to try to compile the application, they'd have to install Flex Builder

After reading a blog post by Marc Hughes I realized it was time we put in place a more versatile environment for building Flex applications.

I settled on using ANT since the Flex SDK includes a set of ANT tasks to simplify compiling using ANT. I was quickly able to follow the examples to make an ANT script to compile a simple application:

Simple Build File

<?xml version="1.0"?>  
 <project name="TestANT" basedir="." default="compile">

  <taskdef&nbsp;resource="flexTasks.tasks"&nbsp;classpath="${basedir}/flexTasks/lib/flexTasks.jar"/>

  <property name="FLEX\_HOME" value="/var/lib/flex"/>

  <target name="compile">  
   <mxmlc file="TestANT.mxml">  
      <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml">  
      <source-path path-element="${FLEX_HOME}/frameworks"/>  
     </mxmlc>  
   </target>

</project>

This works fine for a simple Flex project, but most projects we use utilize external libraries that have been compiled into a SWC. Getting the Cairngorm SWC compiled into my test application by following the documentation proved harder than it looked. I first tried the following build file to compile a project using Cairngorm:

Build File Attempting to Include Cairngorm

<?xml version="1.0"?>  
 <project name="TestANT" basedir="." default="compile">

  <taskdef resource="flexTasks.tasks"&nbsp;classpath="${basedir}/flexTasks/lib/flexTasks.jar"/>

  <property name="FLEX_HOME" value="/var/lib/flex"/>

  <target name="compile">  
     <mxmlc file="TestANT.mxml">  
      <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>  
      <source-path path-element="${FLEX_HOME}/frameworks"/>  
      compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">  
       <include name="/var/lib/swcs/Cairngorm.swc" />  
       </compiler.library-path>  
     </mxmlc>  
   </target\>

</project\>

I thought I had followed the instructions properly, but unfortunately this was yielding:

[mxmlc] /home/greg/blah/test.mxml(6): Error: Definition com.adobe.cairngorm.control:CairngormEvent could not be found.

After playing around with some parameters and re-reading the documentation a few times, i finally got it to include SWCs using the following code:

Build File to Properly Include SWCs

<?xml version="1.0"?>  
 <project name="TestANT" basedir="." default="compile">

  <taskdef resource="flexTasks.tasks" classpath="${basedir}/flexTasks/lib/flexTasks.jar"/>

  <property name="FLEX\_HOME" value="/var/lib/flex"/>  
  <property name="LIBS" value="/var/lib/swcs"/>

  <target name="compile">  
     <mxmlc file="TestANT.mxml"/>  
      <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>  
      <source-path path-element="${FLEX_HOME}/frameworks"/>  
      <compiler.library-path dir="${LIBS}" append="true">  
      <include name="Cairngorm.swc"/>  
      </compiler.library-path\>  
      </mxmlc>  
    </target\>

</project>

The documentation is confusing since it says to specify the ${FLEX_HOME}/frameworks directory as the dir attribute to the <compiler.library-path> tag. I had thought my modification of their example would work, since I was assuming the append attribute was indicating to also include the paths in addition to the frameworks directory. I guess that's not the case, and by specifying the <compiler.library-path> parameter with append="true" included you are indicating to do the equivalent to mxmlc -l+=somepath on the command line.