.aファイルを使ってXSモジュールを作った

よく分かってないんだけど、
“.a”ファイルを作って、XSモジュールを作るところまではできた。

やりたいのは、既に存在する”.dylib”とか、”.dll”を使って、
XSモジュールを作りたいんだけど。。。
とりあえず、手元のMacでやってみたのでメモ。

1. Minillaでひな形を作成する
$ minil new -p XS Hoge-XS

2. “builder/MyBuilder.pm”を作る

package builder::MyBuilder;

use strict;
use warnings;
use parent qw(Module::Build);
use File::Copy;

sub new {
    my ($self, %args) = @_;
    $self->SUPER::new(
        %args,
        extra_compiler_flags => ['-Wall'],
        extra_linker_flags => ['lib/Hoge/libhoge.a'],
    );
}

1;

3. “libhoge.a”を作る

hoge.h

extern int my_add(int a, int b);

hoge.c

#include "hoge.h"

int my_add(int a, int b)
{
    return a + b;
}

“.a”ファイルを作る
$ gcc -c hoge.c
$ ar rv libhoge.a hoge.o
ar: creating archive libhoge.a
a - hoge.o

これで、”libhoge.a”が完成。
でもって、これと”hoge.h”を”lib/Hoge”にコピー。

4. “XS.xs”ファイルを書き換え

#ifdef __cplusplus
extern "C" {
#endif

#define PERL_NO_GET_CONTEXT /* we want efficiency */
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>

#ifdef __cplusplus
} /* extern "C" */
#endif

#define NEED_newSVpvn_flags
#include "ppport.h"
#include "hoge.h"

MODULE = Hoge::XS    PACKAGE = Hoge::XS

PROTOTYPES: DISABLE

int
hello()
    CODE:
        RETVAL = my_add( 8, 10 );
	OUTPUT:
	    RETVAL

見ての通り、
Hoge::XS::hello()は18を返すだけのXSモジュールが完成。

5. テストを通す

“t/01_simple.t”をこんな感じにすると、テストが通る。

use strict;
use Test::More;

use Hoge::XS;

is(Hoge::XS::hello(), 18);

done_testing;

この時点で、変更をgit addしたり、git commitすれば、
minil testが通ってハッピー。

6. 使ってみる

minil buildをしないといけないのかどうなのか分かんないけど、
この段階で、”Hoge-XS/Hoge-XS-0.01″が存在するので、
それをインストールして使ってみる。

$ tree -L 2
.
├── Hoge-XS
│   ├── Build
│   ├── Build.PL
│   ├── Changes
│   ├── Hoge-XS-0.01
│   ├── LICENSE
│   ├── META.json
│   ├── MYMETA.json
│   ├── MYMETA.yml
│   ├── README.md
│   ├── _build
│   ├── blib
│   ├── builder
│   ├── cpanfile
│   ├── lib
│   ├── minil.toml
│   └── t
├── aaa.pl
└── lib

で、一番下にある、”lib”にインストールしてみる。
$ cpanm -L lib ./Hoge-XS/Hoge-XS-0.01

aaa.pl

use v5.10;
use strict;
use warnings;

use lib './lib/lib/perl5/darwin-2level';

use Hoge::XS;

say Hoge::XS::hello();

実行すると、こんな感じ。
$ perl aaa.pl
18

ほんと、つらい。

おしまい。

Leave a Comment