xsubppとは
コンパイルの順番と読み込み
- .xsファイル -> [xsubpp] -> .cファイル(Cマクロいっぱい) -> [Cプリプロセッサ] -> [Cコンパイラ] -> .bundleファイル
- .pmファイルから「XSLoader::load」を使って、共有オブジェクトファイルを読み込む。
(.xsファイルから.soファイル(共有オブジェクトファイル)が生成されるらしいけど、見当たらない><)
コード
下記のコマンドでひな形を作成
h2xs -A -b 5.8.1 -n Foo::Bar
Bar.xsの中身。
// EXTERN.h perl.h XSUB.h の順番で書く #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" =pod Cを書くエリア =cut MODULE = Foo::Bar PACKAGE = Foo::Bar =pod XSエリア =cut
lib/Foo/Bar.pmの中身。
package Foo::Bar; use 5.008001; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.01'; # 共有オブジェクトコードを読み込む require XSLoader; XSLoader::load('Foo::Bar', $VERSION); 1;
コンパイルしてみる
下記の流れでコンパイル。
コンパイル出力の流れ。
- cp lib/Foo/Bar.pm blib/lib/Foo/Bar.pm
- blib下にpmファイルをコピー
- perl (Path)/ExtUtils/xsubpp -typemap (Path)/ExtUtils/typemap Bar.xs > Bar.xsc && mv Bar.xsc Bar.c
- xsubppでxsファイルをコンパイル
- -typemapオプションでtypemapファイルを読み込み
- Bar.cファイルが生成される
- cc -c (なんか色々オプション) Bar.c
- cc -bundle -undefined dynamic_lookup Bar.o -o blib/arch/auto/Foo/Bar/Bar.bundle
デバッガでたどってみる
pmファイルの「XSLoader::load('Foo::Bar', $VERSION);」の直前に「$DB::single=1」を追加してコンパイル。
下記のコマンドで実行。
perl -d -Mblib -MFoo::Bar -e ''
シングルステップ(sを入力)で進める。
Bar.bundleを読みこんでいるような部分を見つける。これが共有オブジェクトコード?