wikipedia

Support Wikipedia

Thursday, June 4, 2009

Ant build script for Flex projects

It took me a while to get the build script working for Flex. I started out by googgling for them. Took some scripts out there and put it together. But ran into some errors like"Unable to transcode swf", "Out of memory heap space". Having fixed them all, wanted to share what i ended up with.

One compile error I was getting regularly was for embedded objects like swf or image files. Care needs to be taken to make sure that the paths are correct. For example inside a class which is deep in the source package tree, the path needs to be absolute. But for mxml files at the root level, relative paths are OK. Flex builder IDE or eclipse with Flex plugin will not raise a compile error for this issue. Only an ant build script will do that. FLEX_HOME environment variable needs to be set to the flex sdk directory.

Also the mxmlc compile task can take a lot of memory, so added maxmemory attribute to take care of that.You need to use fork=true (launch it's own jvm process instead of running under ant's jvm).

build.xml



<?xml version='1.0'?>
<project name='MYUIProject' default='masterbuild' basedir='.'>
<target name='init'>
<!--FLEX_HOME environment property should be set to where flex is installed-->
<property environment="env"/>
<property name="FLEX_HOME" value="${env.FLEX_HOME}"/>
<property name="DEFAULT.LOCAL" value="en_US"/>
<property name="ENCODING" value="UTF-8"/>
<!-- directories-->
<property name="application.name" value="AppMain"/>
<property name="src.dir" value="src"/>
<property name="bin.dir" value="bin"/>
<property name="build.dir" value="build"/>
<property name="lib.dir" value="lib"/>
<property name="vendor.lib.dir" value="${lib.dir}/vendor"/>
<property name="dist.dir" value="${basedir}/dist"/>
<property name="wrapper.dir" value="html-template"/>
<property name="html.file" value="${dist.dir}/${application.name}.html"/>
<property name="main.class" value="${src.dir}/AppMain.mxml"/>
<property name="swf.export" value="${bin.dir}/AppMain.swf"/>

<!--ASSETS DIR-->
<property name="assets.dir" value="${src.dir}/assets/"/>
<path id="project.classpath">
<pathelement location="${build.dir}" />
<fileset dir="${lib.dir}">
<include name="**/*.swc" />
</fileset>
<fileset dir="${vendor.lib.dir}">
<include name="**/*.jar" />
</fileset>
</path>

<!-- Configure the custom Ant tasks -->
<taskdef resource="flexTasks.tasks" classpath="${lib.dir}/vendor/flexTasks.jar" />
<taskdef resource="com/adobe/ac/ant/tasks/tasks.properties" classpath="${FLEX.ANT.TASK.DIR}"/>

</target>

<target name='initdirs' depends="init">
<mkdir dir='${dist.dir}'/>
</target>

<!-- define all .mxml files and .css files that need to be converted into a .swf file
for the application-->
<target name="compile" depends="init, clean">
<antcall target="build-mxml-module">
<param name="module" value="AppMain" />
</antcall>
<antcall target="build-css-module">
<param name="module" value="core" />
</antcall>
<antcall target="build-css-module">
<param name="module" value="day" />
</antcall>
<antcall target="build-css-module">
<param name="module" value="night" />
</antcall>
</target>

<!--Compile the "mxml" file passed in as an argument into a .swf file -->
<target name="build-mxml-module" >
<mxmlc fork="true" maxmemory="128m" file="${src.dir}/${module}.mxml"
keep-generated-actionscript="true"
output="${dist.dir}/${module}.swf"
actionscript-file-encoding="UTF-8"
optimize="true"
debug="false"
incremental="true">
<!-- Include the necessary libraries -->
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.source-path path-element="${src.dir}"/>
<compiler.include-libraries dir="${lib.dir}" append="true">
<include name="as3crypto.swc" />
<include name="AS3IteratorImplementation.swc" />
<include name="Cairngorm.swc" />
<include name="flexunit.swc" />
<include name="flexlib-.2.1.swc" />
</compiler.include-libraries>
</mxmlc>
</target>

<!--Compile the "css" file passed in into a .swf file -->
<target name="build-css-module" >
<mxmlc fork="true" file="${src.dir}/${module}.css"
keep-generated-actionscript="true"
output="${dist.dir}/${module}.swf"
actionscript-file-encoding="UTF-8"
optimize="true"
debug="false"
incremental="true">
<!-- Include the necessary libraries -->
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.source-path path-element="${src.dir}"/>
<compiler.include-libraries dir="${lib.dir}" append="true">
<include name="as3crypto.swc" />
<include name="AS3IteratorImplementation.swc" />
<include name="as3-rpclib.swc" />
<include name="Cairngorm.swc" />
<include name="flexunit.swc" />
<include name="primitives.swc" />
<include name="util.swc" />
</compiler.include-libraries>
</mxmlc>
</target>

<target name="clean" depends='initdirs'>
<delete dir="${dist.dir}" />
</target>

<!-- Create HTML wrapper -->
<target name="wrapper" depends="compile" description="Creates the HTML wrapper">
<html-wrapper
title="Welcome to My Flex App"
file="${application.name}.html"
height="800"
width="800"
bgcolor="red"
application="app"
swf="${application.name}"
version-major="9"
version-minor="0"
version-revision="0"
history="true"
template="express-installation"
output="${dist.dir}"/>

</target>

<!-- Copy non-embedded files to output folder -->
<target name="output" depends="compile" description="Copies non-embedded files to output folder">
<!-- Copy the assets dir -->
<copy todir="${dist.dir}/assets">
<fileset dir="${assets.dir}">
</fileset>
</copy>
<!-- Copy the swf files from src dir -->
<copy todir="${dist.dir}">
<fileset dir="${src.dir}" includes="*.swf">
</fileset>
</copy>
</target>

<!-- Run all, default -->
<target name="masterbuild"
depends="clean, compile, output, wrapper"
description="Complete build in efficient sequence"/>
</project>

5 comments:

  1. Thank you for the clean structure. I have one observation, and it is based on multiple attempts. The antcall results in larger module size in comparision to multiple mxmlc tasks inside a target.

    Can you confirm your run against Flex Builder's Export Release build?

    ReplyDelete
  2. The main module compilation needs link-report and the other module compilation needs load-externs parameter specified in mxmlc. With that, release size matches with Flex Builder

    ReplyDelete
  3. Thanks tiku. I will update the post with your suggestions.

    ReplyDelete
  4. Thank you very much for sharing :-)

    ReplyDelete
  5. Only suggestion is that instead of listing out all the .swcs for the libraries, you can use:
    <include name="*.swc" >
    Thanks for the post

    ReplyDelete