Once you’ve created a project and written some code, you’ll want
to build the project, which means compiling it and deploying it. How you
accomplish these tasks depends, in part, on what tools you’re using. The
following sections discuss how to compile using the mxmlc
compiler. If you’re using Flex Builder,
you may want to skip directly to Compiling Using Flex Builder” later in this chapter, although
it is always good to know about mxmlc
,
especially if you intend to use Ant or any build tool.
The mxmlc
compiler is used to compile Flex applications (versus compc
, which is used to compile components and
libraries). When you use Flex Builder to compile, it automatically calls
mxmlc
(Flex Builder includes the
SDK).
There are several ways you can use mxmlc
, including from the command line, from a
.bat or shell script, from an IDE,
and from Apache Ant. Initially, we’ll look at using mxmlc
from the command line since it’s the
most basic way to use the compiler (though we’ll also look at using the
compiler via Apache Ant later in this chapter). The compiler flags we’ll
look at from the command line also apply to any other use of the
compiler.
When you want to work with mxmlc
from the command line, it’s generally
a good idea to make sure you add it to your system path. If you’re
running Windows and you’re uncertain how to edit your system
path, follow these steps:
Right-click My Computer from the desktop or from the Start menu, and select Properties.
Click the Advanced tab, and then click the Environment Variables button.
In the System Variables list in the bottom part of the dialog, scroll until you see a variable called Path. Then edit the variable either by double-clicking on it or by selecting it and then clicking the Edit button.
At the end of the existing value, add the path to the Flex
SDK’s bin directory. If
you’re using Flex Builder, the default location is C:Program FilesAdobeFlex Builder 3sdks<sdk
version>. If you’re using the SDK and you installed
the SDK in C:FlexSDK, the
location is C:FlexSDKin.
Windows uses a semicolon (;
) as
a delimiter. If necessary, add a semicolon between the existing
value and the new addition.
Click OK on each open dialog.
For OS X and Linux, you’ll want to set the PATH
environment variable in your shell. If you are using .bash or any shell that supports .profile files, you will want to add a
.profile file in your user
directory (or edit the file if it already exists). You can edit the
file with any text editor that you want. If you are familiar with
vi, for example, you can simply open a Terminal
and type vi ~/.profile
. The
.profile should contain a line
such as the following:
export PATH=$PATH:/Users/username
/FlexSDK/bin
The preceding line of code assumes that you have installed the
SDK in your user directory (you’ll need to change
username
to your actual username). If
you’ve installed the SDK elsewhere, you should modify the path
correspondingly. Also note that the preceding code assumes that you
don’t want to add additional directories to your path. If you have an
existing .profile file that
already contains an export PATH
line, you should simply append the Flex bin path to that line using a colon
(:
) as a delimiter. For
example:
export PATH=$PATH:/existing/directories:/Users/username
/FlexSDK/bin
Once you’ve edited the .profile you’ll need to run the following command from any existing Terminal window or command prompt:
source ~/.profile
To use the compiler from the command line you simply
specify the compiler name followed by the options. The only required
option is called file-specs
, and it
allows you to specify the entry point to the application you want to
compile, that is, the main MXML document (or ActionScript
class):
mxmlc -file-specs SampleApplication.mxml
Notice that file-specs
is
preceded by a hyphen. All options are preceded by a hyphen.
The file-specs
option is the
default option for mxmlc
. That
means a value that is not preceded by an option flag will be
interpreted as the value for file-specs
. The following example is
equivalent to the preceding example:
mxmlc SampleApplication.mxml
The examples that follow attempt to compile SampleApplication.mxml to SampleApplication.swf.
By default, mxmlc
compiles the application to an .swf with the same name as the input file
(i.e., SampleApplication.mxml
compiles to SampleApplication.swf) in the same
directory as the input file. However, you can specify an output path
and .swf name using the output
option. The following compiles
SampleApplication.mxml to
bin/main.swf:
mxmlc SampleApplication.mxml -output bin/main.swf
The source path is the path in which the compiler looks for
required MXML and ActionScript
files. By default, the compiler looks in the same directory as the
compile target (the file specified by file-specs
). This means it will also look in
subdirectories for documents and classes that are in packages.
However, any files located outside the same directory structure won't
be found using the default source path compiler settings.
You can use the source-path
option to specify one or more directories in which the compiler should
look for the MXML and ActionScript files. You can specify a list of
directories by using spaces between directories. The following example
looks for files in the current directory as well as in C:FlexApplicationCommonLibraries:
mxmlc -source-path . C:FlexApplicationCommonLibraries -file-specs SampleApplication.mxml
The default background color is the blue you see for most Flex
applications. Use the default-background-color
option to customize
the background value. You can specify the value using 0x-prefixed
hexadecimal representation in the form of RRGGBB. Use this in cases
where you customize the appearance of an application and want the
initial color seen by the user to match the overall look of your
application. The following sets the default background color of
SampleApplication to
white:
mxmlc -default-background-color=0xFFFFFF SampleApplication.mxml
Note that the background color in this case is the background
color of Flash Player. A Flex application being deployed to the Web
has several places where its background is set. There is the
background color in the HTML document, the .swf file, and the Flex root container.
Setting the
compiler setting will set only the background color of the .swf file. The most common way to set the
background color for all three values is to set the root -default-background-colorph
Application
tag’s
backgroundProperty
style. Setting the value of this
style will instruct the Flex compiler to set the values of the root
container (Application
), the
.swf file, and the HTML
document background if you are using the provided templates.
Flash Player automatically places restrictions on script execution in an attempt to prevent applications from crashing client systems. This means that if too many levels of recursion occur, or if a script takes too long to execute, Flash Player will halt the script.
The default-script-limits
option allows you to customize each of these settings. The option
requires two values: one for the maximum level of recursion and one
for the maximum script execution time. The default maximum level of
recursion is 1000, and the default maximum script execution time is 60
seconds (you cannot specify a value larger than 60 for this
parameter):
mxmlc -default-script-limits 200 15 -file-specs SampleApplication.mxml
Although it’s important to know about the existence of
default-script-limits
, it’s also
important to know that it should rarely be used. If you have to
increase the default-script-limits
setting for an
application to avoid an error, frequently it’s because there is a
problem in the code or in the application logic.
The .swf format allows you
to encode metadata in the application file. The allowable metadata includes the following: title
, description
, creator
, publisher
, language
, and date
. You can set these values using options
with the same names as the metadata elements:
mxmlc -title "Sample Application" -description "A Flex Sample Application" -file- specs SampleApplication.mxml
By default, when you compile from the command line, mxmlc
compiles a clean build every time.
That means that it recompiles every source file, even if it hasn’t
changed since you last compiled. That is because by default, mxmlc
doesn’t have a way of knowing what has
changed and what hasn’t.
There are times when a clean build is exactly the behavior you
want from mxmlc
. However, in most
cases you’ll find that it’s faster to use incremental builds. An incremental build is
one in which the compiler recompiles only those elements that have
changed since you last compiled. For all other elements it uses the
previously compiled versions. Assuming that not much has changed since
the previous compile, an incremental build can be much faster than a
clean build.
If you want to use incremental builds, you need a way to
determine what things have changed between builds. When you set the
-incremental
option to true
, mxmlc
writes to a file in the same directory
as the target file you are compiling, and it shares the same name. The
name of the cache file is TargetFile_<#>.cache, in which the
#
is a number generated by the compiler.
For example, the following might write to a file called SampleApplication_302345.cache (where the
number is determined by the compiler):
mxmlc -incremental=true -file-specs SampleApplication.mxml
Although it is undoubtedly great fun to specify compiler options
on the command line, you can also store settings in configuration
files. You can then specify the configuration file as a single option
from the command line. The load-config
option lets you specify the file
you want to load to use as the configuration file:
mxmlc -load-config=configuration.xml SampleApplication.mxml
By default, mxmlc
uses a
configuration file called flex-config.xml located in the frameworks directory of the SDK or Flex
Builder installation. If you specify a value for the load-config
option, that can override
flex-config.xml. Many, though not
all, of the settings in flex-config.xml are required. That means
it’s important that you do one of the following:
Copy and modify the content of flex-config.xml for use in your custom configuration file. When you do so, you will likely have to modify several values in the file so that they point to absolute paths rather than relative paths. Specifically, you have to modify:
The <external-library-path>
setting from the relative libs/playerglobal.swc to a valid
path pointing to the actual .swc file
The <library-path>
settings from
libs
and locale/{locale}
to the valid paths
pointing to those resources (you can keep the {locale}
variable)
Load your custom file in addition to the default. When you
use the =
operator to assign a
value to the load-config
option, you load the file in place of the default. When you use
the +=
operator, you load the
file in addition to the default. Any values specified in the
custom configuration file override the same settings in the
default file:
mxmlc -load-config+=configuration.xml SampleApplication.mxml
Configuration files must have exactly one root node, and that
root node must be a <flex-config>
tag. The <flex-config>
tag should define a
namespace, as in the following example:
<flex-config xmlns="http://www.adobe.com/2006/flex-config"> </flex-config>
Within the root node you can nest nodes corresponding to
compiler options. You can configure any and every compiler option from
a configuration file. However, the option nodes must appear in the
correct hierarchy. For example, some option nodes must appear within a
<compiler>
tag, and others
must appear within a <metadata>
tag. You can determine the
correct hierarchy from the compiler help.
The following is a list of the options returned by mxmlc -help list advanced
:
-benchmark -compiler.accessible -compiler.actionscript-file-encoding <string> -compiler.allow-source-path-overlap -compiler.as3 -compiler.context-root <context-path> -compiler.debug -compiler.defaults-css-files [filename] [...] -compiler.defaults-css-url <string> -compiler.define <name> <value> -compiler.es -compiler.external-library-path [path-element] [...] -compiler.fonts.advanced-anti-aliasing -compiler.fonts.flash-type -compiler.fonts.languages.language-range <lang> <range> -compiler.fonts.local-fonts-snapshot <string> -compiler.fonts.managers [manager-class] [...] -compiler.fonts.max-cached-fonts <string> -compiler.fonts.max-glyphs-per-face <string> -compiler.headless-server -compiler.include-libraries [library] [...] -compiler.incremental -compiler.keep-all-type-selectors -compiler.keep-as3-metadata [name] [...] -compiler.keep-generated-actionscript -compiler.library-path [path-element] [...] -compiler.locale [locale-element] [...] -compiler.mxml.compatibility-version <version> -compiler.namespaces.namespace <uri> <manifest> -compiler.optimize -compiler.services <filename> -compiler.show-actionscript-warnings -compiler.show-binding-warnings -compiler.show-shadowed-device-font-warnings -compiler.show-unused-type-selector-warnings -compiler.source-path [path-element] [...] -compiler.strict -compiler.theme [filename] [...] -compiler.use-resource-bundle-metadata -compiler.verbose-stacktraces -compiler.warn-array-tostring-changes -compiler.warn-assignment-within-conditional -compiler.warn-bad-array-cast -compiler.warn-bad-bool-assignment -compiler.warn-bad-date-cast -compiler.warn-bad-es3-type-method -compiler.warn-bad-es3-type-prop -compiler.warn-bad-nan-comparison -compiler.warn-bad-null-assignment -compiler.warn-bad-null-comparison -compiler.warn-bad-undefined-comparison -compiler.warn-boolean-constructor-with-no-args -compiler.warn-changes-in-resolve -compiler.warn-class-is-sealed -compiler.warn-const-not-initialized -compiler.warn-constructor-returns-value -compiler.warn-deprecated-event-handler-error -compiler.warn-deprecated-function-error -compiler.warn-deprecated-property-error -compiler.warn-duplicate-argument-names -compiler.warn-duplicate-variable-def -compiler.warn-for-var-in-changes -compiler.warn-import-hides-class -compiler.warn-instance-of-changes -compiler.warn-internal-error -compiler.warn-level-not-supported -compiler.warn-missing-namespace-decl -compiler.warn-negative-uint-literal -compiler.warn-no-constructor -compiler.warn-no-explicit-super-call-in-constructor -compiler.warn-no-type-decl -compiler.warn-number-from-string-changes -compiler.warn-scoping-change-in-this -compiler.warn-slow-text-field-addition -compiler.warn-unlikely-function-value -compiler.warn-xml-class-has-changed -debug-password <string> -default-background-color <int> -default-frame-rate <int> -default-script-limits <max-recursion-depth> <max-execution-time> -default-size <width> <height> -dump-config <filename> -externs [symbol] [...] -frames.frame [label] [classname] [...] -help [keyword] [...] -include-resource-bundles [bundle] [...] -includes [symbol] [...] -licenses.license <product> <serial-number> -link-report <filename> -load-config <filename> -load-externs <filename> -metadata.contributor <name> -metadata.creator <name> -metadata.date <text> -metadata.description <text> -metadata.language <code> -metadata.localized-description <text> <lang> -metadata.localized-title <title> <lang> -metadata.publisher <name> -metadata.title <text> -output <filename> -raw-metadata <text> -resource-bundle-list <filename> -runtime-shared-libraries [url] [...] -runtime-shared-library-path [path-element] [rsl-url] [policy-file-url] [rsl-url] [policy-file-url] -static-link-runtime-shared-libraries -target-player <version> -use-network -verify-digests -version -warnings
You’ll notice that some of the options you already know, such as
incremental
and title
, are prefixed (e.g., compiler.incremental
and metadata.title
). These prefixed commands are
the full commands. The compiler defines aliases that you can use from
the command line. That way, the compiler knows when you type
incremental
, you really mean
compiler.incremental
. However, when
you use a configuration file, you must use the full option names.
Prefixes translate to parent nodes. For example, the following sets
the incremental
option to true
and the title
option to Example
:
<flex-config xmlns="http://www.adobe.com/2006/flex-config"> <compiler> <incremental>true</incremental> </compiler> <metadata> <title>Example</title> </metadata> </flex-config>
In the options list you’ll notice that some options are followed
by a value enclosed in <>
.
For example, the title
option is
followed by <text>
. These
values indicate that the option value should be a string. For example,
as you can see in the preceding sample code, the <title>
tag has a nested string value
of Example
. If an option is
followed by two or more <value>
values, the option node should
contain child tags with the specified names. For example, the localized-title
option is followed by
<text> <lang>
.
Therefore, the following is an example of a configuration file that
correctly describes the localized-title
option:
<flex-config xmlns="http://www.adobe.com/2006/flex-config"> <metadata> <localized-title> <text>Example</text> <lang>en_US</lang> </localized-title> </metadata> </flex-config>
If an option is followed by [value]
[...]
, it means the option node must contain one or more
tags with the name specified. For example, file-specs
is followed by [path-element] [...]
. This means that the
following is a valid configuration file specifying a file-specs
value:
<flex-config xmlns="http://www.adobe.com/2006/flex-config"> <file-specs> <path-element>Example.mxml</path-element> </file-specs> </flex-config>
The following example is also a valid configuration file. This time, it defines several target files to compile.
<flex-config xmlns="http://www.adobe.com/2006/flex-config"> <file-specs> <path-element>Example.mxml</path-element> <path-element>Example2.mxml</path-element> <path-element>Example3.mxml</path-element> <path-element>Example4.mxml</path-element> </file-specs> </flex-config>
When an option is not followed by anything, it indicates that
the value should be Boolean. For example, incremental
is not followed by anything in
the list.
If you would like to get more details on each compiler option,
you can review the help documentation provided with Flex as well as
issue a help command for a single command. For example, if you want to
find what the -use-network
command
is for, you would issue:
mxmlc -help use-network
Using the compiler from the command line is not the best way to build applications, for the following reasons:
It’s inconvenient because you have to open a command line and type the command each time.
Because you have to type the command each time, there’s a greater chance of introducing errors.
Not only is opening a command line and typing a command inconvenient, but it’s also slow.
Compiling from the command line doesn’t allow you much in the way of features, such as copying and deploying files, testing for dependencies, and so on.
A standard tool used by application developers for scripting application builds is a program called Apache Ant. Ant is an open source tool that runs on Java to automate the build process. This includes testing for dependencies (e.g., the existence of directories), compiling, moving, and copying files, and launching applications. Although you can use .bat files or shell scripts to achieve many of Ant’s basic tasks, Ant is extremely feature-rich (it offers support for compressing and uncompressing archives, email support, and FTP support, to name just a few) and can better handle potential errors than .bat or shell scripts.
If you’re not familiar with Ant, the first thing you should do is
to download and install Ant from http://ant.apache.org. Once you’ve installed Ant, you
should add a new environment variable, called ANT_HOME
, as well as the Ant bin directory to the system path. The
ANT_HOME
environment variable should
point to the root directory of the Ant installation on the computer. For
example, if Ant is installed at C:Ant on a Windows system, the ANT_HOME
environment variable should point to
C:Ant. Additionally, you should
add the Ant bin directory to the
system path. For example, if Ant is installed at C:Ant, add C:Antin to the system path.
Ant works by executing a set of tasks, and by default it does not include a task for compiling
Flex applications. We could use a task to manually invoke the mxmlc
compiler, as we would via the command
line, but instead Adobe has provided us a set of Flex tasks to simplify
Ant use. The tasks allow you to invoke mxmlc
and compc
and generate an HTML wrapper. The tasks
are included within the SDK distribution in <sdk dir>ant. Installing the provided
tasks is easy. You simply copy the <sdk
dir>antlibflexTasks.jar file to your lib folder within your Ant installation. Once
the file is installed, Ant will recognize the new tasks. Ant uses XML
files named build.xml. The build.xml file
for a project contains all the instructions that tell Ant how to compile
and deploy all the necessary files (e.g., the application). The
build.xml file consists of a
<project>
root node that
contains nested target nodes. The project node allows you to define three attributes:
name
The name of the project
default
The name of the target to run when no other target is specified
basedir
The directory to use for all relative directory calculations
For our sample build.xml, the
<project>
node looks like this
to start:
<?xml version="1.0" encoding="utf-8"?> <project name="FlexTest" default="compile" basedir="./"> </project>
This says that the base directory is the directory in which the
file is stored, and the default target is called compile
. Once the <project>
root node is set up, you need
to instruct Ant to load the Flex tasks and set some basic properties
that every Ant build file must contain:
<?xml version="1.0" encoding="utf-8"?> <project name="FlexTest" default="compile" basedir="./"> <taskdef resource="flexTasks.tasks" classpath="${basedir}/flexTasks/lib/flexTasks.jar"/> <property name="FLEX_HOME" value="C:/flex/sdk"/> <property name="APP_ROOT" value="myApp"/> </project>
The basic setup of a build file is now complete. FLEX_HOME
and APP_ROOT
are Ant properties that will be useful when configuring tasks later on. As
when you declare a variable in code, it is common practice to define
properties in Ant in a single location toward the top and to reference
them throughout, as we will see in a bit. You can declare any property
you wish, but it is common to create at least these two. FLEX_HOME
should point to the Flex sdk
root, and APP_ROOT
should reference your application
directory.
Now that we have a basic build file ready, the final step is to
set up a <target>
within the
<project>
node. Multiple <target>
nodes can exist within a build file, and each target node represents a
named collection of tasks. Ant tasks could involve compiling an
application, moving files, creating directories, launching applications,
creating ZIP archives, using FTP commands, and so on. You can read all
about the types of tasks available within Ant at http://ant.apache.org/manual/tasksoverview.html. The
following defines the compile
target for our
sample build.xml file, which makes
use of the newly installed task, mxmlc
:
<?xml version="1.0" encoding="utf-8"?> <project name="FlexTest" default="compile" basedir="./"> <taskdef resource="flexTasks.tasks" classpath="${basedir}/flexTasks/lib/flexTasks.jar"/> <property name="FLEX_HOME" value="C:/flex/sdk"/> <property name="APP_ROOT" value="myApp"/> <target name="compile"> <mxmlc file="${APP_ROOT}/FlexTest.mxm"> <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/> <source-path path-element="${FLEX_HOME}/frameworks"/> </target> </project>
This compile
target runs by
default because it is set as the default for the project. When you run
the Ant build, the compile
target
runs the mxmlc
task. Nested within
the <mxmlc>
tag you specify the
framework and Flex configuration using the
and
<load-config>
<source-path>
nodes. In this
build file, we didn’t specify that you can place one or more <arg>
tags that allow you to add
arguments to the command. In this case, we’re simply adding the file-specs
option when calling the
compiler.
Once you have a valid build.xml file you can run it from the
command line by running the ant
command from the same directory as the file:
ant
This runs the default target in the build.xml file located in the same directory. To run a nondefault target, you can specify the target name after the command. To run several targets, specify each target in a list, separated by spaces:
ant target1 target2
Ant integrates well with most IDEs and is often the preferred choice for build environments. Full coverage of Ant is beyond the scope of this book. For further information on Ant you can review http://ant.apache.org/, and for Flex-specific coverage you can review the documentation provided with the Flex SDK.
If you work with Flex Builder, you can use the built-in options for building. Flex Builder automatically compiles your application for development purposes as you work, but the application produced by this automatic compilation is not suitable for deployment as it contains debug code that you will want to avoid for deployment unless you intend to debug in a production environment. To compile a production-ready application, use the Export Releaser Build option in the Project→Export release build menu item. By default, the compiled application will be placed in the bin-release folder of your Flex project.
Flex Builder runs the application in your default web browser unless you configure it to do otherwise. You can configure what web browser Flex Builder uses by selecting Window→Preferences→General→Web Browser.
Flex Builder builds all projects incrementally by default in debug mode within the bin-debug folder. That means it compiles only the elements that have changed since the last build. If you need to recompile all the source code, you need to clean the project, meaning that you instruct the compiler to recompile every necessary class, not just those that have changed since the last compile. You can do that by selecting Project→Clean. This opens the Clean dialog. The Clean dialog has two options: “Clean all projects” and “Clean projects selected below.” If you select “Clean projects selected below,” it cleans only the projects that you have selected in the list that appears in the dialog. Flex Builder then builds the project or projects the next time it is prompted, either by automatic triggers (saving a file) or when explicitly directed to run a build.
If you want to manually control a build, you must disable the automatic build feature by deselecting Project→Build Automatically. You can then select the Build All, Build Project, or Build Working Set option from the Project menu to manually run a build. The automatic build option is convenient for smaller projects that compile quickly. However, it’s frequently helpful to disable automatic build for larger projects that require more time to compile. In such cases, the automatic build feature can cause delays every time you save a file rather than allowing you to build on demand.
Since Flex applications are compiled, the source code for the application is not available by default. This is in contrast with traditional HTML applications in which the user has the option to view the source code from the browser. Although not appropriate for all applications, you do have the option to publish the source code for Flex applications using a Flex Builder feature. When you publish the source code, the user can select a View Source context menu item from Flash Player. The menu option will launch a new browser window that allows the user to view the published source code.
From Flex Builder you can select Project→Export Release Build. The Export Release Build dialog will open, where you can enable the view source. You may also select which source elements you want to publish by clicking on the Choose Source Files button. By default, all project source code and assets are selected. You can also specify the subdirectory to which to publish the source code files. All the selected ActionScript and MXML files are saved as HTML files.
If the main application entry point is an MXML file, Flex Builder
automatically adds the necessary code to enable the View Source context
menu item. To manually enable the View Source context menu for an MXML
document, you should add the viewSourceURL
attribute to the <mx:Application>
tag such that it points
to the index.html page in the
published source code directory.
If you're publishing the source code for an application that
uses an ActionScript class as the main entry point, you'll have to
enable the context menu item using ActionScript code. This step
requires the com.adobe.viewsource.ViewSource
class. You
should then call the static addMenuItem()
method, passing it a reference
to the main class instance and the URL for the source code, like
so:
ViewSource.addMenuItem(this, "sourcecode/index.html");