Hybrid Module Question

M

Mark Shelor

I'm the author of a CPAN module that contains XSUBs written in C. In
other words, users are required to have a C compiler to build the module.

In the future, I'd like to also include pure Perl versions of these
subroutines so that the module can still be used even if a C compiler
isn't present. I assumed there was a more-or-less standard way to go
about writing a hybrid module, but I've yet to find specific guidelines
in the Perl documentation I've looked at.

Basically, I want to set things up such that the C-language XSUBs are
automatically used if the build platform has a C compiler. Otherwise,
the pure Perl versions of the routines would be installed.

Could anyone point me to relevant examples or how-to documentation?

Thanks, Mark
 
U

Uri Guttman

MS> Basically, I want to set things up such that the C-language XSUBs are
MS> automatically used if the build platform has a C compiler. Otherwise,
MS> the pure Perl versions of the routines would be installed.

MS> Could anyone point me to relevant examples or how-to documentation?

i do this exact thing in stem. it is very simple. you make the C and
perl versions into sibling classes and have a wrapper class above
them. something like this:

Foo.pm
Foo/Perl.pm
Foo/C.pm

the user always creates a Foo but inside that it tries to load Foo/C.pm
and it uses that if it can. else it tries to load Foo/Perl.pm and that
had better succeed or you die.

here is my code that does this. it tries to load the event loop you
request which is normally the c module Event.pm and falls back to my
Perl event loop. on winblows it always uses the Perl one since Event.pm
is unix specific.

the can't locate a module is the only error allowed. then it
will do the forced load of Perl.pm

my $loop_type = $Stem::Vars::Env{ 'event_loop' } ||
($^O =~ /win32/i ? 'perl' : 'event' );

my $loop_class = $loop_to_class{ $loop_type } || 'Stem::Event::perl' ;

unless ( eval "require $loop_class" ) {
die "can't load $loop_class: $@" if $@ && $@ !~ /locate/ ;

eval 'require Stem::Event::perl' ;
die "can't load default event loop Stem::Event::perl $@" if $@ ;
}

uri
 
M

Malcolm Dew-Jones

Mark Shelor ([email protected]) wrote:
: I'm the author of a CPAN module that contains XSUBs written in C. In
: other words, users are required to have a C compiler to build the module.

: In the future, I'd like to also include pure Perl versions of these
: subroutines so that the module can still be used even if a C compiler
: isn't present. I assumed there was a more-or-less standard way to go
: about writing a hybrid module, but I've yet to find specific guidelines
: in the Perl documentation I've looked at.

: Basically, I want to set things up such that the C-language XSUBs are
: automatically used if the build platform has a C compiler. Otherwise,
: the pure Perl versions of the routines would be installed.

: Could anyone point me to relevant examples or how-to documentation?

MIME::Base64 does this.
 
T

Tassilo v. Parseval

Also sprach Malcolm Dew-Jones:
Mark Shelor ([email protected]) wrote:
: I'm the author of a CPAN module that contains XSUBs written in C. In
: other words, users are required to have a C compiler to build the module.

: In the future, I'd like to also include pure Perl versions of these
: subroutines so that the module can still be used even if a C compiler
: isn't present. I assumed there was a more-or-less standard way to go
: about writing a hybrid module, but I've yet to find specific guidelines
: in the Perl documentation I've looked at.

: Basically, I want to set things up such that the C-language XSUBs are
: automatically used if the build platform has a C compiler. Otherwise,
: the pure Perl versions of the routines would be installed.

: Could anyone point me to relevant examples or how-to documentation?

MIME::Base64 does this.

The 2.x releases at least do it. It's quite a clutch, though. It works
by having the user delete Base64.xs before building it. Not something
that I would call very elegant.

I think it should be possible with three distinct Makefile.PLs. The
top-level one checks for the existance of a C compiler. If one is found,
it calls, for example, xs/Makefile.PL. Otherwise it will call
perl/Makefile.PL. The pure Perl version and the XS version would then
have to live in separate sub directories.

It has to be ensured that the correct Makefile is called in the correct
directory. So another approach would be to have the top-level
Makefile.PL create the correct Makefile. When doing 'make', things will then
descend into one of the two directories and trigger the standard
procedure 'perl Makefile.PL; make; make test; make install'.

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top