Swordkeeper has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I am currently working on a perl module to allow a direct interface with the a speech synth engine, and due to my need for portability and multi language use so that it is easily portable and usable by members of the blind computer using community I am forced to use swig for this. However a very important thing escapes my grasp, and after extensive searching on the web, through google, and even the perl manual pages I can not find information on gluing the 2 together. First of all, the perl manuals talk of many things, all as if I understand it already and as such they are of no use to me due to my own ignorance; and the swig documentation doesn’t even touch the makefile.pl format needed for a swig generated project, instead using a bash command line script that works, but does not seem like the perl way to me; I wish to know the perl way, but the format to convert my humble shell script into a makefile.pl as well as test and install the package, without pages of information I don’t need, is unfound, or at least hidden behind my ignorance. The script that creates my code, in shell script form is as follows:
#!/bin/bash swig -perl5 say.i gcc say.c say_wrap.c -fpic -c -I/usr/local/include/flite -L/usr/local/ +lib/ -I/usr/lib/perl5/5.8.0/i386-linux/CORE ld -G say.o say_wrap.o -lflite_cmu_us_kal -lflite_usenglish -lflite_cm +ulex -lflite -lm -o say.so
Could somone please help me understand what must be done to convert this into a makefile.pl? Once its done I plan on adding the info to the swig wiki so no one else has to go through this.

Replies are listed 'Best First'.
Re: Perl Module Make Format Conversion.
by Corion (Patriarch) on Mar 08, 2004 at 09:23 UTC

    The two modules performing the chores of module installation are ExtUtils::MakeMaker (classic) and Module::Build (new).

    Both have a different set of problems - ExtUtils::MakeMaker is a veteran module, tried and proven on many platforms, but if you want to do anything special in the build process, you're left with ugly manual parsing of the generated Makefile. Module::Build is new and has problems with older versions of CPAN, but it allows you more easily to extend the build process.

    I have done a similar yet different preprocessing step for one of my modules, the generation of Perl code from an abstract grammar, and used Module::Build for that. Here is my Module::Build script, adapted somewhat to your needs:

    use strict; use Module::Build; use Config; my $build = Module::Build->new ( module_name => 'Swordkeeper::Speechengine', license => 'perl', requires => { # 'perl' => '5.6.1', }, create_makefile_pl => 'passthrough' ); $build->do_system('swig','-perl5','say.i'); $build->do_system('gcc',qw(say.c say_warp.c -fpic -c -I/usr/local/incl +ude/flite -L/usr/local/lib/ -I/usr/lib/perl5/5.8.0/i386-linux/CORE)); $build->do_system('ld', qw(-G say.o say_wrap.o -lflite_cmu_us_kal -lfl +ite_usenglish -lfliste_cmulex -lflite -lm -o say.so)); $build->create_build_script;

    The above script plainly recreates your shell script, but this will not be very portable if anyone is using it with a differen version of Perl or a Perl compiled with a different compiler - for that, you should use the values provided in Config.pm, replacing gcc with $Config{cc} and so on, see perldoc Config.

    After you've written your Build.PL script, you need to add Module::Build in your prerequisites and include Build.PL and Makefile.PL in your module distribution (this is the passthrough Makefile.PL I stole from Autrijus):

    #!/usr/bin/perl # $File: //member/autrijus/XML-RSS-Aggregate/Makefile.PL $ # $Revision: 1.6 $ $Change: 2920 $ $DateTime: 2002/12/25 14:43:18 $ # This Makefile.PL creates a pass-through Makefile that simply calls # the equivalent Module::Build methods for each make target. See the # documentation for Module::Build::Compat for more information. unless (eval "use Module::Build::Compat 0.02; 1" ) { require Cwd; require File::Spec; require ExtUtils::MakeMaker; my $yn = ''; # Check if we're likely to have permission to install Module::Buil +d if (-w $INC{'ExtUtils/MakeMaker.pm'}) { # Check if we're under the non-reentrant CPAN.pm require CPAN; CPAN::Config->load; my $cwd = File::Spec->canonpath(Cwd::cwd()); my $cpan = File::Spec->canonpath($CPAN::Config->{cpan_home}); if (index($cwd, $cpan) == -1) { print "This module requires Module::Build to install itsel +f.\n"; $yn = ExtUtils::MakeMaker::prompt( ' Install Module::Build from CPAN?', 'y' ); } } if ($yn =~ /^y/i) { # Save this 'cause CPAN will chdir all over the place. my $cwd = Cwd::cwd(); my $makefile = File::Spec->rel2abs($0); if (eval { require CPANPLUS::Backend; 1 }) { CPANPLUS::Backend->new->install( modules => [ 'Module::Build' ] ); } else { require CPAN; CPAN::Shell->install('Module::Build::Compat'); } chdir $cwd or die "Cannot chdir() back to $cwd: $!"; exec $^X, $makefile, @ARGV; # Redo now that we have Module::B +uild } else { warn << '.'; This module requires Module::Build to install itself. Please re-run Makefile.PL with root privilege to install it automatically from CPAN, or manually download it from: http://search.cpan.org/author/KWILLIAMS/Module-Build/ . # Leave hints for CPAN.pm and CPANPLUS.pm ExtUtils::MakeMaker::WriteMakefile( PREREQ_PM => { 'Module::Build' => 0.11 } ); exit(0); } } Module::Build::Compat->run_build_pl(args => \@ARGV); Module::Build::Compat->write_makefile(); __END__ # Local variables: # c-indentation-style: bsd # c-basic-offset: 4 # indent-tabs-mode: nil # End: # vim: expandtab shiftwidth=4:
      Thank you so much, I had no idea the newer one even existed until now; much thanks.
Re: Perl Module Make Format Conversion.
by PodMaster (Abbot) on Mar 08, 2004 at 10:15 UTC
    ...documentation doesn’t even touch the makefile.pl format needed for a swig generated project...
    Really? What's http://www.swig.org/Doc1.3/Perl5.html then?

    Anyway, I wouldn't go the SWIG route, I'd stick with plain XS (I can't remember ever successfully compiling a module wrapped with SWIG on win32).

    For a quick comparison between XS and SWIG take a look at the swig version of String::Ediff and the XS version of the code. The intent of the module is to wrap a single C function.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      That doesnt show how to make a perl module package, just the command line methodes used to make the raw .so file as I said above; Also I'm not worried about windows since flite doesnt compile well under it anyway, its broken as a operating system, and I avoidusing it as a general rule. Besides there are better speech synth stuff for windows. My goal is simply to provide interaction with flite from perl under linux based systems so that the blind may use it. And I have to use swig for this, I dont have a choice in the matter... besides all the XS tutorials I could find are writen for the person who understands it in mind.
        Try this. Create a directory called "say" and place the file say.i in it, along with Makefile.PL which should look like
        #!/usr/bin/perl -w - use strict; use ExtUtils::MakeMaker; system q[ swig -perl5 say.i ]; WriteMakefile( 'NAME' => 'say', # Name of package 'INC' => ' -I/usr/local/include/flite ', 'LIBS' => [ ' -llflite_cmu_us_kal -lflite_usenglish -lflite_cmulex -lflite + -lm ' ], # Name of custom libraries 'OBJECT' => 'say.o say_wrap.o', # Object files );
        Now, execute the commands
        • perl Makefile.PL
        • make
        • make install
        If all that works out as it should, you should now have a module called "say" installed, and you can go ahead and execute "make dist" which should create a file "say-0.01.tar.gz" suitable for uploading to cpan.

        If you do plan to upload this to cpan, I'd suggest thinking about a better name since all lowercase package names are generally reserved for pragmas.

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.