Re: [Module::Build] mb advice in CPAN READMEs
Status: Beta
Brought to you by:
kwilliams
|
From: Marvin H. <ma...@re...> - 2006-02-14 05:22:04
|
On Feb 13, 2006, at 6:37 PM, Marvin Humphrey wrote:
> On Feb 13, 2006, at 5:29 PM, David Golden wrote:
>> So unless you're doing those things I'd say give 'traditional' a
>> try. If it works for you, then it's just that much easier for
>> others. (And one less potential bug report to worry about.)
>
> 'traditional' doesn't work in this case, because traditional
> doesn't know about c_source, or .xs files in the lib tree.
>
> It's not that I'm doing something with MB that can't be done with
> EUMM, it's just easier dealing with MB.
Let me elaborate:
Lingua::Stem::Snowball is the Perl interface to the C version of the
Snowball stemming library. These days, that C library comes in it's
own tarball, which unpacks nicely into a dir called libstemmer_c.
I've rewritten Lingua::Stem::Snowball to use the most recent version
of the library; the revised module is much faster, offers UTF-8
compatibility, doesn't segfault any more, and a bunch of other good
stuff. As of this morning, it's official: I'm taking over
maintenance responsibility.
Unfortunately, the Makefile that comes with libstemmer_c isn't
portable. That's not a problem, if I use MB -- all I have to do is
specify 'c_source => "libstemmer_c"' in the MB constructor, and put
'#include "libstemmer.h"' in Snowball.xs. MB ignores libstemmer_c/
Makefile; everything gets compiled in place, and it all Just Works.
As far as I can tell, EUMM has no equivalent behavior. So far, I've
explored four ways of attacking the problem using EUMM.
The first possibility is to override MY::postamble as per the the
EUMM docs (which use sdbm as an example)...
sub MY::postamble {
return <<'MAKE_FRAG';
$(MYEXTLIB): sdbm/Makefile
cd sdbm && $(MAKE) all
MAKE_FRAG
}
... but that won't work, because the stock libstemmer_c/Makefile
isn't portable.
The second way of doing things is to follow perlxstut example #4,
which is godawful voodoo <http://perldoc.perl.org/
perlxstut.html#EXAMPLE-4>. It involves writing a libstemmer_c/
Makefile.PL to generate a libstemmer_c/Makefile -- essentially, I
have to duplicate the functionality of the existing libstemmer_c/
Makefile, rewriting it through a layer of indirection using EUMM's
convoluted interface. This Makefile.PL has to do things like
override MY::top_targets (huh?), which spec Make targets like
"pure_all" (huh?), "static" (huh?)...
The third way of doing things is used by the current
Lingua::Stem::Snowball Makefile.PL, which was written a long time ago
by people no longer involved with the project: use File::Find to grab
all the C files and create a list of object files, supplying those to
OBJECT.
Unfortunately, MakeMaker dumps all .o files into the current
directory, and since libstemmer_c's C files are divided up into
multiple directories, they contain stuff like...
#include "../src_c/stem_UTF_8_english.h"
... which can't be found because of where MakeMaker puts the .o
file. So... it looks like what the original authors did was write a
config.c file that #included every .h file, then tailored all the XS
functions to use only the low-level API. They essentially rewrote
libstemmer.h/libstemmer.c from scratch. Hopefully they didn't do
this just because of MakeMaker, but perhaps because libstemmer.h
wasn't available in its present form at the time. Needless to say, I
don't want to carry forward that tradition.
The fourth way was suggested by Tye McQueen (tye on PerlMonks, TYEMQ
on CPAN). He offered his Makefile.PL for Win32API::File as an
example of how I might customize a Makefile.PL to force the compile
commands into a desired form: <http://search.cpan.org/src/TYEMQ/
Win32API-File-0.09/Makefile.PL>. I stared at it a while stupidly,
then gave up.
There's gotta be a way to do this with MakeMaker. Maybe a way to add
"-o $fullpath" to each compile command-string. But here's where the
difficulty of customizing MakeMaker comes in. It's taken me a
looonnnngggg time to even get to this point. I've been through the
EUMM/perlxs/perlxstut/etc docs time and again, and I think I've
finally figured out what it would take to make that danged -o param
appear: I have to override MY::c_o and perform a regex substitution
on the value it normally returns. That strikes me as kludgy and
brittle.
Then there's MB....... which... just... works......
Marvin Humphrey
Rectangular Research
http://www.rectangular.com/
|