I’ve recently been reading a lot of articles recently about the new Alchemy research project at Adobe Labs. At first glances this looks very exciting: compile optimised C/C++ code to be executed within an ActionScript 3 Flash movie. As quoting from the Alchemy home page :
“… Ideally suited for computation-intensive use cases, such as audio/video transcoding, data manipulation, XML parsing, cryptographic functions or physics simulation, performance can be considerably faster than ActionScript 3.0 and anywhere from 2-10x slower than native C/C++ code.”
Sounds good! Ideal even when thinking about 3D graphics that are heavily dependent on vector and matrix calculations…
So, I decided to take a look and see how easy it was to integrate C++ code into an ActionScript project and what the benefits were. I discovered fairly quickly that documention on the web is fairly limited which has prompted this blog entry. Also, I’m a fan of the eclipse development environment and like all my work to be concentrated within the same window so wanted the Alchemy development to be done in parallel to the ActionScript development.
First off, it should be noted that this article is aimed mainly at Mac users: Hopefully there are things along the way that will be useful for Windows but I’m going to be looking at an automake utility to compile the Alchemy code which may not work on Windows (maybe under Cygwin, but I’ve not tried it).
Here are a few links to get started anyway:
- The main Alchemy home page at Adobe Labs
- Essential Adobe guide for installing and getting started with Alchemy
- The C/C++ API
- The ActionScript 3 API
- A couple of libraries built with Alchemy
First of all download Alchemy Toolkit from Adobe. Personally I copied the extracted directory to the Applications folder in my home directory. Then follow the instruction given on the Getting Started page.
NOTE !! I had huge trouble to start with because I was running a shell with tcsh: you must have bash (which is anyway the default for Mac) running for this to work!
Once I managed to compile the C code using the Alchemy tools, I went straight to Flex Builder 3 to try to integrate the ActionScript and compiled swf together.
In Flex Builder (or the Eclipse plugin as I’m using), create a new ActionScript project called EchoTest, as is the case for the ActionScript class shown on the Alchemy Getting Started page. Now we need to ensure that the project is compiled for Flash Player 10 (this is easily possible if you have Flex Builder 3.0.2 installed). Go to the project Properties menu item, select ActionScript Compiler and for Require Flash Player version enter 10.0.0 and click OK.
In the newly created EchoTest class, copy the code from the GettingStarted page that is linked to compiled C.
package { import flash.display.Sprite; import cmodule.stringecho.CLibInit; public class EchoTest extends Sprite { public function EchoTest() { var loader:CLibInit = new CLibInit; var lib:Object = loader.init(); trace(lib.echo("foo")); } } }
This won’t compile because we need to link to the Alchemy-compiled C code. Create a bin directory at the root of the project and copy stringecho.swf, compiled before, here. Go into the project Properties menu item, select ActionScript Build Path, go to the Library Path tab and select Add SWC…. Browse to the bin directory and select stringecho.swf. Now when you click on OK you should find that the project compiles.
To see anything happen you need to run in debug mode… even then its not very exciting: you’ll just see foo written in the Console.
The main objective (for me at least) is to set up an environment where we can compile the C/C++ code with Alchemy within the Flex environment. For this I’m going to be combining some automake files with shell scripts and link them to Eclipse with an ant build file.
Lets first of all copy the alchemy source in the project. Create a directory called alchemy at the root of the project. Into this, copy the C file from the Alchemy samples (ALCHEMY_HOME/samples/stringecho/stringecho.c).
For automake we need a configure.in file and (depending on the project) several Makefile.am files.
At the project root, copy the following into configure.in :
dnl Process this file with autoconf to produce a configure script. AC_INIT(alchemyTest, 0.0.1) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR(alchemy/stringecho.c) AM_INIT_AUTOMAKE dnl Compiler AC_PROG_CXX AC_PROG_CC AC_LANG(C++) AC_LANG(C) CFLAGS="" AM_CFLAGS="-Wall -O3 -swc " AC_SUBST(AM_CFLAGS) CXXFLAGS="" AM_CXXFLAGS="-Wall -O3 -swc " AC_SUBST(AM_CXXFLAGS) dnl Initialise top_srcdir top_srcdir=. AC_OUTPUT([ Makefile alchemy/Makefile ])
Create a Makefile.am file at the project root as well containing the following line (indicating simply which is the main alchemy source directory):
SUBDIRS = alchemy
Finally in the alchemy directory, copy the following also into a Makefile.am file :
INCLUDES = -I$(top_srcdir)/alchemy bin_PROGRAMS = stringecho.swc stringecho_swc_SOURCES = \ stringecho.c
That’s all that’s needed for the automake part. Now we need a couple of shell scripts to be called from ant and that take into account the environment variables necessary for the Alchemy tools.
At the root, create a file called init and copy the following:
#!/bin/sh if [ ! -d config ] then mkdir config; fi if [ ! -x AUTHORS ] then touch AUTHORS; touch README; touch NEWS; touch ChangeLog; fi aclocal -I config autoconf automake --gnu --add-missing if [ ! -d obj ] then mkdir obj; fi path=`pwd` cd obj ../configure --prefix=`pwd`/.. cd $path
Once it is created, make sure it is executable by changing the file permissions (chmod +x init). This will essentially create any necessary directories and files (for automake) and launch the configuration process. This will then create all the necessary Makefiles.
In the same directory (the root) create a file called build (that should also be executable) and copy this:
#!/bin/bash ALCHEMY_HOME=$HOME/Applications/Alchemy source $ALCHEMY_HOME/alchemy-setup PATH=$ALCHEMY_HOME/achacks:$PATH export PATH cd obj make -e install
Here we specify the home of Alchemy (so, obviously, change the directories accordingly) and we then launch the compilation, passing the environment variables at the same time (with the -e flag).
Finally, we come to the ant build file. The following should be copied into build.xml at the project root.
<project name="EchoTest" basedir="."> <property name="builddir" value="."/> <target name="compile alchemy"> <exec executable="${builddir}/build"/> </target> <target name="init alchemy"> <exec executable="${builddir}/init"> </exec> </target> <target name="remove obj"> <exec executable="rm"> <arg line="-fr"/> <arg line="obj"/> </exec> </target> </project>
This includes a couple of targets to initialise the compilation (create the Makefiles) and compile the C source. A final target just removes the compiles object files.
in the end you should have a project structure that looks something like this:
So let’s test this. Open the Ant view in eclipse by selection the menu Window, Show View, Other… and then searching for the Ant view. Drag and drop build.xml into this view and you should find the targets compile alchemy and init alchemy available.
NOTE !!! For this to work you need to lauch eclipse from the command line using the command tcsh -e ./eclipse from the installed eclipse directory. I don’t know why, but ant behaves differently - I presume because environment variables are passed to it! If you could tell me why, or how to avoid this, I’d be very happy to hear from you!
So, back again, assuming that eclipse is launched as tcsh -c ./eclipse, double click on the init alchemy target. You should hopefully see the configuration process in the console terminated with BUILD SUCCESS! This means that the Makefiles are ready. You can now double click on build alchemy to compile the C code. If it works you should see output that resembles that shown of the compilation on the Getting Started page.
The init process is typically necessary only once. From now on when modifying the C code just launch the build target.
This has now compiled stringecho.swc in the bin directory. Refresh the workspace (fn_key + F5 on a Mac) if it doesn’t refresh automatically which then recompiles the ActionScript if a change has occurred. In this case, I’m simply showing a build process so there’s no difference to the result. However, in future projects, you’ll find that every time you recompile using the Alchemy tools you’ll need to refresh the workspace otherwise the ActionScript project isn’t updated.
Also to note, when editing the C or C++ files, I’d recommend using the CDT plugin for eclipse rather than an external editor - again it avoids switching application for compiling the same project!
Anyway, hope this is of some use to people getting started with Alchemy (like me!). If you find any problems then please let me know… same if you have any comments. Next I’ll be looking at testing some of what Alchemy is supposed to be capable of!
