LICENSE
This is in the public domain. I needed it, so I wrote it, and I'm
sharing it with no warranties or support whatsoever. If you find it
useful, good for you. Use it, abuse it, drive ICBMs up your nose with
it, I don't care. Just don't blame me for any fallout, such as lost
revenue, lost productivity, radiation poisoning, or whatever else
happens if/when you shoot yourself in the foot.
INTRODUCTION
This is a command line build environment with Adobe Flash 8, Flash
CS3 or Flex SDK
ActionScript sources fed through the C preprocessor before they go to
mxmlc or Flash. It is minimalistic and very suitable for use with
easily
scripted code editors or IDEs, or just as a straight command line
development environment.
What you get is a couple of different makefiles, some batch files,
and some 'readme' files sort of like this one.
Be sure to read this entire document, especially the 'BUGS,
Work-Arounds and Notes' section at the bottom. It contains some very
important little details that will drive you insane if you're not aware
of them.
Flash 8/CS3/CS4
The Flash version of the build is deprecated. You should use
the 'Complete' version with combines Flash and Flex builds, as well as
Flash resource builds. The differences from the Flex
SDK version are relatively minor. First off, it supports Actionscript 2
or Actionscript 3. The makefile keeps the
original and preprocessed files straight by keeping them in different
directories. This also makes the tool a little more 'universal' as it
doesn't care whether it's preprocessing AS2 or
AS3 code. It leaves it up to Flash to tell the difference.
The main difference between Flex and Flash is those handy, wonderful
'Metadata' tags you can sprinkle in Flex SDK to [Embed()] things is ignored! There are
work-arounds for that if you
have code that has to build under Flash and Flex.
Also, the half-baked
conditional compilation things they added to Flex aren't in
Flash. So if your code has those, all of the blocks will
be compiled by Flash. Whereas, if you use an external
preprocessor, it
works for any environment.
How it Works
- The project starts with .as files in a source tree. These are
ActionScript files
with preprocessor directives in them.
- It invokes the C preprocessor on each file.
- It pipes the C preprocessor output through a ‘#line filter’ to
‘repair’ the C preprocessor output, making the preprocessed .as code
match up with the original .as code lines.
- It invokes mxmlc (or builds a .jsfl script to call Flash) on the
target tree of .as files, and redirects
the console and error output to a file.
- It feeds this to a sed script that replaces the .as source code
path with the original .as path.
- Your IDE (jEdit, MS Visual Studio, etc.) sees the errors in
stderr, and
pops up its normal mouse-clicking handlers to navigate to the original
code where you had the error.
- You still have the original ‘errors’ file from mxmlc to refer
back to the preprocessed .as code, too.
- You can 'pretty-print' the preprocessed code so it becomes
readable actionscript code with no clear evidence it was ever
preprocessed. This is particularly useful if you use complex
'inline' functions and x-macros to produce code, to see the code/data
your macro templates actually made.
What is the C Preprocessor?
A preprocessor is a tool that performs text-based transformation on
code. At its simplest, if you '#define foo 3', then wherever you type
'foo' as a token in your code, the number 3 will appear. The GNU
preprocessor (GPP) does handle UTF-8 by default, so there's no
incompatibility there.
#define foo 3
int tmp = foo; // int tmp = 3;
int foobar = 4; // int foobar = 4;
It adds conditional compilation...
It adds debug instrumentation that automatically disappears in the
'release' mode build.
It hides complicated low-level 'junk'.
Including certain extensions allows you to suck in other files less
'conditionally' than AS3 'include' statement, and go ahead and mess up
the line count between the original and the preprocessed file. This
allows you to import built-in data trivially from tools and build much
more elaborate templates than you'd want to make with the backslash
line continuation character. The down-side is that wherever you include
the text will blow the line count for errors reported by the makefile,
so include code/data/xmacros as close to the bottom of the file as you
can.
- .inc
- .temp
- .as
- .mxml (Only with the GNU tools - nmake threw up a show stopper
that would force me to rewrite nmake.mak but hey, M$ sux.)
- .xml
Why use a Preprocessor?
- Control contents of the source code from the make script target.
- Assert macros of all kinds. Look for articles on assert if you
don’t understand why these are important in a large project.
- Trivially allow exceptions to go uncaught in debug builds with
#ifdef to step through problems.
- Work around all the little annoyances and things you wish the
language did for you with a little macro.
- Proper conditional compilation to trivially remove lots of pesky
tool and diagnostic code from the release version, so you can have your
‘level editor’ live in the same code as the game, for instance.
- Code generation of common/repetitive things. Edit once,
everything relating to it changes in appropriate ways.
- Trivially move blocks of code around in the project at
compile-time.
- Making a C/Actionscript data bridge from a single definition
file, so messaging components of a client/server architecture don’t get
out of whack.
- Hard constants. None of this ‘look it up in the class the first
time and it’ll be that way for the rest of the function’ business. When
I '#define ppPI 3.14159...', I definitely know I will get a
'3.14159...' in the code where I put a ppPI, debugging or not.
- Decompiler obfuscation. Fairly easy to rename ‘release’ mode
class and function definitions to drivel. What’s easier to read?
'radians * 180/Math.PI;' or '_var5 *
0.017453292519943295769236907684886;', which in your code was 'radians
* ppRad2Deg'?
- Easily test ‘what if’ cases for performance.
- Make unit tests trivially, that are written in the same files as
what they test.
- Native enum! #define eFirst 0, #define eSecond 1, etc. No need
to lookup and compare strings to index into something. Not type-safe,
but very simple.
- Make one list of items in your source code, it can produce every
list of things wherever you need it in the rest of the as code.
- Want to ‘[(Embed)]’ an Array of BitmapData items without
maintaining separate code to iterate/initialize them? You can do this
trivially.
- Formalize that anonymous { label:value, label2:value2 ... }
scratch-pad Object data by wrapping them up in macros, and even add
macro 'functions' to operate on things that have 'similar' naming
transparently, like simple x/y/z things in variables on the stack OR in
an object.
- Lots more fun, silly little things, like trivially unrolling
BitmapData pixel operations, or defining simple one-line iterators that
produce dozens of lines of ‘boiler plate’ code in the background.
Where to Get the Files
The files are in SVN, and there they'll stay. I can program many
computer languages, do all manner of evil, nasty stuff with scripts of
all kinds... but I can't make SourceForge.net's 'File Releases' thing
work any more, and I don't feel like figuring out why, so I won't. This
is not exactly a fruity, new MP3 player that a million kids will want
at the same time, so I'm not worried about the bandwidth cost of all
the dozens of you people who may actually try to use this.
You can download the 'latest' of whatever I'm up to in the project
with SVN, or browse the SVN repository with the web browser and grab
the ZIP files which just might be somewhat more stable. You only need
'installer.zip' if you're going to install the GNU Makefile version and
all of its tools. Otherwise, for the MSVC tools, you only really
need 'sed' (links below). SourceForge has helpfully hidden the SVN 'Code'
browse under a 'More' tab on the main project page.
PREREQUISITES
First off, you'll need that Free Flex 2 or Flex 3 SDK from Adobe.
Unzip it
somewhere permanent and add its 'bin' folder to your PATH. You'll have
to log in (or make a free account) to get the files, but that's about
it, and I haven't received much spam from Adobe as a result. Not to be
confused with 'Flex Builder', which costs $500 and comes with an
'Eclipse' IDE.
While you're there with that account you had to make all logged in,
you may as well get the Flex Documentation. I recommend 'Documentation
ZIP file', near the bottom. It has most everything you need on a daily
basis. You can short-cut it to your desktop where you can get at it
easily.
As installed, Flex 2.01 will import Macromedia Flash 8 swf content,
but not Flash CS3 content. You'll need to get a patch from Adobe to fix
that. Follow this link and follow the instructions. Basically, unzip
the file and dump the jar files into the lib folder where you'll
replace the jar files with the same names. The main symptom is it'll
throw up mysterious errors about failing to import when you embed
things.
Under Ubuntu or a Debian-based Linux distribution, you will probably
need to type 'sudo apt-get install
indent' in a shell to initially have this tool. For most command
line
tools, if you open a shell and type the name of a command, Ubuntu will
tell you what to do in order to get it. Or, just copy/paste the
following into a command shell to automagically get everything
mentioned in this document, except for the Adobe links, above. If
the packages are already installed or newer, the command line is
harmless.
- sudo apt-get install gcc findutils sed indent jedit vim-gnome
You'll need either Microsoft NMake and the tools that go with that,
or a version of gcc. If you have GNU gcc, you probably have GNU make,
sed and cpp already, but not necessarily, especially if you're running
under Windows.
Other C preprocessors may work with the Makefile or nmake.mak
directly, or with trivial modifications. For instance, Open Watcom's
cl.exe behaves almost identically to MSVC's cl.exe. So, if you have
another make tool and/or development environment you might want to use
the makefile(s) as an example to write your own.
I tried to do this with Cygwin, but something was 'hosed' with the
paths in mxmlc (having to do with drive letters), and I abandoned it.
Other Handy Links
This contains tons of documentation for the Flex SDK, especially the
'Complete Flex 3 documentation' ZIP file link at the bottom of the
list. Unzip it, browse through it, make desktop shortcuts to your
favorites. Mine is 'flex3_documentation/langref/index.html'.
This contains tons of documentation for Flash, including Flash 8.
There's a 'ActionScript 2.0 Language Reference' PDF there that I'm
particularly fond of, as well as another version of the AS3 docs, the
'ActionScript 3.0 Language and Components Reference'.
Scripted Build
This is just BASH scripts and Windows CMD shell batches to invoke the
build tools. This will be the easiest to follow, assuming you
already know how to write a script for BASH or DOS. It needs 'GNU
find tools' and 'GNU sed' to work, and you'll need to compile the
cppfilter.c file. Both versions of script assume you have the GNU
Compiler Collection installed, but you can manually have that
executable built and leave it in the buildtools folder, under version
control, and everybody on the project can share it. Similarly for
Windows users, sed (%SED%) can be redefined in the make and pointed at
the buildtools folder as well, so you can share that in your project
without everyone on the team setting up a bunch of build tools and
paths.
This version of the build doesn't scan dependencies, so it will always
preprocess all the files it finds, and invoke the Flash and MXMLC
compilers on the resulting code tree.
The script tools are suitable for integrating into a more elaborate
top-level make that DOES scan dependencies, which is why I wrote
them. I have some projects that are being built in more than one
swf, and want a more elaborate build. (Coming soon: extra
complicated project build make.)
GNU Makefile Build
For a GNU Makefile build, use the Makefile. It's the default
parameter for make.
The Makefile and tools will build with other preprocessors (see the
comments in the makefile), but you may as well play along with one set
of tools, and the gnu toolset is either already installed, or easy to
find for pretty much EVERY OS, and also free.
- Under Windows, if either OS or OSTYPE isn't set to Windows_NT,
you'll need to set it in your environment. It should be set by default.
Under Windows, the installer.zip file has a batch
similar to Mathias Michaelis' 'Download and Maintenance utility for
GnuWin32', only a little more bare-bones and simple. It will download
and install a functional MinGW build environment (to provide 'cpp' and
build one filter the make needs) and a selection of command line tools
(many of which aren't strictly needed, but they're handy). You may edit
the 'files.txt' file to narrow down the bulk of what's installed, if
you like. Then you only need to add the 'mingw/bin' folder (not the
mingw/mingw/bin folder) to your PATH to be in business. There is a
README.txt file in the installer that will lead you by the nose if you
need it. Like any batch or script files you find on the web, I
recommend reading every one before you try to run it.
Thanks to Windows SHISTA, the install.bat will
prompt for the path AND you'll end up with a pop-up for a
self-extracting archive, which doesn't take command line arguments for
some reason. The only "all together" MinGW I could find that
would work under Vista was the one maintained to build MAME.
- From the command prompt, invoke download.bat
- Invoke install.bat C:\cygwin
- Type C:\cygwin into that annoying popup
- Wait for all the spew to finish
- Add a reference to C:\cygwin\bin in your PATH environment variable
- Log out and log back in to make sure it's all updated.
The mingw-mame-20070617.exe
came from http://www.mamedev.org/tools/
- at least somebody made a MinGW distro that isn't bent
in Vista.
(NO! I will not maintain a Vista version on top of an
XP and and a Linux and an OSX version of the build.)
ANT Build
The ant folder works more or less like the makefile version, except instead of invoking the C preprocessor, it uses a combination of ANT's regular expression translations on files and the conditional compilation goodies added in Flex 3. For this one, all you need is the Flex SDK and ANT (and Java, naturally).
OSX
Under Mac/OSX, you need to install XCODE (or the iPhone SDK; it comes with XCODE). This will also get you 'gcc' and the related tools.
http://developer.apple.com/TOOLS/Xcode/
What's here...
CONFIGURE.MAK
This is the place to customize the project per your
local/group/project needs. If generic things, like 'game.swf' aren't
what you want out of make, this is where you change them. Both Makefile
and nmake.mak include this file, and 'fix up' the path
slashes/backslashes accordingly. This makes it a lot easier to support
either form of 'make', and update or reuse the Makefile without
stomping your project preferences.
MAKEFILE
This is the main GNU make script. It has some house-keeping targets
and settings, and invokes cpp2mxmlc.mak to do the preprocessed mxmlc
builds.
| make debug |
Build a debug version |
| make release |
Build a release version |
| make profile |
Build a 'release' version with profile tools |
| make all |
Cleans, then builds debug and release |
| make run |
Run the game |
| make runhtml |
Run the game in web page |
| make rundebug |
Run the game in the debugger * |
| make runprofile |
Run the game with profiler hooks |
| make clean |
Wipes out intermediate files |
| make cleaner |
Invokes clean in any subdirectory nmake.mak |
| make prettyprint=true [debug|release|profile] |
Build with pretty print output ** |
| make obfuscate |
Build a list of symbols compatible with obfuscate.h |
make whitelist
|
Build a list of symbols that
aren't to be redefined for obfuscation.
|
| make symbols |
Build a list of functions, constants and variables |
| make zip |
Make a zip file of the project tree (needs Info-ZIP) |
* See the 'BUGS' section about what disables fdb...
** Error call-out lines won't line up with original AS3 code
CPP2MXMLC.MAK
This is called by the GNU Makefile, and does most of the dirty work.
You probably won't need to change any of it, unless you want to
'tinker'. You may need to tinker outside of Windows, as a few things
are 'stuck' that way.
NMAKE.MAK
This is the Microsoft NMAKE makefile. It's part of every
version of Visual Studio, and has been tested starting with MSVC 6 and
.NET. If you invoke it from the Game.vcproj, your errors will show up
in the IDE just like Visual C++ errors.
| nmake -f nmake.mak cfg=debug |
Build a release version |
| nmake -f nmake.mak cfg=release |
Build a release version |
| nmake -f nmake.mak cfg=profile |
Build a profile version |
| nmake -f nmake.mak cfg=[debug|release|profile] run |
Run the game |
| nmake -f nmake.mak cfg=[debug|release|profile] runhtml |
Run the game in a web page |
| nmake -f nmake.mak cfg=debug rundebug |
Run the game in the debugger * |
| nmake -f nmake.mak cfg=[debug|release|profile] prettyprint |
Build a version with pretty print output ** |
| nmake -f nmake.mak clean |
Wipes out intermediate files |
nmake -f nmake.mak obfuscate
|
Build a list of symbols
compatible with obfuscate.h |
| nmake -f nmake.mak make whitelist |
|
| nmake -f nmake.mak cleaner |
Invokes clean in any subdirectory nmake.mak |
| nmake -f nmake.mak nuke |
Clean AND destroy 'extra' msvc files (nukes your run settings) |
| nmake -f nmake.mak zip |
Make a zip file of the project tree (needs Info-ZIP) |
* See the 'BUGS' section about what disables fdb...
** Error call-out lines won't line up with original AS3 code
FILTERS/CPPFILTER.C
cppfilter [-gcc|-msvc] <input >output
cpp | cppfilter [-gcc|-msvc] >output
Built as a target in the Makefile, it is written in C. You can remove
the Makefile target for this if that's more convenient. There's a
make.bat there with examples of command lines that will build it with
other compilers. Whatever it takes to make the executable (not much),
and you're set. This runs through the preprocessor utput and translates
the '#line' spew into blank space matching up with the original source
code. The process was a little more 'stateful' than I was willing to
put up with in sed, and if anybody can make a sed script do that, they
can be a hero. There's nothing magic there, and no dependencies outside
of the standard C runtime library, and it could as easily have been
written in any language with good command line streaming support. A
BASH script could do it, or maybe
even a BAT file, but I'm not going to spend the time doing it like
that. It supports two modes: -gcc and -msvc. In '-gcc' mode, it looks
for '# 123', like GNU cpp puts out. In '-msvc' mode, it looks for
'#line 123' directives like msvc puts out.
It has a table of file extensions at the top of cppfilter.c for
which file types it will include and dump into the body of its output.
This will 'lose track' of the original 1:1 line relationships when you
#inlcude "somefile.as", but it will unconditionally insert the whole
body of that inline, which the built-in 'include' statement will not.
GNUBATCHES
These are just shorthand to invoke the various GNU make
targets. Make them into scripts, delete them, whatever.
MSVCBATCHES
These are just shorthand to invoke the various Microsoft NMAKE
targets.
RES/
Whatever tree of folders/files you put here will end up in the
bin/bind directories. Add XML, HTML, whatever assets the app needs.
INCLUDE/
Handy preprocessor macros and definitions for the application.
SRC/
This is where the .as files go, and there are a couple of
sample ones in here. If you understand how MXMLC and the 'import'
keyword end up searching paths by
default, that's basically the tree that goes here. If you add different
'package' folders, they'll need to appear in the Makefile LIBDIRS entry.
AS/ASD/ASP/BIN/BIND/BINP
These are intermediate and output folders for various kinds of
builds. If you have 'special' authoring and time consuming diagnostic
code to stuff in
the application that shouldn't go to the public, make it conditional on
DEBUG. These folders are destroyed when the 'clean' target is evaluated.
obfuscate.sh
Enable build obfuscation for non-debug builds using the GNU
tools. Takes a little while to run the first time in order to
create the 'white list' of system calls.
obfuscate.bat
Enable build obfuscation for non-debug builds using the
Microsoft tools. Takes a little while to run.
SETTING UP With VIM
The vim editor is nice, in that it's everywhere, but most
people loathe it. I use it all the time for minor edits and quick hacks
when I'm too lazy to open an IDE and make a project to do it.
Anyway, if you use VIM, here is the stuff you need...
- Get the actionscript.vim, and mxml.vim files (the third link is
for ActionScript 2).
http://www.abdulqabiz.com/files/vim/actionscript.vim
http://www.abdulqabiz.com/files/vim/mxml.vim
http://www.vim.org/scripts/script.php?script_id=1061
- Linux/Unix/OSX: Put those files in a '.vim/syntax' folder in your
home folder. Create these folders if they don't exist.
- Windows: In the foler where vim is installed, there's a _vimrc
file, and a _vimfiles/syntax folder. They are the same as above.
- Edit '.vimrc' (you can edit it with vim)
- Add this to the bottom of the file...
au BufNewFile,BufRead *.mxml set filetype=mxml
au BufNewFile,BufRead *.as set filetype=actionscript
syntax on
- Close all your open vim/gvim sessions and open a .as or .mxml
file
SETTING UP With jEdit
jEdit is yet another IDE/editor that I sort of like for dealing with
command line builds. It has a nice little command prompt plugin and
error parser/list plugin that makes setting it up simple, and you can
just type the commands in if you haven't recorded a 'Macro' and
assigned a hot key to every possible thing in the universe that could
be done with your code. It already has a halfway decent syntax
highlighter for .as files.
http://www.jedit.org/
- Plugins you'll need: Console, ErrorList
- Plugins you'll want: BufferTabs, Project Viewer
- Things you'll need to do:
- Add an 'mxmlc' error pattern to the Console plugin in
Plugins->Plugin Options->Console->Error Patterns
- Click the '+' at the bottom of the Error patterns list.
- Name: mxmlc (press OK)
- Error Regexp: (.*)[(](\d+)[)]: col: (\d+) Error: (.*)$
- Warning Regexp: (.*)[(](\d+)[)]: col: (\d+) Warning: (.*)
- Filename: $1
- Line number: $2
- Error message: $4
- . Go into Utilities->Global Options->Editing
- Set up your tab and editing preferences
- Set up 'actionscript' settings to recognize '.mxml'
(File
name glob: *.{as,mxml})
- You'll probably also want to go to Utilities->Global
Options->Shortcuts and add these keyboard shortcuts, if you're a
Windows user.
- Close: Ctrl-F4
- Go to Next Buffer: Ctrl-Tab
- Go to Previous Buffer: Ctrl-Shift-Tab
When you build in the 'Command' window, the errors will pop up in
the Errors list, and the file will be brought up and the error line
will be highlighted correctly. It takes a little groping around to get
all the windows up and parked on the IDE the way you'll like.
Here are the jEdit error patterns for Flash 8, Flash CS3 and Flex
(MXMLC)
Name: Flash 8
Error Regexp: ^\*\*Error\*\* ([^:]*): Line ([^:]*): (.*)$
Warning Regexp: ^\*\*Warning\*\* ([^:]*): Line ([^:]*): (.*)$
Extra Lines Regexp: \s+(.*)
Filename: $1
Line Number: $2
Error Message: $3
Name: Flash CS3
Error Regexp: ^\*\*Error\*\* (.*), Line (.*): (.*)$
Warning Regexp: ^\*\*Warning\*\* (.*), Line (.*): (.*)$
Extra Lines Regexp: \s+(.*)
Filename: $1
Line Number: $2
Error Message: $3
Name: Flex2
Error Regexp: (.*)[(](\d+)[)]: col: (\d+).+Error: (.*)$
Warning Regexp: (.*)[(](\d+)[)]: col: (\d+).+Warning: (.*)
Extra Lines Regexp:
Filename: $1
Line Number: $2
Error Message: $4
VISUAL Studio SETUP
For versions after Visual C++ 6, the 'External Makefile'
project will host the nmake.mak file adequately, and
allow you to run the program and launch the debugger using the keyboard
shortcuts you're used to. Visual C/C++ 6 will let you build, but not
run, and will also make a mess of your project folder. This can be
added as one project in a workspace.
- File->New->Project... Track down the
Makefile project. That's what you want.
- Make sure the project.vcproj will end up in the same directory as
the nmake.mak, or all of these relative paths will be wrong. You can
make it work if you put it in a different directory, but you'll have to
tinker with all of the paths.
- Give it a name, save it, proceed with the Wizard, or skip over
it. In this case, let's call it 'BlankProject' and skip the wizard.
- Right-click on 'BlankProject' in the Solution Explorer ('File
View' on VC6), and add various files and folders to it, as you like.
(Add->Existing Item, from the context menu, creating Filters (VC6:
Folders) as you desire.)
- Right-click on 'BlankProject' and this time pick 'Properties'
(VC6: Settings)
- There are two modes for everything. Release and Debug. You can
add other project configurations (i.e. Profile) as you like.
- For Visual C/C++ 6 or earlier, I would recommend downloading
the free Visual C++ 2005 Express
- Settings for Debug: nmake /f nmake.mak cfg=debug
- Settings for Release: nmake /f nmake.mak cfg=release
- Rebuild all options: all
- Output file name for Debug: bind\game.swf
- Output file name for Release: bind\game.swf
- On the debug tab, well, good luck. I couldn't make it run.
- For later versions of Visual Studio.net (the absolute naming and
placement varies a bit), just grope around in the tree view box...
- Output Directory
- Settings for Debug: bind
- Settings for Release: bin
- Intermediate Directory
- Settings for Debug: asd
- Settings for Release: as
- 'Build Command Line'
- Settings for Debug: nmake /f nmake.mak cfg=debug
- Settings for Release: nmake /f nmake.mak cfg=release
- 'Rebuild All Command Line'
- Settings for Debug: nmake /f nmake.mak cfg=debug all
- Settings for Release: nmake /f nmake.mak cfg=release all
- Settings for Debug: nmake /f nmake.mak cfg=debug clean
- Settings for Release: nmake /f nmake.mak cfg=release clean
- 'Output'
- Settings for Debug: bind\game.swf
- Settings for Release: bin\game.swf
- Debugging Command
- Settings for Debug: Browse to...
C:\WINDOWS\system32\cmd.exe
- Settings for Release: Browse to...
C:\WINDOWS\system32\cmd.exe
- There is a 'start.c' in the filters directory that can be
compiled and used to ShellExecute() without invoking a command prompt
(and getting that 'Press any key to continue' prompt).
- You could also invoke the SAFlashPlayer directly
- You could also 'start' the test.html
- Command Arguments
- Settings for Debug: /c fdb $(TargetPath)
- Settings for Release: /c start $(TargetPath)
- Working Direcrory
- Settings for Debug: bind
- Settings for Release: bin
FREE VISUAL C++ 2005 Express SETUP
http://msdn.microsoft.com/vstudio/express/default.aspx
This version is the 'preferred' one if you're going the MS route.
Not only is it free and handles the build OK (though it always wants to
make sub-directories of the projects when you make a new one), it will
allow you to map the as files to 'Microsoft Visual C++' in
Tools->Options->File Extension. Since the C parser is pretty
close to AS, most of the syntax highlighting just sort-of works.
Debugging with Adobe Flash CS3
It may be desirable to debug under Adobe Flash CS3 (Flash 9) because
it has a nice GUI to debug in. That's do-able. If you don't have Flash
CS3, you can get a 30 day trial of that from Adobe's web site and see
if it's any better than the command-line fdb debugger.
- Make the debug build and launch it with the 'debug'
SAFlashPlayer.exe that came with the Flex SDK. You should see a popup
that says 'Where is the Debugger or Pofiler running?'. Leave it alone
for the moment.
- In Flash CS3, go to Debug->Begin Remote Debug
Session->ActionScript 3.0'. If it's not enabled (or not there), make
a 'New' FLA file. While you're at it, you might just want to make a
Flash 'Project' and add that FLA file to it, along with your various
'.as' files in the 'asd' tree. The .as files in the asd tree, not the
.as files in the src tree.
- Flash will enter a debug 'stand-by' mode waiting for
SAFlashPlayer.exe to connect. Now you can open .as files from your
project and set breakpoints. The .as files in the asd tree, not the
.as files in the src tree.
- Go back to that pop-up window and press OK. You should hit your
breakpoint and be able to debug from there.
- If you don't set any breakpoints, the game will run off without
you. You can open a .as file and set a breakpoint someplace, and it
will stop, if it hits it.
- You can swap steps 1 and 2, and the game will take off
immediately. If you're not checking for initialization troubles, or
just waiting for a crash, this will work, and save you a couple of
mouse clicks.
I have also had success working with an AS3 'Loader' that did
the little 'Loading...' animation and loaded the main application. If
you launch the loader under the debugger, the loaded swf will also be
loaded under the debugger, and faults and such pop up the .as file
associated with it.
Indent
As stated previously, running the 'prettyprint' command will
pretty-print the preprocessor output before building, and the original
AS3 file won't line up with the AS file. There are several reasons you
might want to build with 'prettyprint'.
- You want to debug and see things laid out nicer, with seperate
statements on seperate lines in the .as file.
- You expanded a macro that you just can't read or debug the output
of
- You need to give your code to somebody else who isn't set up for
your build environment
- So an artist can build and test without setting everything
else up
- You made an obfusctated build, and only want the funky output
available to someone who only needs to build it
- You made an obfuscated build, and you want to see how hard it
is to read yourself.
- You don't want to 'confuse' somebody with your example code.
- You decided you hate CPP and want a trivial path back to 'normal'
Flex SDK or Flash CS3 development.
- Your boss arbitrarily demands you not use it, because he wants to
do things the hard way.
- You found a 'better' preprocessor to use (there are many other
preprocessors to choose from that you might like better than CPP, feel
free to substitute them into this make, if you want).
- You want to be certain it's always trivial to 'make indent=true',
so you test it occasionally to be sure it builds and runs.
The following steps illustrate how to make 'pretty' AS ouput.
- Build the pretty-print output version of the game
- make prettyprint=true debug
- make prettyprint=true release
- nmake -f nmake.mak cfg=debug prettyprint=true
- nmake -f nmake.mak cfg=release prettyprint=true
- You may have a few syntax errors induced by 'indent' to fix (see
below).
- Go to the as, asd or asp folder
- Type: mxmlc -o game.swf Main.as
- Optionally, add whatever other flags you like to the command line
invocation...
- mxmlc -o game.swf -compiler.debug=false
-compiler.optimize=true Main.as
- mxmlc -o game.swf -compiler.debug=true
-compiler.optimize=false Main.as
You'll probably want to review what happened to your code, as
'indent' was meant for C, not Actionscript. It will do some odd things
to Object {var:val}, especially if deeply embedded. Those will have to
be hand-tweaked. Wrapping things with parentheses, especially when
returning them as a value will clean up most of the problems that
you'll routinely encounter.
Going back to CPP After Some Development Without It
Going BACK to a preprocessed build once you've done some development
without it will be far more difficult than stripping the CPP directives
out, as all the definintions and rules won't be in the code anymore.
The easiest way to go back to using CPP again would be to diff the
revisions in your version control between the last preprocessed version
and the current version. Then manually repeat the changes that were
made into the preprocessed code base. If the versions have diverged too
far, you might be stuck. A good regular expression 'Search and Replace'
(check each change) will be your best friend, then.
Normally you'll discover that the code changes to make the output
readable will impact the speed, as the things you unrolled with macros
get rolled back up, and other macro calls get manually turned into
functions which get called by functions, instead of being expanded
'inline', as it should have been. On the plus side, if this is the
case, it will usually be less than a week before everyone sees the
light and goes back to using the preprocessor... though some people
might resist and want to try to maintain the gawdawful mess that should
have been relatively few lines of code with some macro assumptions. If
Adobe gets around to an 'inline' function type that works, that would
certainly replace some of the worst of this (bot not all), but for now,
macro functions make a VERY big difference.
Building with Adobe Flash CS3
You probably won't want to, but if you need to give your code to
somebody else who ONLY wants to work in Flash, you may have to build in
Flash.
- Build the game, as normal
- Create a new FLA file and save it in the as, asd or asp folder,
according to what sort of instrumentation you wanted.
- In Flash CS3, go to File->Publish Settings... Pick the Flash
tab, then pick the Settings... button next to 'Actionscript version:'.
- In 'Document Class', type 'Main' (or whatever you called the main
class that starts the app up). Press OK and OK. You shouldn't see any
error or warning pop-ups, or you have saved the FLA file in the wrong
folder.
- Press Control->Enter. It should attempt to build.
- This is where the sad, sad news begins. It may build 'just fine'
(as this project does). It may throw a lot of build errors at you.
There's a lot of good stuff in the Flex SDK not in Adobe Flash. If you
used 'Embed', or mx.core.ANYTHING, or various other things, Adobe Flash
CS3 won't build it. Shame on Adobe for not producing a
somewhat more uniform development environment.
BUGS, Work-Arounds and Notes
- The MinGW GNU cpp (I don't know about other GCC revisions) that I
use will double-space the comments if the input file is DOS encoded
(\r\n for newlines). This naturally buggers the line count, and errors
mismatch the original source. It's a known bug in MinGW's CPP. Making
the source files 'unix encoded' (\n newlines) makes the problem go
away. This is a common setting in programmer's editors, and the default
for vim.
- To successfully debug with fdb, you'll have to go into the
FlexSDK/player folder and run the debug 'SAFlashPlayer.exe' once. That
will register it as the default player for fdb to find. It will also
make all of your flash playbacks run a little slower.
- Invoking Flash 8 player (i.e. by running/debugging AS2 code under
Flash 8) or the release-mode Flash 9 player will break the associations
that fdb uses. This can be corrected by running the 'debug'
SAFlashPlayer.exe again.
- You can get a 'release' mode SAFlashPlayer.exe by downloading and
installing the Flex Builder demo, and grabbing the release one out its
player folder. It
runs significantly faster than the debug, and you will want to switch
between debug and release players to test/profile the game.
- All of the C preprocessor tools become a part of your
ActionScript 3 build environment. Assert, conditional compiles, hard
constants, macros and code generation templates/techniques galore.
- The preprocessor tool ONLY imports definitions, so anything NOT
in a macro and expanded in your code will not appear in the code where
#include is invoked. This breaks some 'dirty tricks' for the
preprocessor, such as #including repetitive code to be operated on, but
if this were allowed by the CPPFILTER, then the code would never line
up right. You may use the 'include directive' to get this functionality
natively.
- You get some preprocessor files in the INCLUDE directory right
off the top, to use or throw away, or whatever.
- Error call-outs refer back to the original line of source code,
not the preprocessed code. The preprocessed output is processed some
more to make it match up to the original code, and to remove those
pesky '#line' statements that MXMLC doesn't understand, as well as the
tons of inserted white space that some preprocessors dump in. Anyway,
it's translated so if your editor/IDE has an output or 'error' box that
pulls up the source code, it will work.
- In the 'fdb' debugger, you are looking at the preprocessor
output. This is both bad and good. Sometimes it's very useful to see
what a macro became. Sometimes that can be a little confusing, too. The
code comments are left intact.
- The preprocessor stage is very fast, and the make actually
shortcuts around the (occasionally very slow) mxmlc startup, so once
you have a working build, you can keep running/debugging without that
long pause, at least until you change something.
- Dependencies for the source and header files are generated and
maintained automatically. If you touch any makefile script or header,
everything gets rebuilt. If you touch a particular file, only that file
gets rebuilt. Add '-compiler.incremental=true' to the mxmlc command
line parameters if the project is big enough to make a difference there.
- You will probably want to tell your editor about the extra .as
(and .mxml)
extension and associate it with the correct language parser, if such a
parser is available for your editor..
- Debug and release mode builds and dependencies go into seperate,
parallel as/asd, and bin/bind folders, so the builds can
coexist..Additional targets are easily added.
- Certain underlying preprocessor assumptions change. For
instance, where you might have used string concatenation like this:
"One " "string.", your macros will need to look like this: "One " +
"string."
- If you use the same libraries and general projects over and over
again, then the Makefile can be reused readily without modification.
- Using a VMWare shared volume or a Linux mounted Windows
Partition? MXMLC will throw all kinds of fits. It just won't
work. Don't even try. I recommend putting your source code under
version control (i.e. svn or cvs) and syncing to the local, native file
system when working in a shared Linux/Windows environment, and
NOT to try to get clever and 'share' the data one way or the
other. Some problems I encountered with VMWare were mysterious
forced capitalizations (or lower-case) of files (i.e. mxmlc will
complain that a file named 'Class' with a class named 'Class' is in a
file named 'class'). Under any kind of Linux, mxmlc will mysteriously
decide it doesn't have privileges to do anything with some files and
not other files on a read-write volume. You can chown to anybody you
like, you can see that attribs are '777', it just won't matter, and it
just won't work.
- When using Flash 8 under WINE/Ubuntu 7.1, I notice Flash crashes
when the last file is closed, so remember not to close the last open
file. If you launch a swf file (i.e. control enter) before you
close, you can exit cleanly and save your preferences.
- Flash 8 and Flash CS3 are both badly behaved applications.
Whenever you run a jsfl script, they tend to want to grab input focus
and maximize. It tends to grab focus just as you're attempring to
operate other things, and then all manner of keyboard shortcuts get
activated, making unintended modifications galore. I highly
recommend a second monitor to banish Flash to so it doesn't keep
jumping on top of your real work. I highly recommend using
version control with 'locking' enabled, so Flash doesn't inadvertently
save modifications to its ugly, monolithic FLA file.