2011年11月7日月曜日

c++でphp extensionを作成する。

なにはともあれ、

C++でPHP extensionを作成する。


1、スケルトンを作成
# ./ext_skel --extname=eigen
# cd eigen


2、config.m4を修正

① PHP_ARG_WITHのコメントアウトを外す。

② コンパイラの環境変数を設定

CC=/usr/bin/gcc
CXX=/usr/bin/g++


追記 : のちに、以下もつける必要があるとわかった。

CFLAGS="-g -O2 -lstdc++"
CXXFLAGS=-fPIC


③ 拡張子を「c」から「cc」 or 「cpp」にする。
PHP_NEW_EXTENSION(eigen, eigen.cc, $ext_shared)



3、ソースファイルを修正

① 名前の拡張子を修正
# mv eigen.c eigen.cc
② 中身の #includeを extern "C"で囲む

extern "C"{
    #include "php.h"
    #include "php_ini.h"
    #include "ext/standard/info.h"
    #include "php_eigen.h"
}


4、phpizeでconfigure作成
# phpize

5、configure実行
# ./configure

6、makeを実行
# make

※1 ここで「.libs/eigen.o: could not read symbols: Bad value」というエラーが発生した。

(1)config.m4の「CCをg++」にてみた。


CC=/usr/bin/gcc
CXX=/usr/bin/g++
CC=/usr/bin/g++


ダメ。

(2) php_eigen.hも extern "C"を付けた。

ダメ。

(3) ちゃんとエラーを読んでみた。
「/usr/bin/ld: .libs/eigen.o: relocation R_X86_64_32 against `eigen_module_entry' can not be used when making a shared object; recompile with -fPIC」

なるほど。-fPICオプションをつけてコンパイルし直せと。
Makefile or config.m4に追記。
CXXFLAGS=-fPIC

よしできた。

7、make installを実行
# make install

開発するときはいちいちめんどいので、
シンボリックリンクのほうがいいかも。

# sudo ln -s /usr/local/share/php-5.3.8/ext/eigen/modules/eigen.so /usr/lib64/20090626/



8、php.iniの修正
extension=eigen.so

9、実行を確認。

helloworld
?>
できない!?。

※1 「PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/20090626/eigen.so' - /usr/lib64/20090626/eigen.so: undefined symbol: __gxx_personality_v0 in Unknown on line 0」
と出る。
ちょっと調べてみると、gccでコンパイルすると出るエラーだと。
確かにsoをコンパイルするとき、gcc使ってたな。

(1) Makefile の CC=gcc を CC=g++にしてみた。
なんか変なエラー出た。

(2) Makefile の CCFLAGS に -lstdc++をつけてみた。
-lstdc++はc++をコンパイルするよってオプション。
g++ は gcc -lstdc++みたいなもんか。

よしできた。



続いて、eigen.cc の中で、eigen3を実行してみる。

9、前作ったサンプルをそのままコピペしてみる。
→ 動いた。

0 件のコメント:

コメントを投稿