Skip to content

Flex2 & ANT

2007 February 20
tags: ,
by Joe

I’ve had the opportunity to work with Adobe’s Flex2 and the Flex Builder IDE a substantial amount and have loads of tips and thoughts about the environment – both positive and negative. This first Flex2 post is about building a Flex2 project with Ant.

Flex Builder has some issues. While the debugger and design view can be nice, its weakness with ctrl-space completion and lack of refactoring support can really alienate a Java developer accustomed to the fantastic intelligence of Eclipse and IntelliJ IDEA (and not to mention fully capable Linux versions). I’ll post specific pointers and tips for working around Flex Builder’s weaknesses in the future. For now I’ll just describe how to use ANT to build your Flex2 projects.

My philosophy on projects is that if your team is larger than 1 person there should be absolutely no dependencies on an IDE or an environment to check out, modify, or build the code. If this doesn’t sound incredibly obvious, I highly recommend reading Practices of an Agile Developer or something similar.

That said, putting together an ANT build file that mimics what Flex Builder does under the hood is a great idea as it eliminates the IDE dependency and makes more advanced deployments easier as you can take advantage of a proven, professional build system in ANT. I’ll just do a basic configuration here and mention a few gotchas. If are hitting a brick wall with ANT and Flex2 just leave a comment and I will try to help.

If you just want links go to the Flex Ant Tasks page at Adobe Labs and optionally read this page for some documentation and tips.

Alternatively, here is a quick example. This assumes you have a project setup like this:

/myProject/Main.mxml - the main application mxml file
/myProject/etc - contains images, xml, or other project resources
/myProject/lib - contains any external libraries (.swcs)
/myProject/src - your .mxml and .as files
/myProject/build - the directory to place build artifacts
  • Make sure you have ANT properly installed
  • Extract the flexTasks.jar file from the zip on the Adobe Labs page and place it in your project’s lib directory
  • Create a build.xml file in your project’s root directory (see below)
  • Optionally configure Flex Builder to use your project’s build directory for compiler output and running/debugging (instead of the “bin” directory that is used by default). This simply make the build process and output more similar to that of developers using the ANT tasks

Sample build.xml

This covers compiling debug and non-debug versions of your swf as well as copying additional resources into your build directory. The build file can get complicated if you have lots of source directories, lots of external libraries, or if you need to pass the compiler special arguments (such as for preserving custom metadata).


<?xml version="1.0"?>
<!--
Required Environment Variables:
FLEX_HOME: must point to the root of your flex sdk (probably in flex builder directory)
-->
<project name="myProject" default="compile">

    <!-- Make the Flex Ant Tasks available -->
    <taskdef resource="flexTasks.tasks" classpath="lib/flexTasks.jar"/>

    <!-- Module properties -->
    <property environment="env"/>
    <property name="build.dir" value="build"/>
    <property name="swf.name" value="MyProjectSwf"/>
    <property name="root.mxml" value="Main.mxml"/>
    <property name="locale" value="en_US"/>
    <property name="FLEX_HOME" value="${env.FLEX_HOME}"/>

    <!-- Clears out the build directory -->
    <target name="clean">
        <echo message="Removing build directory contents..."/>
        <delete includeemptydirs="true">
         <fileset dir="${build.dir}" includes="**/*"/>
        </delete>
    </target>

    <!-- standard compile w/o debug -->
    <target name="compile">
        <antcall target="perform-compile">
            <param name="debugMode" value="false"/>
        </antcall>
    </target>

    <!-- compile with debug -->
    <target name="compile-debug">
        <antcall target="perform-compile">
            <param name="debugMode" value="true"/>
        </antcall>
    </target>

    <target name="perform-compile">
        <!-- Make sure the build directory exists -->
        <mkdir dir="${build.dir}"/>

        <mxmlc
            file="${root.mxml}"
            output="${build.dir}/${fullSwfName}"
            incremental="true"
            debug="${debugMode}"
        >
            <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>

            <!-- directories outside of your 'main' source directory -->
            <source-path path-element="${FLEX_HOME}/frameworks"/>

            <!-- list any swcs in your lib directory to include -->
            <library-path dir="lib" append="true">
                <include name="Cairngorm.swc"/>
                <include name="SomeOtherLibrary.swc"/>
            </library-path>

            <!-- flex sdk core libraries -->
            <library-path dir="${FLEX_HOME}/frameworks" append="true">
                <include name="libs"/>
                <include name="../bundles/${locale}"/>
            </library-path>
        </mxmlc>

        <!-- copy over the etc directory contents -->
        <antcall target="copy-files"/>
    </target>

    <!-- Copies contents of /etc to /build -->
    <target name="copy-files">
        <copy todir="${build.dir}">
            <fileset dir="." includes="etc/**/*"/>
        </copy>
    </target>

</project>

This may not be the most barebones build file possible for an initial example, but it is a realistic one that takes into account external libraries and non-code items such as images and xml that you may want to use outside of the swf. With this file you can run any of the following commands from the root of your projects:

ant:
runs the default target, currently set to “compile”
ant compile:
builds a swf from your source code and places it in the build directory along with the contents of /etc
ant compile-debug:
same as compile except it generates a swf that can be debugged
ant clean:
deletes the contents of the build directory

ant copy-files:
copies the contents of /etc to /build. used as part of other targets but could be used individually

Some Notes

  • The FLEX_HOME property must be set in your build file – it is an undocumented requirement of the mxmlc task
  • Many mxmlc arguments available if you invoke the compiler directly are not available in the mxmlc ANT task. For these you will need to create a custom configuration file and use it in your ANT target. See this page for an example of setting up the config file. To use a config file in your build.xml simply add an additional <load-config> property to the mxmlc task.
  • If you are using Flex Builder it is best to use its preset builder and not change it to use your ANT targets. If you hook Flex Builder to ANT directly you will lose the benefits of inline error messages and warnings when building.
  • Note that the result of the copy-files target isn’t something automatically performed by the build process of Flex Builder. There may be a cleaner way, but you can configure an additional builder for your Flex Builder project that will run the copy-files target of your ANT build file after the regular build-related tasks have completed.
  • The above build.xml file assumes all developers have a FLEX_HOME environment variable set on their machine. This may seem like a hassle but it is a far more reasonable approach to obtaining consistency across platforms and environments that requiring a specific and expensive IDE.
  • This build file assumes you are running your swfs directly and not inside an html container. If you need to run your project inside of a container take a look at the html-wrapper ANT tasks described at that Adobe Labs page or put together your own wrappers and copy them over to the /build directory as is being done above for the contents of /etc.

I have a lot of Flex-related content that I would like to share, mostly brick walls that have been conquered. I hope to get them all posted eventually so that google can get them indexed and they can smooth adoption for other developers working with Flex.

9 Responses
  1. April 20, 2007

    Do you have an experience with using compc and Ant?

    U have an difficulty when I point ‘compc’s command line parameter -library-path to location that contains spaces

    Example:

    …..

    Compile shared FlexLibrary to SWC file

    …..

    I receive an error command line: Error: unable to open ‘C:\Program’ every time even if I use quote characters surrounding -library-path’s value :(

  2. April 20, 2007

    One more posting with probably fixed formatting….

    <property name=”FLEX_HOME” value=”C:\Program Files\Adobe\Flex Builder 2 Plug-in\Flex SDK 2″/>
    <property name=”flexSDK.libraries” location=”${FLEX_HOME}\frameworks\libs” />
    …..
    <target name=”compile FlexLibrary SWC”>
    <echo>Compile shared FlexLibrary to SWC file </echo>
    <exec dir=”.” executable=”cmd” failonerror=”true”>
    <arg line=”/c ‘${flex.compc}’
    -library-path ‘${flexSDK.libraries}’
    -output=${FlexLibrary.output}”/>
    </exec>
    </target>

  3. April 20, 2007

    Hey,

    Thanks for the question. Unfortunately I haven’t had to use compc and thus am not much help here. I would say try using the compc ANT task in the Adobe Labs project I mentioned in the post though it seems likely you would have the same issue.

    Also, it looks like other people are having issues with spaces in paths as well (here is a question on the wiki page for the ANT tasks project). It looks like there are a couple suggestions related to it and maybe those will work.

    Hopefully it can be figured out, sorry I am not much help.

    Joe

  4. April 20, 2007

    Thanks for the answer.

    Thanks for the pointing me to page http://labs.adobe.com/wiki/index.php/Talk:Flex_Ant_Tasks, I missed this entry.


    Yes, I am trying to use compc ANT task in the Adobe Labs in parallel too as possible second solution :)

    Unfortunately, I cannot figure out how to use “include-namespaces” directive with this util. It is not documented properly here:
    http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks

    I posted recently about my problem here: http://tech.groups.yahoo.com/group/flexcomponents/message/2052
    and here:
    http://labs.adobe.com/wiki/index.php/Talk:Flex_Ant_Tasks

    My solution – do not use namespaces and manifest files together with compc util from the Adobe Labs :)

  5. Suzanne Dorman permalink
    December 6, 2007

    I have an Ant script that I am using for mxmlc. I am having problems getting the debug flag to work. It seems to have no effect. I have commented out the loading of the config file to avoid option conflicts but I still get the same results. Oddly, if I have Flex Builder up and running when I run my Ant script (outside of Flex Builder), it does create debug files (even if I have debug off). It seems to pick up Flex Builder’s compile options. Here is my task:

    FLEX_HOME is set to the Flex SDK directory via an Ant properties file:

    FLEX_HOME=C:/Program Files/Adobe/Flex Builder 2/Flex SDK 2

  6. Suzanne Dorman permalink
    December 6, 2007

    Well, my task got filtered on my last post. Trying again:

    &ltmxmlc&nbspfile=”${flexsrc.dir}/${filename.@{file}}.mxml”&nbsp&nbspoutput=”${bin.dir}/${filename.@{file}}.swf”&nbspkeep-generated-actionscript=”true”&nbspdebug=”true”&gt

    &nbsp&nbsp&nbsp&nbsp&lt!–&nbspGet&nbspdefault&nbspcompiler&nbspoptions.&nbsp–&gt

    &nbsp&nbsp&nbsp&nbsp&ltload-config&nbspfilename=”${FLEX_HOME}/frameworks/flex-config.xml”/&gt

    &nbsp&nbsp&nbsp&nbsp&lt!–&nbspList&nbspof&nbsppath&nbspelements&nbspthat&nbspform&nbspthe&nbsproots&nbspof&nbspActionScript&nbspclass&nbsphierarchies.&nbsp–&gt

    &nbsp&nbsp&nbsp&nbsp&ltsource-path&nbsppath-element=”${FLEX_HOME}/frameworks”/&gt

    &nbsp&nbsp&nbsp&nbsp&lt!–&nbspList&nbspof&nbspSWC&nbspfiles&nbspor&nbspdirectories&nbspthat&nbspcontain&nbspSWC&nbspfiles.&nbsp–&gt

    &nbsp&nbsp&nbsp&nbsp&ltcompiler.library-path&nbspdir=”${FLEX_HOME}/frameworks”&nbspappend=”true”&gt

    &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&ltinclude&nbspname=”${flex.lib.dir}”&nbsp/&gt

    &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&ltinclude&nbspname=”../bundles/{locale}”&nbsp/&gt

    &nbsp&nbsp&nbsp&nbsp&lt/compiler.library-path&gt

    &nbsp&nbsp&nbsp&nbsp&ltcompiler.external-library-path&nbspdir=”${flex.lib.dir}”&nbspappend=”true”&gt

    &nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&ltinclude&nbspname=”*.swc”/&gt
    &nbsp&nbsp&nbsp&nbsp&lt/compiler.external-library-path&gt

    &lt/mxmlc&gt

  7. Suzanne Dorman permalink
    December 6, 2007

    Can you give me a hint as to how to get the post the ant information without it being filtered? Apparently using html tags wasn’t the solution.

  8. Suzanne Dorman permalink
    December 6, 2007

    I figured out one part of the problem – I was using compiler.library-external-path for my local SWC files instead of library-path. But it doesn’t resolve the problem of getting different results if Flex Builder is up and running. The Ant script generates many files if Flex Builder is running – it creates all the same files that Flex Builder does when you use it to compile. I can’t understand why it would effect an external compilation. I don’t see any environmental variables getting changed.

    Sorry for the messy posts before. Feel free to delete them.

  9. Jay permalink
    July 1, 2009

    Thanks for this! I kept trying to use some form of an external-library-path path-element= tag, and was getting nowhere. This is an extremely helpful example!

Comments are closed.