Perl XSメモ - ひな形を作る
[Perl XS メモへ戻る]
- Perl XSメモ - ひな形を作る
-
- いくつか、ツールがあるのですが・・・
- ひな形はできても・・・
- なら、少し共通化すればいいんじゃないの?
- ん?ライブラリ?
- ↑って、ヘッダ作る機能があるようですが・・
- アンケート
- このことに関する話題
いくつか、ツールがあるのですが・・・
結局、標準で使われる、Extutils::Makemakerだけに落ち着きました。
h2xs -An XS::ModuleName
ひな形はできても・・・
このままじゃ、使う気がしません。
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つのモジュールを開発するだけならいいのですが、いくつか開発することを前提に、共通化してみます。
use 5.;
require "../xsmake/xsbuild.pl";
&writemakefile(
Module=>"XS::ModuleName",
File=>"ModuleName.pm",
Author=>'Nanami <>',
Libs=>['-L../xslib -lxslib'],
);
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 <
↑って、ヘッダ作る機能があるようですが・・
実際、こうやって使います。
#define XS 1
#include "../xslib/xslib.h"
#include "../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
アンケート
このことに関する話題