C/C++ のコードを ActionScript に変換する Adobe Alchemy を試す
Adobe Labs の研究プロジェクト、コードネーム Alchemy を試してみた。同プロジェクトについては、すでに多くの方が書かれており、今更な感もあるが、以前に紹介記事を書いていることだし、備忘録も兼ねて残しておく。
Alchemy について
Alchemy プロジェクトで配布されているツールを使うと、C/C++ コードで記述されたプログラムを ActionScript Virtual Machine (AVM2) で動作するように変換できる(AVM2 については Adobe ActionScript Virtual Machine 2 (AVM2) Overview (PDF, 400K) を参照)。
これはつまり、既存の C/C++ プログラムが Flash Player や AIR 上で動作することを意味している。また、C/C++ プログラムのコンパイルには LLVM を利用しており、そこで生成された中間コードが ActionScript 3.0 のソースコードに変換される(そのままバイトコードには変換しない)。その後、生成された ActionScript コードが Alchemy 独自の ActionScript コンパイラで ActionScript Byte Code (ABC) にコンパイルされるようだ。
- 既存の C/C++ ライブラリの再利用に。特に OS 非依存なもの(例:オーディオ/ビデオ、XML パース、暗号処理、シミュレーション)
- CPU バウンドなプログラムなら Alchemy でコンパイルすると 10 倍ほども速くなるかもしれない。これは、LLVM による最適化の恩恵と、
ByteArray
に関する最適化された命令が理由(ActionScript コンパイラではまだ使われていない) - C/C++ コードは ActionScript 3.0 の SWF または SWC にコンパイルされる。SWF/SWC のセキュリティ制限やサンドボックスは通常の SWF/SWC と同様
- C/C++ コードから
"AS3.h"
で宣言された API を使うことで、Flash Player にアクセス可能
インストール
Alchemy:Documentation:Getting Started を参考に、インストール作業を進めていく。
- Flash Player 10 が必要(開発用に
content debugger
の方が便利) - ダウンロードページから Alchemy ツールキットを落とす(思ったより軽い)
- Flex SDK 3.2 をダウンロードする
$FLEX_HOME/bin
を PATH
に追加する
% adt -version
adt version "1.5.0.7220"
Alchemy のディレクトリに移動し、config
プログラムを実行する
% cd Developer/System/Flash/alchemy-darwin-v0.4a/
% ./config
config
プログラムで生成された alchemy-setup
をシェルの起動時に読み込むようにする:
source /Users/ishikawa/Developer/System/Flash/alchemy-darwin-v0.4a/alchemy-setup
また、alchemy-setup
は PATH を変更する前に読み込むらしい。そして、次に、${ALCHEMY_HOME}/achacks
を PATH
に追加する。最終的には以下のようになる:
# Flash, Flex, Alchemy ...
source /Users/ishikawa/Developer/System/Flash/alchemy-darwin-v0.4a/alchemy-setup
PATH=${PATH}:/Users/ishikawa/Developer/System/Flash/flex_sdk_3/bin
PATH=${PATH}:${ALCHEMY_HOME}/achacks
...
export PATH
サンプルを試す
では、同梱されているサンプルを試してみよう:
% cd $ALCHEMY_HOME/samples/stringecho
% which gcc
/usr/bin/gcc
% alc-on; which gcc
/Users/ishikawa/Developer/System/Flash/alchemy-darwin-v0.4a/achacks/gcc
まず、alc-on
を実行すると、gcc
が Alchemy 独自のものに切り替わるのが分かると思う。そして、samples/stringecho
にあるファイルは以下の通り:
- as3/EchoTest.as
- readme.txt
- stringecho.c
ここで、Alchemy 独自の gcc で stringecho.c
をコンパイルする
% gcc stringecho.c -O3 -Wall -swc -o stringecho.swc
WARNING: While resolving call to function 'main' arguments were dropped!
...
464.achacks.swf, 362566 bytes written
WARNING はとりあえず無視で。コンパイルの結果、stringecho.swc
が出来た。
そして、as3 ディレクトリにある EchoTest.as
が stringecho.swc
を使う AS3 のプログラムである。EchoTest.as を覗いてみると、
import cmodule.stringecho.CLibInit;
という import
文があり、これがコンパイルされた C プログラムを参照しているのだと分かる。また、trace()
を使って文字列を出力している:
trace(lib.echo("foo"));
では、この EchoTest.as
を mxmlc
でコンパイルしよう:
% mxmlc -library-path+=stringecho.swc --target-player=10.0.0 as3/EchoTest.as
Loading configuration file /Users/ishikawa/Developer/System/Flash/flex_sdk_3/frameworks/flex-config.xml
/Users/ishikawa/Developer/System/Flash/alchemy-darwin-v0.4a/samples/stringecho/as3/EchoTest.swf (142882 bytes)
ここで思い出してほしい。このプログラムは trace()
で文字列を出力するだけのプログラムだった。なので、デバッグ版の Flash Player 10 でログが出力されるように、mm.cfg でログを出力するように設定しておこう。
% cat > /Library/Application\ Support/Macromedia/mm.cfg
ErrorReportingEnable=1
TraceOutputFileEnable=1
Mac OS X の場合、mm.cfg
を置く場所は ~/mm.cfg
でもいいようなことがコメントにはあるけど、出来れば、~/Library/Application Support/Macromedia/mm.cfg
も見てくれないだろうか。それはともかく、ログファイルは ~/Library/Preferences/Macromedia/Flash Player/Logs/
に flashlog.txt
という名前で保存される。
Console.app からログを確認できるように、~/Library/Logs
にシンボリックリンクを作成しておこう:
% ln -s ~/Library/Preferences/Macromedia/Flash\ Player/Logs/flashlog.txt ~/Library/Logs/
やっとデバッグの準備が整った。デバッグ用 Flash Player で EchoTest.swf
を開き、flashlog.txt
に foo という文字列が書き込まれれば成功だ。Alchemy でコンパイルしたプログラムが無事、動作していることになる。