coreserverでphp5.3.8用のAPCをビルドしてみたけどうまくいかなかった

coreserverPHPは5.2.5がデフォルトだけど、CGIモードにすると5.3.8か5.4.7が使えます。CakePHP2系は5.2.8以上が必要なので、coreserverでCakePHP2系を使うならCGIモードで5.3.8以上のどちらかにしないとです。
ただ、この5.3.8 / 5.4.7にするとcoreserverでのAPC(Alternative PHP Cache)について調べてみた - kanonjiの日記で調べたapc.soが動かない事に気がつきました。ちょっとレスポンスが悪く、APCを使いたいなと思っていたところなので、なんとかしようと、APCをソースからビルドしようと色々やってみました。結果は行き詰まってしまって、お手上げ状態なんだけど、やってみた事をまとめておきます。

CGIモードのphp 5.3.8にapc.soを読み込んだ時のエラー

Script Error

The script did not produce proper HTTP headers. Please see the error log to see the detail of the errors. Depending on the server configuration, you can also run thisscript under CGIWrap debugging. Usually, either rename or linkthe script temporarily to a file which ends with .phpdextension, or add a AddType application/x-httpd-phpcgi-debug .phpline to your .htaccess file.

見慣れないエラー、多分phpじゃなくApacheのエラーだと思う。
デバッグ方法が書いてあるけど、まずはcoreserver上に5.3.8 / 5.4.7用のapc.soが無いか探したり、その流れでビルドを試しました。

色々試す中、CGIモードphpのバージョンを5.3.8と5.4.7とで、何度も切り替えてたので、コマンドとかが5.3だったり5.4だったりします。が、解決しない事は一緒だし恐らく問題点も一緒だと思います。

APCソースコードからビルドしたけど、やっぱり上記のエラー

$ curl -LO http://pecl.php.net/get/APC-3.1.14.tgz
$ tar xzvf APC-3.1.14.tgz
$ cd APC-3.1.14
$ php54ize --clean
$ php54ize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
$ ./configure --enable-apc \
 --with-php-config=/usr/local/bin/php54-config \
 --prefix=/virtual/myuser/myhome/local/lib/php54/extensions
$ make
$ make install

ここで、なぜか--prefix指定を無視して/usr/localにinstallする動きをします。共用サーバーなので当然パーミッションは無く書き込めないけど、なぜ--prefixが無視されるんだろうか。複数のバージョンが同時にある事でphpizeの他にphp54izephp53ize等があるんだけど、そういう特殊な環境だからなのかな?

$ ls modules/
apc.la  apc.so
$ cp modules/* /virtual/myuser/myhome/local/lib/php54/extensions

仕方ないのでmakeで生成されたファイルをcpでコピー。

extension_dir = "/virtual/myuser/myhome/local/lib/php54/extensions/"
extension=apc.so

この内容でphp.iniを作ってこれでAPCが使えるかと思いきや、前述と同じエラーが出ました。

CGIWrap debuggingを試してみる

Usually, either rename or linkthe script temporarily to a file which ends with .phpdextension, or add a AddType application/x-httpd-phpcgi-debug .phpline to your .htaccess file.

前述のScript Errorをよく読んでみると、デバッグ手段が書いてある事に気がつきました。拡張子を.phpdに変える*1か、MimeTypeをapplication/x-httpd-phpcgi-debugにすると、デバッグ出来るらしい。

AddHandler application/x-httpd-php5cgi .php   #5.2.5
AddHandler application/x-httpd-php53cgi .php #5.3.8
AddHandler application/x-httpd-php54cgi .php #5.4.7

coreserverはこれでphpのバージョンを使い分けます。

AddType application/x-httpd-php5cgi-debug .php
AddType application/x-httpd-php53cgi-debug .php
AddType application/x-httpd-php54cgi-debug .php

試しにやってみたら、デバッグ出来ました。この辺はちゃんとそれぞれ用意してあるみたいです。
ただ、今書いてる最中に気がついたけど、AddHandlerじゃなくてAddTypeを使っちゃってました。でも、ちゃんと指定したバージョンでのデバッグになってたので、このサーバーではどっちで設定しても良い様にしてあるんだと思います。

PHP Warning:  PHP Startup: apc: Unable to initialize module
Module compiled with module API=20060613
PHP    compiled with module API=20100525

デバッグでは、phpの普段意識しない低レイヤー部の動きを表すデバッグ出力が、ブラウザに出てました。その中に、APCモジュールの初期化に失敗しているメッセージがあり、理由としてはphpAPCモジュールで、コンパイル時に使ったAPI*2のバージョンが違うといったもの。
coreserverに元々あったAPCでも、自分でビルドしたAPCでも、同じ理由で初期化に失敗しているようです。

php54izeの中を見てみた
$ php54ize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519

phpizeした時に似たようなものが出ていたので、次はphpizeを調べることに。恐らく「Zend Module Api No」が「20100525」になれば解決出来そうな感じ。

#!/bin/sh

# Variable declaration
prefix='/usr/local'
datarootdir='/usr/local/php'
exec_prefix="`eval echo ${prefix}`"
phpdir="`eval echo ${exec_prefix}/lib/php`/build"
includedir="`eval echo ${prefix}/include`/php"
builddir="`pwd`"
SED="/usr/bin/sed"

[snip]

phpize、ここでは5.4系用のphp54izeだけど、の中身は単にシェルスクリプトみたいなので、中を見てみました。
configureprefixと同じものか分からないけど、prefix='/usr/local'と決めうちになってたりします。この辺が怪しい様な感じです。

./php54ize_
exec_prefix=/usr/local
phpdir=/usr/local/lib/php/build
includedir=/usr/local/include/php

php54izeをコピーして、変数をechoしてみました。phpdirincludedirとか、異なるバージョンのphpが入ってる環境で、どうなるのか、気になります。

$ ls /usr/local/lib/php/build/
acinclude.m4          config.sub            ltmain.sh             mkdep.awk             run-tests.php         shtool                
config.guess          libtool.m4            Makefile.global       phpize.m4             scan_makefile_in.awk

試しにphpdirの中を確認してみると、どうもビルドに必要そうなファイルが入ってました。

[snip]

phpize_check_build_files()
{
  if test ! -d "$phpdir"; then
    cat <<EOF
Cannot find build files at '$phpdir'. Please check your PHP installation.

EOF
    exit 1
  fi

[snip]

phpizeの中をもう一度見てみると、phpize_check_build_files関数の中でphpdirを参照していて、build filesを探してる的なメッセージもあります。

この辺りから、異なるバージョンのphpを同居させるにあたってphpizeは単に別名で保存しておくだけじゃなく、中で序盤に定義してある変数の書き換えや、phpdirに有るべきビルドファイルも、バージョン毎に残しておく必要が有るんじゃないかと思いました。
この仮定が合っている場合、ビルドに必要なファイルが無いってことになるので、ここで行き詰まりです。

環境

*1:エラーメッセージだと.phpdextensionとなってるけど、多分スペース抜け落ちだと思う。

*2:何のAPIか知らないけど