Auto-generate SWC asset libraries with Apache Ant and the Flex SDK
I recently needed to create a swc library containing a large number of classes with embedded assets, so set about creating an Ant build to do the hard work for me...
Here's the situation:
I have 1000 png icons, courtesy of famfamfam, and want them available as pre-compiled classes to use, as required, in a project. The classes will all extend the same base class, the only difference being the class name and the asset that gets embedded.
So, what needs doing?
- Generate all the source classes from a template, changing the file name, class name, and embed for each image
- Compile all classes into a swc
- Delete the generated source classes
I'm assuming that, by this point, anyone reading at least knows what Ant is and is fairly familiar with the Flex SDK. If not, and you're still interested, then I'd suggest reading a little on using Ant with the Flex SDK.
Code:
build.properties...
# Build SWC asset library #
#
# Build requires ant-contrib library, included in tools/
# See readme.txt in tools/ for more details
# path to flex sdk
FLEX_HOME = C:/Program Files/Adobe/flex_sdk
# source config
src.dir = ${basedir}/../src/as
src.classesDir = madebypi/example/icons
src.packagePath = madebypi.example.icons
src.ASTemplate = ${src.dir}/${src.classesDir}/AssetClassTemplate.tpl
# asset config
assets.dir = ${basedir}/../src/assets/icons
assets.relativeDir = ../../../../assets/icons
assets.extension = png
# library config
lib.classNamePrefix = Icon_
lib.swcPath = ${basedir}/../lib/icons.swc
Unless you need to change the build functionality, build.properties is all you'll need to modify to get things working for your projects.
Build setup...
<!-- load user configuration properties -->
<property file="build.properties" />
<!-- setup flex sdk tasks -->
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
<!-- setup ant contrib tasks -->
<taskdef resource="net/sf/antcontrib/antlib.xml" />
The default task...
<!-- run everything needed to build the library, then clean-up -->
<target name="buildAssetLibrary" depends="createTemporaryClasses, build SWC, deleteTemporaryClasses">
<echo>Asset library built to ${lib.swcPath}</echo>
</target>
Generate temporary classes...
<target name="createTemporaryClasses">
<path id="assetList">
<fileset dir="${assets.dir}" includes="*.${assets.extension}"/>
</path>
<pathconvert targetos="windows" property="assetList2" pathsep="," refid="assetList">
<mapper>
<chainedmapper>
<flattenmapper/>
<globmapper from="*.${assets.extension}" to="*"/>
</chainedmapper>
</mapper>
</pathconvert>
<for param="file" list="${assetList2}">
<sequential>
<copy filtering="true" file="${src.ASTemplate}" tofile="${src.dir}/${src.classesDir}/${lib.classNamePrefix}@{file}.as">
<filterset>
<filter token="ASSET_NAME" value="@{file}"/>
<filter token="ASSET_PATH" value="${assets.relativeDir}"/>
<filter token="ASSET_EXTENSION" value="${assets.extension}"/>
</filterset>
</copy>
</sequential>
</for>
</target>
A list of file names is created from a fileset containing all the icons. Using the <pathconvert> task we reformat the references into something usable as the class name.
By including the antcontrib library, we are can use a <for> loop to iterate through the items in the list and create a copy of the template for each, replacing the tokens with real values as we copy.
Compile the library...
<!-- build the swc -->
<target name="build SWC">
<!-- get all the classes to add to the swc -->
<path id="classList">
<fileset dir="${src.dir}">
<include name="${src.classesDir}/*.as"/>
</fileset>
</path>
<!-- convert all the class file locations into a list of class-paths to pass to the include-classes paramater of compc -->
<pathconvert property="classList2" pathsep=" " dirsep="." refid="classList">
<mapper>
<chainedmapper>
<flattenmapper/>
<globmapper from="*.as" to="${src.packagePath}.*"/>
</chainedmapper>
</mapper>
</pathconvert>
<!-- compile all classes listed into a swc -->
<!-- NOTE: if you're compiling a large library swc, compc/Java may run out of memory. Increase java's heap size if this happens -->
<compc output="${lib.swcPath}" include-classes="${classList2}">
<source-path path-element="${src.dir}"/>
</compc>
</target>
All classes are added to comma-separated list to pass to the <compc> task for compilation. I had memory issues here when compiling - it would seem that the default heap size available to compc / Java is too small when building a swc with lots of classes. I had to increase it to 512 MB to get compc to compile my swc.
To change the available memory you'll need to edit your Environment Variables, add/edit the following;
name: ANT_OPTS value : -Xms512m -Xmx512m
You might get away with a value lower than 512, but that's how much I needed for this project.
Delete temporary classes...
<!-- remove the generated classes -->
<target name="deleteTemporaryClasses">
<!-- delete the temporary generated classes -->
<delete>
<fileset dir="${src.dir}">
<include name="${src.classesDir}/*.as"/>
</fileset>
</delete>
<echo>Deleted temporary classes</echo>
</target>
So, assuming you modify build.properties to meet your needs - that's it. Run the task to generate a SWC with all your pre-compiled, asset-based classes ready to go.
Get the source code here.
The archive contains a cut-down version of my project with a few icons to compile into the swc, and the template class is just a Sprite to contain the image asset.
If you have the ant-contrib tasks installed then running build.bat should make you a shiny new SWC with some icons in. If not, I've included the ant-contrib jar and a little read-me in tools/ too.
Enjoy.








[...] the next time you recompile the changes are there. You can certainly compile a SWC by checking out this blog post by MadeByPi. Personally I don’t see any great benefit one way or another except in the exact example that [...]
[...] Auto-generate SWC asset libraries with Apache Ant and the Flex SDK | MadeByPi® Blog [...]