[トップ] [自作PC] [PCの履歴] [フリーソフト] [プロバイダー選び] [レンタルサーバー]
[ワイマックスで損しない方法] [VPS比較] [フレッツ光東西でギガビットインターネット接続] [着メロ] [MSX] [ツイッターでポイントを貯めよう! ]

#powerusage

Perl XSメモ - ひな形を作る

[Perl XS メモへ戻る]

  • Perl XSメモ - ひな形を作る
    • いくつか、ツールがあるのですが・・・
    • ひな形はできても・・・
    • なら、少し共通化すればいいんじゃないの?
    • ん?ライブラリ?
    • ↑って、ヘッダ作る機能があるようですが・・
    • アンケート
    • このことに関する話題

いくつか、ツールがあるのですが・・・

結局、標準で使われる、Extutils::Makemakerだけに落ち着きました。
h2xs -An XS::ModuleName

ひな形はできても・・・

このままじゃ、使う気がしません。

  • Makefile.PL
 use 5.;
 use ExtUtils::MakeMaker;
 # See lib/ExtUtils/MakeMaker.pm for details of how to influence
 # the contents of the Makefile that is written.
 WriteMakefile(
     NAME              => 'XS::ModuleName',
     VERSION_FROM      => 'lib/XS/ModuleName.pm', # finds $VERSION
     PREREQ_PM         => {}, # e.g., Module::Name => 1.1
     ($] >= 5.5 ?     ## Add these new keywords supported since 5.5
       (ABSTRACT_FROM  => 'lib/XS/ModuleName.pm', # retrieve abstract from module
        AUTHOR         => 'Charlie & ') : ()),
     LIBS              => [''], # e.g., '-lm'
     DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
     INC               => '-I.', # e.g., '-I. -I/usr/include/other'
        # Un-comment this if you add C files to link with later:
     # OBJECT            => '$(O_FILES)', # link all the C files too
 );

なら、少し共通化すればいいんじゃないの?

1つのモジュールを開発するだけならいいのですが、いくつか開発することを前提に、共通化してみます。

  • Makefile.PL
use 5.;
require "../xsmake/xsbuild.pl";
&writemakefile(
        Module=>"XS::ModuleName",
        File=>"ModuleName.pm",
        Author=>'Nanami <>',
        Libs=>['-L../xslib -lxslib'],
);

  • ../xsmake/xsbuild.pl
use ExtUtils::MakeMaker;

my $testfile="testfile";
my $cclist=<

int main(void) {
        printf("Hello test world¥¥n");
        exit(0);
}
EOM

        &writefile("$testfile.c", $testsrc);

        my ($path, $opt)=&execchk("$testfile.c", $cclist, $ccopts);

        unlink("$testfile.c");
        unlink("$testfile.o");
        unlink("a.out");
        if($mode eq "cmd") {
                return $path;
        } elsif($mode eq "optimize" || $mode eq "opt") {
                return $opt;
        }
        return "$path $opt";
}

sub execchk {
        my($testfile, $execlist, $optlist)=@_;

        foreach my $cmd(split(/¥n/,$execlist)) {
                $cmd=~s/.*¥///g;
                $cmd=~s/.*¥¥//g;
                foreach my $opt(split(/¥n/,$optlist)) {
                        if($ENV{PATH}=~/:/) {
                                foreach my $path(split(/:/,$ENV{PATH})) {
                                        my $ret=system("$path/$cmd $opt $cflags $testfile >/dev/null 2>/dev/null");
                                        if($ret eq 0) {
                                                return ("$path/$cmd","$opt $cflags");
                                        }
                                }
                        } elsif($ENV{PATH}=~/;/) {
                                foreach my $path(split(/;/,$ENV{PATH})) {
                                        my $ret=system("$path¥¥$cmd $opt $cflags $testfile >/dev/null 2>/dev/null");
                                        if($ret eq 0) {
                                                return ("$path¥¥$cmd","$opt $cflags");
                                        }
                                }
                        }
                }
        }
        return ("", "");
}

sub writefile {
        my($fname, $data)=@_;
        open my $fh, ">$fname" || die;
        print $fh $data;
        close($fh);
}

sub writemakefile {
        my(%hash)=@_;
        WriteMakefile(
                NAME                            => $hash{Module},
                VERSION_FROM            => $hash{File},
                PREREQ_PM                       => {},
            ($] >= 5.5 ?
              (ABSTRACT_FROM  => $hash{File},
               AUTHOR         => $hash{Author}) : ()),
                CC                                      => &cc("cmd"),
                OPTIMIZE                        => &cc("opt"),
                LIBS                            => $hash{Libs},
                DEFINE                          => $hash{Define},
                INC                                     => $hash{Inc} eq "" ? "-I" : $hash{Inc},
                OBJECT            => '$(O_FILES)',

        );
}

ちなみに、

#OBJECT            => '$(O_FILES)',
のコメントを外すと、カレントディレクトリの拡張子 c を勝手にコンパイルして、勝手にリンクしてくれます。

ん?ライブラリ?

試しにやってます。ただし、gmakeでないと、これは動きません。

require "../xsmake/xsbuild.pl";
my $xsinclude="xsinclude.h";
my $xsdef="xsdef.h";
my $tst="pyukiwiki.xslib.test";

my $includes=<$xsinclude");
        print W "/* Auto generated by Makefile.PL */¥n¥n";
        close(W);

        foreach my $h (split(/¥n/,$includes)) {
                my $flg=0;
                foreach my $headers(split(/,/,$h)) {
                        print "Check $headers - ";
                        my $testsrc=<

int main(void) {
}
EOM
                        &writefile("$tst.c", $testsrc);
                        my ($p, $o)=&execchk("$tst.c", $ccpath, " ");
                        unlink("$tst.o");
                        unlink("$tst.c");
                        unlink("a.out");
                        if($p ne "") {
                                open(W, ">>$xsinclude")||die;
                                print W "#include <$h>¥n";
                                close(W);
                                $flg=1;
                                print "Found¥n";
                                last;
                        } else {
                                print "Not found¥n";
                        }
                }
                if($flg eq 0) {
                        die "Include file not found $h";
                }
        }
}

sub mkxsdef {
        my @c;
        opendir(DIR, ".");
        while(($file=readdir(DIR))) {
                next if($file eq "." || $file eq "..");
                push(@c, $file) if($file=~/¥.c/);
        }
        closedir(DIR);

        unlink($xsdef);
        open(W, ">$xsdef")||die;
        print W "/* Auto generated by Makefile.PL */¥n¥n";

        foreach my $file(@c) {
                open(R, "$file")||die;
                print "Detect:$file¥n";
                foreach() {
                        chomp;
                        if(/^(void|char|int|long|long long|short|double|float)¥t(.*)¥{$/) {
                                my $a=$1;
                                my $b=$2;
                                print W"extern¥t$a¥t$b;¥n";
                        }
                }
                close(R);
        }
        close(W);
}

sub mkmakefile {
        my @h;
        my @c;

        my $cc=&cc("cmd");
        my $opt=&cc("opt");

        opendir(DIR, ".");
        while(($file=readdir(DIR))) {
                next if($file eq "." || $file eq "..");

                push(@h, $file) if($file=~/¥.h/);
                push(@c, $file) if($file=~/¥.c/);
        }
        closedir(DIR);

        open(W, ">Makefile")||die;
        print W "# Auto generated by Makefile.PL¥n¥n";
        print W "CSRCS=";
        foreach(@c) {
                print W "$_ ";
        }
        print W "¥n";

        print W "HEADS=";
        foreach(@h) {
                print W "$_ ";
        }
        print W "¥n";

        print W <
              

↑って、ヘッダ作る機能があるようですが・・

実際、こうやって使います。

  • ???.xs
#define XS      1
#include "../xslib/xslib.h"

  • ???.c
#include "../xslib/xslib.h"

  • ../xslib/xslib.h
#ifndef XSLIB_H
#define XSLIB_H

#include "xsinclude.h"
#include "xsdef.h"

#ifdef  XS
        #include "EXTERN.h"
        #include "perl.h"
        #include "XSUB.h"
        #include "ppport.h"
#endif

#define STR_TMPLENGTH_      (sizeof(char) * )
#define STR_TMPLENGTH_0       (sizeof(char) * 0)

#endif

アンケート

このことに関する話題

このページのトラックバックURL
https://daiba.cx/?cmd=tb&tb_id=a9fffaf4eb9d9f0c8c1c

リンク元

Perl XS メモ/ひな形を作るのトラックバックはありません。