A collection of examples of using ANT to automate building flash apps/games. It's meant to be a cook book or a learning resource, therefore each example is as small as possible and should be self-describing.
Make your build continuous integration ready!
At first of all, you have to install JRE (Java Runtime Environment). To check everything works as expected, just type $ java
to your terminal.
Then you have to download ANT from http://ant.apache.org/bindownload.cgi. Just extract the downloaded .zip file into the, let's say ~/sdks/ant
directory, set ANT_HOME
environment variable to this location and add ANT_HOME
to PATH
:
${ANT_HOME}/bin
(MacOS) or %ANT_HOME%/bin
(Windows)
To check everything works as expected, just type $ ant
to your terminal.
If you are using MacOS you can install ANT with brew:
$ brew install ant
If you are using Adobe Flash Builder 4.7, you can find the AIR SDK at /Applications/Adobe Flash Builder 4.7/eclipse/plugins/com.adobe.flash.compiler_4.7.0.349722
(MacOS) or C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flash.compiler_4.7.0.349722
(Windows).
Otherwise, you can download it from http://www.adobe.com/devnet/air/air-sdk-download.html. Just extract it into the, let's say ~/sdks/air
directory.
If you are using Adobe Flash Builder 4.7, you can find the Flex SDKs directory at <FlashBuilder_installation_location>/sdks
.
Otherwise, you have to download and install it manually. I personally prefer release by Adobe, which can be downloaded from http://www.adobe.com/devnet/flex/flex-sdk-download.html. Just extract it into the, let's say ~/sdks/flex
directory. But you may want to use the latest version of the Flex SDK, which is currently developed by Apache. If so, you can install it using their http://flex.apache.org/installer.html.
You should set the FLEX_HOME
environment variable and add it to PATH
.
You use the application compiler to compile SWF files from your ActionScript and/or MXML source files.
You use the component compiler to generate a SWC file from component source files and other asset files such as images and style sheets.
You can compile the ActionScript and MXML assets of your AIR application with the command line MXML compiler (amxmlc).
Use the component compiler, acompc, to compile AIR libraries and independent components.
ASDoc is a command-line tool that you can use to create API language reference documentation as HTML pages from the ActionScript classes and MXML files.
The AIR Developer Tool is a multi-purpose, command-line tool for developing AIR applications. You can use ADT to perform the following tasks:
- Package an AIR application as an .air installation file
- Package an AIR application as a native installer—for example, as a .exe installer file on Windows, .ipa on iOS, or .apk on Android
- Package a native extension as an AIR Native Extension (ANE) file
- Sign an AIR application with a digital certificate
- Change (migrate) the digital signature used for application updates
- Determine the devices connected to a computer
- Create a self-signed digital code signing certificate
- Remotely install, launch, and uninstall an application on a mobile device
- Remotely install and uninstall the AIR runtime on a mobile device
Use the AIR Debug Launcher to run both SWF-based and HTML-based applications during development. Using ADL, you can run an application without first packaging and installing it. By default, ADL uses a runtime included with the SDK, which means you do not have to install the runtime separately to use ADL.
The most simple ANT build.xml file, which describes how to build an bin/output.swc
file:
<?xml version="1.0"?>
<project name="swc example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<compc output="${DEPLOY.dir}/output.swc" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
<include-sources dir="${basedir}/src" includes="*"/>
</compc>
</target>
</project>
Let's say, that the project contains a libs
directory with linked .swc libraries. We have to tell to compc where to find them:
<?xml version="1.0"?>
<project name="swc example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<compc output="${DEPLOY.dir}/output.swc" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
<include-sources dir="${basedir}/src" includes="*"/>
<library-path dir="${basedir}/libs" includes="*" append="true"/>
</compc>
</target>
</project>
Or if we want to specify an .swc file located anywhere:
<?xml version="1.0"?>
<project name="swc example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<compc output="${DEPLOY.dir}/output.swc" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
<include-sources dir="${basedir}/src" includes="*"/>
<library-path file="lib.swc" append="true"/>
</compc>
</target>
</project>
Now we are using custom metadata and we want to keep them in compiled application (the default behavior is that they are removed them to keep the application/library as small as possible):
<?xml version="1.0"?>
<project name="swc example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<compc output="${DEPLOY.dir}/output.swc" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
<include-sources dir="${basedir}/src" includes="*"/>
<library-path dir="${basedir}/libs" includes="*" append="true"/>
<keep-as3-metadata name="Inject"/>
<keep-as3-metadata name="PostConstruct"/>
<keep-as3-metadata name="ArrayElementType"/>
</compc>
</target>
</project>
<compc ... target-player="11.4" swf-version="17"/>
Do not forget to check if FLEX_HOME/frameworks/libs/player/<target-version>/playerglobal.swc
and ${FLEX_HOME}/runtimes/player/<target-version>/.../FlashPlayerDebugger
exist. You can find all released versions of playerglobal.swc and Flash Player Debuggers at http://helpx.adobe.com/flash-player/kb/archived-flash-player-versions.html.
swf-version | target-player |
---|---|
9 | 9 |
10 | 10.0, 10.1 |
11 | 10.2 |
12 | 10.3 |
13 | 11.0 |
14 | 11.1 |
15 | 11.2 |
16 | 11.3 |
17 | 11.4 |
18 | 11.5 |
19 | 11.6 |
20 | 11.7 |
21 | 11.8 |
22 | 11.9 |
23 | 12.0 |
24 | 13.0 |
25 | 14.0 |
26 | 15.0 |
27 | 16.0 |
Let's take a look at the compc options. If you are intrested in more detailed informations, you can dump out config, size report and link report:
<compc ... dump-config="${DEPLOY.dir}/config.xml" size-report="${DEPLOY.dir}/sizereport.xml" link-report="${DEPLOY.dir}/linkreport.xml">
To disable warnings:
<compc ... warnings="false">
If you are building a lot of applications/libraries, you can exhaust the memory. Very useful is set fork option to true, which should solve, especially with maxmemory set to at least one gig, everything:
<compc ... fork="true">
The most simple ANT build.xml file, which describes how to build a bin/output.swf
file:
<?xml version="1.0"?>
<project name="swf example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<mxmlc file="${basedir}/src/Main.mxml" output="${DEPLOY.dir}/output.swf" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
</mxmlc>
</target>
</project>
The mxmlc compiler offers almost the same options as the compc compiler does. Each example described in Building SWC section can be easily changed to mxmlc command. Compare Example 1 with Example 9 and you'll see.
The most simple ANT build.xml file, which describes how to build an bin/output.swf
file:
<?xml version="1.0"?>
<project name="swf example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<mxmlc
file="${basedir}/src/Main.as"
output="${DEPLOY.dir}/output.swf"
static-link-runtime-shared-libraries="true"
failonerror="true"
maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
</mxmlc>
</target>
</project>
The mxmlc compiler offers almost the same options as the compc compiler does. Each example described in Building SWC section can be easily changed to mxmlc command. Compare Example 1 with Example 10 and you'll see.
The most simple ANT build.xml file, which describes how to build an bin/output.swf
file:
<?xml version="1.0"?>
<project name="swf example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<target name="main" depends="clean, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
</target>
<target name="compile">
<mxmlc file="${basedir}/src/Main.as" output="${DEPLOY.dir>/output.swf" configname="air" failonerror="true">
<library-path dir="${FLEX_HOME}" append="true">
<include name="frameworks/libs"/>
</library-path>
<library-path dir="${FLEX_HOME}" append="true">
<include name="frameworks/libs/air"/>
</library-path>
</mxmlc>
</target>
</project>
The mxmlc compiler offers almost the same options as the compc compiler does. Each example described in Building SWC section can be easily changed to mxmlc command. Compare Example 1 with Example 11 and you'll see.
Quick download links: Apache FlexUnit 4.2, FlexUnit 4.1
Do not forget to add
CIListener
to yourFlexUnitCore
instance.
<?xml version="1.0"?>
<project name="swf example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<taskdef resource="flexUnitTasks.tasks">
<classpath>
<fileset dir="<path_to_flex_unit_ant_tasks_dir>">
<include name="flexUnitTasks*.jar"/>
</fileset>
</classpath>
</taskdef>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<property name="TESTS.dir" value="${basedir}/tests-output"/>
<target name="main" depends="clean, tests, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
<delete dir="${TESTS.dir}"/>
<mkdir dir="${TESTS.dir}"/>
</target>
<target name="tests">
<mxmlc file="${basedir}/src/tests.mxml" output="${TESTS.dir}/tests.swf" failonerror="true" verbose-stacktraces="true">
<source-path path-element="${basedir}/src"/>
<library-path dir="${basedir}/libs" includes="*" append="true"/>
</mxmlc>
<flexunit
swf="${TESTS.dir}/tests.swf"
toDir="${TESTS.dir}"
haltonfailure="false" failureproperty="flexunit.failure"
verbose="true"
localTrusted="true"
command="${FLEX_HOME}/runtimes/player/11.4/win/FlashPlayerDebugger.exe"/>
<junitreport todir="${TESTS.dir}">
<fileset dir="${TESTS.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${TESTS.dir}/html"/>
</junitreport>
</target>
<target name="compile">
<mxmlc file="${basedir}/src/Main.mxml" output="${DEPLOY.dir}/output.swf" failonerror="true" maxmemory="1024m">
<source-path path-element="${basedir}/src"/>
</mxmlc>
</target>
</project>
Do not forget to add
AIRCIListener
to yourFlexUnitCore
instance.
<?xml version="1.0"?>
<project name="swf example" default="main" basedir=".">
<taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant"/>
<taskdef resource="flexUnitTasks.tasks">
<classpath>
<fileset dir="<path_to_flex_unit_ant_tasks_dir>">
<include name="flexUnitTasks*.jar"/>
</fileset>
</classpath>
</taskdef>
<property name="DEPLOY.dir" value="${basedir}/bin"/>
<property name="TESTS.dir" value="${basedir}/tests-output"/>
<target name="main" depends="clean, tests, compile"/>
<target name="clean">
<delete dir="${DEPLOY.dir}"/>
<mkdir dir="${DEPLOY.dir}"/>
<delete dir="${TESTS.dir}"/>
<mkdir dir="${TESTS.dir}"/>
</target>
<target name="test">
<mxmlc file="${basedir}/src/tests.as" output="${TESTS.dir}/tests.swf" configname="air" failonerror="true" verbose-stacktraces="true">
<library-path dir="${basedir}/libs"includes="*"append="true"/>
<library-path dir="${FLEX_HOME}"append="true">
<include name="frameworks/libs"/>
</library-path>
<library-path dir="${FLEX_HOME}" append="true">
<include name="frameworks/libs/air"/>
</library-path>
</mxmlc>
<copy file="${basedir}/src/tests-app.xml" todir="${TESTS.dir}" overwrite="true"/>
<replace file="${TESTS.dir}/tests-app.xml" token="[This value will be overwritten by Flash Builder in the output app.xml]" value="tests.swf"/>
<flexunit
player="air"
swf="${TESTS.dir}/tests.swf"
toDir="${TESTS.dir}"
haltonfailure="false" failureproperty="flexunit.failure"
verbose="true"/>
<junitreport todir="${TESTS.dir}">
<fileset dir="${TESTS.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${TESTS.dir}/html"/>
</junitreport>
</target>
<target name="compile">
<mxmlc file="${basedir}/src/Main.as" output="${DEPLOY.dir>/output.swf" configname="air" failonerror="true">
<library-path dir="${FLEX_HOME}" append="true">
<include name="frameworks/libs"/>
</library-path>
<library-path dir="${FLEX_HOME}" append="true">
<include name="frameworks/libs/air"/>
</library-path>
</mxmlc>
</target>
</project>
...
<target name="pack">
<copy file="${basedir}/src/swf2png-app.xml" todir="${DEPLOY.dir}" overwrite="true"/>
<replace file="${DEPLOY.dir}/swf2png-app.xml" token="[This value will be overwritten by Flash Builder in the output app.xml]" value="swf2png.swf"/>
<exec executable="${FLEX_HOME}/bin/adt.bat" failonerror="true">
<arg line="-package"/>
<arg line="-storetype pkcs12"/>
<arg line="-keystore ${basedir}/certificate.p12"/>
<arg line="-storepass <password>"/>
<arg line="${DEPLOY.dir}/swf2png.air"/>
<arg line="${DEPLOY.dir}/swf2png-app.xml"/>
<arg line="-C ${DEPLOY.dir} swf2png.swf"/>
</exec>
</target>
...
Generate ASDoc to a temp dir and update the .swc file with it.
...
<target name="asdoc">
<tempfile property="temp.dir" destDir="${java.io.tmpdir}" prefix="${ant.project.name}-doc-xml-" />
<asdoc output="${temp.dir}" lenient="true" failonerror="true" keep-xml="true" skip-xsl="true" fork="true">
<compiler.source-path path-element="${basedir}/src" />
<doc-sources path-element="${basedir}/src" />
</asdoc>
<zip destfile="${DEPLOY.dir}/${ant.project.name}.swc" update="true">
<zipfileset dir="${temp.dir}/tempdita" prefix="docs">
<include name="*.*"/>
<exclude name="ASDoc_Config.xml" />
<exclude name="overviews.xml" />
</zipfileset>
</zip>
<delete dir="${temp.dir}" failonerror="false" includeEmptyDirs="true" />
</target>
...
FlexPMD is a source code analyzer. It finds common programming flaws like unused variables, empty catch blocks, unnecessary object creation, and so forth.
To generate a pmd_ruleset.xml
use the online pmd ruleset creator.
Quick download link: Adobe FlexPMD 1.3
...
<property name="FLEXPMD.dir" value="~/sdks/flexpmd"/>
<property name="FLEXPMD.version" value="1.3"/>
<taskdef name="flexPmd"
classname="com.adobe.ac.pmd.ant.FlexPmdAntTask"
classpath="${FLEXPMD.dir}/flex-pmd-ant-task-${FLEXPMD.version}.jar">
<classpath>
<pathelement location="${FLEXPMD.dir}/flex-pmd-ruleset-api-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/flex-pmd-ruleset-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/flex-pmd-core-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-plugin-utils-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-parser-api-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-parser-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/pmd-4.2.5.jar"/>
<pathelement location="${FLEXPMD.dir}/commons-lang-2.4.jar"/>
<pathelement location="${FLEXPMD.dir}/flex-pmd-files-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/flex-pmd-metrics-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/plexus-utils-1.0.2.jar"/>
<pathelement location="${flexpmd.libs}/dom4j-1.6.1.jar"/>
</classpath>
</taskdef>
<taskdef name="flexCpd"
classname="com.adobe.ac.cpd.ant.FlexCpdAntTask"
classpath="${FLEXPMD.dir}/flex-pmd-cpd-ant-task-${FLEXPMD.version}.jar">
<classpath>
<pathelement location="${FLEXPMD.dir}/flex-pmd-files-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/flex-pmd-cpd-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-plugin-utils-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-parser-api-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/as3-parser-${FLEXPMD.version}.jar"/>
<pathelement location="${FLEXPMD.dir}/pmd-4.2.5.jar"/>
</classpath>
</taskdef>
...
<target name="flexPmd">
<flexPmd
sourceDirectory="${basedir}"
outputDirectory="${DEPLOY.dir}"
ruleSet="${basedir}/pmd_ruleset.xml"/>
</target>
<target name="flexCpd">
<flexCpd
minimumTokenCount="50"
outputFile="${DEPLOY.dir}/cpd.xml">
<fileset dir="${basedir}">
<include name="**/*.as"/>
<include name="**/*.mxml"/>
<exclude name="vendor/**" />
</fileset>
</flexCpd>
</target>
...
Do not repeat yourself, use ${ant.project.name}
as can be seen in Example 15 - generating ASDoc.
When you run your FlexUnit tests on CI machine and any test fails, your build ends. But it ends before the report generation, so your statistics can't be updated and you don't know which test fails and why. Therefore flexunit task offers failureproperty
:
...
<target name="test">
<mxmlc file="${basedir}/src/tests.mxml" output="${TESTS.dir}/tests.swf" failonerror="true" verbose-stacktraces="true">
<source-path path-element="${basedir}/src"/>
<library-path dir="${basedir}/libs" includes="*" append="true"/>
</mxmlc>
<flexunit
swf="${TESTS.dir}/tests.swf"
toDir="${TESTS.dir}"
haltonfailure="false" failureproperty="flexunit.failure"
verbose="true"
localTrusted="true"
command="${FLEX_HOME}/runtimes/player/11.4/win/FlashPlayerDebugger.exe"/>
<junitreport todir="${TESTS.dir}">
<fileset dir="${TESTS.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${TESTS.dir}/html"/>
</junitreport>
<fail if="flexunit.failure" message="Unit test(s) failed. See reports!"/>
</target>
...
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License