hnwの日記

Mavericks上での古いPHPのビルドが苦行だった

先週、MacBook Air 11inch Late 2010にMacOSX Mavericksをインストールしてみました。まだ時々違和感がありますが、もう1ヶ月もすれば細かい問題点も消えてくるのではないでしょうか。


しかし、Mavericks上でOSSをビルドしようと思うと案外苦労するかもしれません。僕は古いPHPをビルドする趣味を持っているのですが、かなり骨が折れました。折角なのでハマったポイントを紹介します。

gccって名前のバイナリがgccじゃない

最初の罠ですが、MavericksからCコンパイラが変わりました。Xcodeをインストールするとgccという名前のバイナリが/usr/binにできますが、コイツはgccじゃありません。

$ /usr/bin/gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix


見ての通り、clangです。LLVMの由緒正しいCフロントエンドとでも言えばいいんでしょうか。


ちなみにMountain Lionまではllvm-gccという、gccを改造したLLVMのフロントエンドが使われていました。バックエンドがLLVMなのは以前と変わっていないんですが、コンパイラとしてはgccだったのが別のCコンパイラになったという認識でいいと思います。


Cコンパイラが変わったくらいで何か困るの?というのはエンジニアとして正常な感覚だと思います。しかし、僕はgcc拡張で偶然動いていたCプログラムが動かなくなるというトラブルに見舞われました。具体的には、PHP 5.0.0からPHP 5.0.5まで、configure中のテストビルドで下記のようなコードをコンパイルしており、が使えない環境だと判定されてしまいました。

#include <stdarg.h>
int main() {
  
int foo(int x, ...) {
    va_list va;
    /* 中略 */
}
int main() { return foo(10, "", 3.14); }
        
return 0; }


僕はgccで関数内に関数が書けるというのを今まで知りませんでしたが、そもそも普通はこんなコードを書かないですよね。


ちなみに、上記コードはautoconfで自動生成されるものです。AC_TRY_COMPILEマクロを使っていたためにgccだけで動く状態になっていたようですが、本当はAC_TRY_RUNマクロを使うのが正解だったようです。autoconfって難しいですね…。


ほかにもC99準拠の書き方にしないとコンパイルが通らない箇所がありました*1ので、お気をつけください。

libxml2が新しすぎる

Mavericksではシステムで利用されているlibxml2のバージョンが2.9.0になっています。このバージョンからXMLバッファ(?)のインターフェースが変わったようで、たとえば次のようなコードを書く必要があるのですが、古いコードはこれに対応していません。

#ifdef LIBXML2_NEW_BUFFER
            ZVAL_STRINGL(*retval, xmlOutputBufferGetContent(buff), xmlOutputBufferGetSize(buff), 1);
#else
            ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1);
#endif


こういう場合、頑張ってPHPにパッチを当てるしかありません。つらいですね。

知見をphpallに反映しました

今回苦労した内容をphpallの付属スクリプトinstall-all-php.shに反映しました。これを使えばPHP 5.0.0からPHP5.5.5までの全バージョンをMavericks上でビルドできるはずです。


ちなみに、上記スクリプトで利用しているパッチは次のようなものです。個別にビルドする場合などにご利用ください。

*1:「inline」というキーワードで関数宣言をしていた箇所について、「static inline」と書く必要がありました

*2:Mavericks標準のOpenSSLは0.9.8yなので、Mavericksでは不要です