PHP拡張モジュールを Windows でビルド

必要なもの

とりあえず下記のものを準備します。


php-sdk は下記をダウンロードしました。

  • php-sdk-binary-tools-20110915.zip

ビルド環境の準備

http://windows.php.net/downloads/php-sdk/ からダウンロードした php-sdk-binary-tools-20110915.zip を「c:\php-sdk」に解凍します。


コマンドプロンプトを起動して「c:\php-sdk」に移動します。

cd c:\php-sdk

下記を実行して php-sdk のための環境変数(PATH)の設定とビルドツリーの作成を行います。

bin\phpsdk_setvars.bat
bin\phpsdk_buildtree.bat php53dev

vc9 や x86 などのサブディレクトリが作成されるので、下記のような名前でディレクトリを作成してPHPのソースファイルを解凍しておきます。

C:\php-sdk\php53dev\vc9\x86\php5.3-xyz

PHP のビルド

拡張モジュールのビルドに必要な phpize を作成するために PHP 本体をビルドします。


PHP ソースファイルのディレクトリに移動します。

cd C:\php-sdk\php53dev\vc9\x86\php5.3-xyz

VC用の環境変数を設定します(「Visual Studio コマンド プロンプト」から起動していたなら不要です)。

"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86

PHP拡張機能を全て OFF にしてコンパイル&インストールします。

buildconf
configure --disable-all --enable-cli
nmake
nmake install

C:\php にインストールされます。phpize は "C:\php\SDK\phpize.bat" にインストールされています。

拡張モジュールのビルド

まずは PHP ソースツリーの ext/ext_skel_win32.php で拡張モジュールの雛形を作るのですが・・・どうやら cygwin が前提になっているようです。
私の環境では cygwin は入れていなかったので、雛形は Linux で作成しました。


適当な LinuxPHP のソースファイルを解凍して下記を実行します。

cd php-5.3.x/ext/
ext_skel --extname=sample

ext ディレクトリの直下に sample ディレクトリが作成されるので、Windows の適当なディレクトリにコピーします。
仮に「C:\php-sdk\php53ext\sample」にコピーしたとします。


sample ディレクトリの config.w32 の

// Otherwise, use ARG_ENABLE
// ARG_ENABLE("sample", "enable sample support", "no");

の部分を下記のように修正します。「Otherwise, 〜〜」の行も削除しないと configure でエラーになります。

ARG_ENABLE("sample", "enable sample support", "no");


コマンドプロンプトで、次の通り実行して拡張モジュールをビルドします。

cd C:\php-sdk\php53ext\sample
C:\php\SDK\phpize
configure --enable-sample
nmake

C:\php-sdk\php53ext\sample\Release_TS に拡張モジュールが作成されます。
ただし、この拡張モジュールは先ほどビルドした PHP バイナリからならロードできますが、本家の PHP バイナリからはロード出来ません。

本家のバイナリからロードするために

Windows版の PHP は拡張モジュールのロード時にビルドに使われたコンパイラのバージョンのチェックが行われており、PHP 本体をビルドしたコンパイラのバージョンと、拡張モジュールをビルドしたコンパイラのバージョンが異なるとロード時にエラーになります。今回作成した拡張モジュールは VC10(VS2010)、公式のバイナリは VC9(VS2008)なため、公式のバイナリでロードすると下記のエラーが表示されてロード出来ません。


f:id:ngyuki:20120625213116p:image


PHP 本体を拡張モジュールも含めて VC10(VS2010)でビルドするか、自分の拡張モジュールを VC9 でビルドすれば良いのですが、どちらもちょっと面倒なので無理やりロードできるようにします。


"C:\php\SDK\include\main\config.w32.h" を開きます。

「#define PHP_COMPILER_ID "VC10"」という行があるので "VC9" に書き換えます。

--- config.w32.h.orig   Mon Jun 25 17:12:56 2012
+++ config.w32.h        Mon Jun 25 17:41:46 2012
@@ -186,7 +186,7 @@
 #define COMPILER "MSVC10 (Visual C++ 2010)"

 /* Compiler compatibility ID */
-#define PHP_COMPILER_ID "VC10"
+#define PHP_COMPILER_ID "VC9"

 /* Detected compiler architecture */
 #define ARCHITECTURE "x86"

再度拡張モジュールをビルドします。再コンパイルは "C:\php-sdk\php53ext\sample\Release_TS" を手動で削除して configure からやり直します(nmake clean-all や nmake clean では駄目だったので・・・)。

configure --enable-sample
nmake

これで VC10 でビルドしていますが、VC9 でビルドしたことになったので公式の PHP バイナリからロードすることが出来ます(正常動作は一切保証できませんが・・・)。

*1:用意できるなら VS2008 の方が良いですが私の環境で既に VS2010 を入れていたので・・・