たかだです。 先日 Adobe Labs が C/C++ のコードを Flash Player 向けにコンパイルする Alchemy というプロジェクトをプレビューリリースしました。 Alchemy は llvm を利用し、C/C++ のコードを ActionScript3(ActionScript ByteCode ではありません)に変換し、それを SWF または SWC 形式にコンパイルします。 llvm の最適化処理によって、しばしばネイティブの ActionScript より高速に動作するそうです。 新しもの好きのわたしが早速こちらを動かしてみたいと思います。 以下 Alchemy:Documentation:Getting Started を参考に、Windows+Cygwin 環境で Alchemy を動かします。 必要なものは、以下の通りです。
  • Cygwin
  • (Cygwin上で動く)Perl
  • (Cygwin上で動く)zip
  • (Cygwin上で動く)gcc/g++
  • Java
  • Flex 3.2 SDK

Flex のインストール

最初に Flex 3.2 SDK をインストールします。Flex SDK は以下から 3.2 をダウンロードしてください。 (Cygwin および Java などのインストールについては以下では解説しません)。 解凍し、適当なパスに置いてください。 Cygwin 上で Flex SDK に Path を通す必要があります。 ここでは Flex SDK のインストール先を C:/develop/flex_sdk_3/ とします。 以下を .bashrc などに書きくわえてください。

PATH=/cygdrive/c/develop/flex_sdk_3/bin/:$PATH
export PATH
正しくパスが通っていれば、以下のようになるはずです。

$ mxmlc -version
Version 3.2.0 build 3958

Alchemy のインストール

Adobe Labs より「Alchemy Toolkit for Cygwin on Windows」をダウンロードし、適切な場所に解凍しておきます。 (以下では C:/develop/alchemy-cygwin/ に解凍したものとします)。 最初に config というスクリプトを実行します。

$ cd /cygdrive/c/develop/alchemy-cygwin/
$ ./config 
Generating alchemy-setup...
Turning execution bit on for Alchemy binaries...

Add "source /cygdrive/c/develop/alchemy-cygwin/alchemy-setup" to your login script.
  "alc-home" takes you to the Alchemy install folder.
  "alc-on" puts Alchemy gcc toolchain replacements at the front of your path.
  "alc-off" restores original path.
  "alc-util" shows you various Alchemy-related environment vars
You need Flash 10 or AIR 1.5 and the Flex 3.2 SDK installed for testing.
以上により alchemy-setup が生成され、alchemy ツールのいくつかが使えるようになりました。 alchemy-setup というシェルスクリプトを実行することで必要な環境変数を設定し、alc-on などのコマンドを呼び出せるようになります。 ただし、こちらを実行する前に Air Debug Launcher(ADL)のパスを alchemy-setup に追加しておく必要があります。ADL は Flexディレクトリの bin/ 以下にある adl.exe というファイルです。 alchemy-setup を編集し、ADL のパスを追加してください。 (以下は alchemy-setup に書き加えます)。

export ADL=/cygdrive/c/develop/flex_sdk_3/bin/adl.exe
ログイン時に、alchemy-setupが実行されるようにするため、.bashrcを変更します。Adobe Labsのgetting startedには、achacksディレクトリをPATHに追加するように書いてありますが、追加しない方がよいようです。 (alchemy-setupの場所は、設定に応じて変更してください)。 (以下は.bashrcに書き加えます)。

source /cygdrive/c/develop/alchemy-cygwin/alchemy-setup
alchemy-cygwin/bin/llvm-stub にシンボリックリンクをはる必要もあるようです

cd bin/
ln -s llvm-stub llvm-stub.exe
以上が終わったら、Cygwinにログインし直し環境変数の設定が更新されるようにします。 (単に source .bashrc を実行するだけでもかまいません)。

C コードのコンパイル

以上までで alc-on / alc-off というコマンドを利用できるようになりました。 alc-on を実行すると gcc コマンドの参照先が alchemyプロジェクトのものに変更され、alc-off で元に戻ります。

$ alc-on
$ which gcc
/cygdrive/c/develop/alchemy-cygwin/achacks/gcc
さっそくサンプルプログラムをコンパイルしましょう。alchemy のディレクトリの中にすでにサンプルプログラムが用意されています。 ここでは、stringecho.c というコードをコンパイルします。 コードを一部だけのぞいてみましょう。以下のようなC言語の関数が定義されています。引数が null かどうかチェックし、AS3_String 型にして返すだけの関数のようです。

static AS3_Val echo(void* self, AS3_Val args)
{
	//initialize string to null
	char* val = NULL;
	
	//parse the arguments. Expect 1.
	//pass in val to hold the first argument, which
	//should be a string
	AS3_ArrayValue( args, "StrType", &val );
	
	//if no argument is specified
	if(val == NULL)
	{
		char* nullString = "null";
		//return the string "null"
		return AS3_String(nullString);
	}
	
	//otherwise, return the string that was passed in
	return AS3_String(val);
}

alc-on の状態で、gcc コマンドを利用し、コンパイルします。

$ cd /cygdrive/c/develop/alchemy-cygwin/samples/stringecho/
$ gcc stringecho.c -Wall -swc -o stringecho.swc
WARNING: While resolving call to function 'main' arguments were dropped!

4328.achacks.swf, 363894 bytes written
frame rate: 60
frame count: 1
69 : 4
72 : 363824
76 : 33
1 : 0
0 : 0
frame rate: 24
frame count: 1
69 : 4
77 : 506
64 : 31
63 : 16
65 : 4
9 : 3
41 : 26
82 : 471
1 : 0
0 : 0
converting to DOS line endings
catalog.xml: done.
  adding: catalog.xml (deflated 75%)
  adding: library.swf (deflated 61%)
$ ls -l
total 149
drwx------+ 2 takada-at ????????         0 Dec  1 10:02 as3
-r-x------+ 1 takada-at ????????       435 Nov 13 10:20 readme.txt
-r-x------+ 1 takada-at ????????      1221 Nov 13 10:20 stringecho.c
-rwxr-xr-x  1 takada-at mkgroup-l-d 144137 Dec  1 11:07 stringecho.swc
SWC ファイルが生成されました! 生成された SWC ファイルはライブラリとして ActionScript コードの中で利用できます。 stringecho.swc は、引数として渡された文字列を、そのまま返すだけの関数を提供しています。 ここでは、以下のような mxml コードを利用して、このライブラリの動作を試してみましょう。以下を、Hello.mxml として保存し、同じディレクトリに stringecho.swc も置きます。

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="main()">
    <mx:Label text="aaa" id="labelone" fontSize="24" />
    <mx:Script><![CDATA[
        public function main():void{
            import cmodule.stringecho.CLibInit;
            var lib:CLibInit = new CLibInit();
            var stringEcho:Object = lib.init();
            labelone.text = stringEcho.echo("Hello!");
        }
    ]]></mx:Script>
</mx:Application>
SWFファイルとしてコンパイルします。target-player の指定を忘れないように注意してください。

$ mxmlc.exe -library-path+=./stringecho.swc Hello.mxml -target-player=10.0.0
設定ファイル "C:\develop\flex_sdk_3\frameworks\flex-config.xml" をロードしています
C:\develop\alchemy-cygwin\samples\stringecho\Hello.swf (461380 bytes)
生成されたSWFファイルをブラウザにドラッグすると...? 期待通り、Helloの文字が表示されました。