無茶なバイナリーの作り方。
Leopardに入っているPHPにはPostgreSQLのライブラリがサポートされてなかったので、作りました。ただ、今度はMySQLが無くなってしまったけど・・・*1
*ちなみに動きません。理由は最下部*
作成したバイナリーは、Universal Binaryになっています。
ダウンロードは、http://a-yasui.info/~yasui/LeopardPHP.tgzです。
ハッシュ値
- md5: 941d465a9ad3a7e2c79aa1d33e0fd9c4 LeopardPHP.tgz
- shasum: 5e911796b2c1709c2e125a3525713521d9e856aa LeopardPHP.tgz
なお、インストールする時、/usr/libexec/apache2以下にある、libphp5.soをコピーして使用してください。
PostgresのバイナリーとPHPのソースコードは下記からダウンロードしました。
- PostgreSQL: http://www.entropy.ch/software/macosx/postgresql/
- PHP Source : http://www.opensource.apple.com/darwinsource/10.5/apache_mod_php-43/
無保証です。
以下作り方。
下記のような、configureコマンドを実行。後にmake && make testで作成とテストをしてます。
#!/bin/sh setenv CFLAGS "-arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk" ./configure \ --prefix=/usr \ --mandir=/usr/share/man \ --infodir=/usr/share/info \ --disable-dependency-tracking \ --with-apxs2=/usr/sbin/apxs \ --with-ldap=/usr \ --with-kerberos=/usr \ --enable-cli \ --with-zlib-dir=/usr \ --enable-trans-sid \ --with-xml \ --enable-exif \ --enable-ftp \ --enable-mbstring \ --enable-mbregex \ --enable-sockets \ --with-iodbc=/usr \ --with-curl=/usr \ --with-config-file-path=/etc \ --sysconfdir=/private/etc \ --with-pgsql=/usr/local/pgsql \ --with-xmlrpc \ --with-xsl=/usr \ --without-pear
追記:ごめん、これ動かない・・・orz
LeopardのApacheは、x86_64,ppc64,i386,ppcのそれぞれを持っているユニバーサルバイナリーで、それに吊られてPHPの方も合わせて作らなきゃ行けない。頭が痛いのは、PHPのバイナリーを作る為には、PostgreSQLの方もそれように作らなきゃ行けない訳。ちょっと現実逃避のため、つらつらと詳しい理由を掻いてみる。
先ず、Apacheは起動する時に共有ライブラリをずらずら読み込んで行く。その際に、dlopenは気をきかして、Apacheの動いているバイナリーのタイプ(例えば、G5だとppc64、Xeonだとx86_64といった感じで読み込んでいる。)、それと同じ物を読み込もうとし少しでも違う物はエラーとして扱う。つまりx86_64で動いており、共有ライブラリがi386だとしてもエラーとして扱われる。そして、これは共有ライブラリを作る際も同じで、この場合だとPHPとPostgreSQLの双方とも、(ppc|ppc64|i386|x86_64)が必要になる。
むぅ、PostgreSQLだけど、heaptuple.cがどうもこの四つのユニバーサルバイナリーを作成することができないみたい。どうも、内部マクロのinclude/access/tupmacs.hにあるstore_att_byval(下の文、参考)で使われているswich文のcaseに同じ値のが使われていると文句を言っている気配。でその比較には、int16やint32があり、それはinclude/c.hで定義されている。(下の文、参考)後、Datumというのもinclude/fmgr.h で定義されており、下記を参考に。
推測だけど、Darwin 9.0以降、int型は(強制的に)64bitになった。今まで、関数のポインターには(多分)long型が使われてて、int32と名付けられたint型とDatum型がダブルブッキング起こしたんじゃないかなぁ・・・
困った事に、こんな所を自分勝手に修正したくないよ・・・
むぅ、DarwinPortsでApache+PHP+PostgreSQL/ppc,i386か・・・
#if SIZEOF_DATUM == 8 #define store_att_byval(T,newdatum,attlen) \ do { \ switch (attlen) \ { \ case sizeof(char): \ *(char *) (T) = DatumGetChar(newdatum); \ break; \ case sizeof(int16): \ *(int16 *) (T) = DatumGetInt16(newdatum); \ break; \ case sizeof(int32): \ *(int32 *) (T) = DatumGetInt32(newdatum); \ break; \ case sizeof(Datum): \ *(Datum *) (T) = (newdatum); \ break; \ default: \ elog(ERROR, "unsupported byval length: %d", \ (int) (attlen)); \ break; \ } \ } while (0) #else /* SIZEOF_DATUM != 8 */ #define store_att_byval(T,newdatum,attlen) \ do { \ switch (attlen) \ { \ case sizeof(char): \ *(char *) (T) = DatumGetChar(newdatum); \ break; \ case sizeof(int16): \ *(int16 *) (T) = DatumGetInt16(newdatum); \ break; \ case sizeof(int32): \ *(int32 *) (T) = DatumGetInt32(newdatum); \ break; \ default: \ elog(ERROR, "unsupported byval length: %d", \ (int) (attlen)); \ break; \ } \ } while (0) #endif /* SIZEOF_DATUM == 8 */
/* * intN * Signed integer, EXACTLY N BITS IN SIZE, * used for numerical computations and the * frontend/backend protocol. */ #ifndef HAVE_INT8 typedef signed char int8; /* == 8 bits */ typedef signed short int16; /* == 16 bits */ typedef signed int int32; /* == 32 bits */ #endif /* not HAVE_INT8 */ /* * uintN * Unsigned integer, EXACTLY N BITS IN SIZE, * used for numerical computations and the * frontend/backend protocol. */ #ifndef HAVE_UINT8 typedef unsigned char uint8; /* == 8 bits */ typedef unsigned short uint16; /* == 16 bits */ typedef unsigned int uint32; /* == 32 bits */ #endif /* not HAVE_UINT8 */
* All functions that can be called directly by fmgr must have this signature. * (Other functions can be called by using a handler that does have this * signature.) */ typedef struct FunctionCallInfoData *FunctionCallInfo; typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);
*1:右を立たせば左が立たぬと申します・・・いやいや