miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

PHPScript のコンパイル

前項で PHPコンパイル方法を書いたけど、そもそもなんで PHPコンパイルしたかったかというと、PHPScript がそのままだと cscript やサクラエディタで動作しないのでバグ報告してた件。

PECL :: Request #13538 :: .php file can't be executed by cscript.exe

これの反応がなかなかないので、もうパッチ作って送っちゃおうと思い立ったから。この GW は自分の中でバグ報告&ActiveScript 強化週間でもあるので。

前項の PHP コンパイル環境が整っている前提で、手順をさくっと書くと、

  1. CVS から PHPScript の最新版を取得する
  2. 一部誤記を修正する(PECLPECL :: Bug #16527 :: PHPScript cannot be compiled
  3. C:\php-sdk\php53dev\vc9\x86\pecl\activescript のような形で格納する
  4. buildconf しなおす
  5. --enable-com-dotnet と --enable-activescript オプションをつけて configure

という感じ。以下引っかかった点とか。(そこそこ長いので注意。)

CVS からのチェックアウト

PHP: PECL 拡張モジュールをダウンロードする - Manual

に解説があるとおりで、できればコマンドラインでやっちゃいたいんですけど・・・CVSNT でチェックアウト→コンパイルするとこんなエラーになってしまいました。

ext\activescript\marshal.cpp : error C4335: Mac ファイル形式が検出されました: ソース ファイルを DOS または UNIX 形式に変
換してください

これは元々改行コード CRLF だったファイルが LF→CRLF の置換がかけられて CRCRLF になっちゃっているから。

設定ファイルで対応できたりしないのかなー?とググってみると、

改行コード問題 [VC++の使い方]

置換するか、WinCVS を使えば OK とのこと。今回はパッチを作るのが目的なので自前の置換は避けたいし、おとなしく WinCVS でチェックアウトしました。手順としては、

  1. Admin->Preference で Checkout text files with the Unix LF (0xa) にチェック
  2. Remote->Checkout module...
    1. Module name and path on the server [...] をクリック
      1. CVSROOT に :pserver;password=phpfi:cvsread@cvs.php.net:/repository と指定
      2. Module で pecl/activescript を指定して OK
    2. 再度 CVSROOT に :pserver;password=phpfi:cvsread@cvs.php.net:/repository と指定

という感じ?なんか二回も CVSROOT 指定してるけど、うまいことやれば一回で済むのかな?TortoiseCVS とか使ってもいいのかもしれない。

モジュールの格納先

当初

  • C:\php-sdk\php53dev\vc9\x86\php5.3-xyz\ext\pcre\activescript

に置いてたけど、これだとダメだった。処理を追ってみると、C:\php-sdk\php53dev\vc9\x86\php-5.3-src-xyz\win32\build\buildconf.js で以下のようなロジックになってる。

// Pick up confs from TSRM and Zend if present
find_config_w32(".");
find_config_w32("sapi");
find_config_w32("ext");
emit_core_module_list();

// If we have not specified any module dirs let's add some defaults
if (module_dirs.length == 0) {
	find_config_w32("pecl");
	find_config_w32("..\\pecl");
	find_config_w32("pecl\\rpc");
	find_config_w32("..\\pecl\\rpc");
} else {
	for (i = 0; i < module_dirs.length; i++) {
		find_config_w32(module_dirs[i]);
	}
}

ここで find_config_w32 は指定されたディレクトリの直下のディレクトリから config.w32 を探す関数で、module_dirs は --add-modules-dir オプションで指定されたディレクトリたち。
ということで、

  • C:\php-sdk\php53dev\vc9\x86\php5.3-xyz\activescript
  • C:\php-sdk\php53dev\vc9\x86\php5.3-xyz\sapi\activescript
  • C:\php-sdk\php53dev\vc9\x86\php5.3-xyz\ext\activescript

は常に対象になって、--add-modules-dir を指定しない場合は、

も対象になるという話かな。
php5.3-xyz とは別の管理のほうがいい気がしたので、とりあえず

を採用。

コンパイルエラー

なぜかこんなエラーが発生。

ext\activescript\scriptengine.cpp(2031) : error C2660: 'zend_exception_error' : 関数に 2 個の引数を指定できません。

ソースを見てみると、普通にカンマが抜けてるっぽい。バグ報告しておいたけど、なんでリリース版で問題になっていないのやら。

PECL :: Bug #16527 :: PHPScript cannot be compiled

リンカエラー

scriptengine.obj : error LNK2019: 未解決の外部シンボル __imp__php_com_variant_from_zval が関数 "public: virtual long __s
tdcall TPHPScriptingEngine::Invoke(long,struct _GUID const &,unsigned long,unsigned short,struct tagDISPPARAMS *,struct
tagVARIANT *,struct tagEXCEPINFO *,unsigned int *)" (?Invoke@TPHPScriptingEngine@@UAGJJABU_GUID@@KGPAUtagDISPPARAMS@@PAU
tagVARIANT@@PAUtagEXCEPINFO@@PAI@Z) で参照されました。

こんなエラーも出た。どうも --enable-activescript するときは --enable-com-dotnet も必要ということらしい。

パッチ書いた

ということで、コンパイルできたのでやりたかったパッチづくり。PHPScript を .php と .phps のどちらと関連付けるか迷ったけど、よく考えたら PHPScript の場合は簡単で、.phps に関連付けるべき。.php は タグ内部しか PHP とみなされないけど、.phps はタグなしでも PHP とみなされる、という明確な違いがあるわけで。

そんなわけでパッチ作成完了と。

PECL :: Request #13538 :: .php file can't be executed by cscript.exe

パッチは WinCVS のメニューからやってもいいし、cvs diff -u でもいいみたいです。

例によってバグ報告の英語は怪しかったりするので、気になった点はツッコミ or 補足お願いします。