Alien-Base-ModuleBuild

 view release on metacpan or  search on metacpan

lib/Alien/Base/ModuleBuild/FAQ.pod  view on Meta::CPAN

 xs_ok $xs, with_subtest {
   my($module) = @_;
   ok $module->version;
 };
 
 done_testing;
 
 __DATA__
 
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
 #include <editline/readline.h>
 
 /* having a string parameter that we ignore
    allows us to call this as a class method */
 const char *
 version(const char *class)
 {
   return rl_library_version;
 }
 
 MODULE = TA_MODULE PACKAGE = TA_MODULE
 
 const char *version(class);
     const char *class;

=head2 How do I patch packages that need minor (or major) alterations?

One approach is to create a unified diff for patches that you want to apply and simply run patch on them.  The
L<Alien::patch> and the C<%{patch}> helper can be used like this:

 # Build.PL
 use Alien::Base::ModuleBuild;
 
 Alien::Base::ModuleBuild->new(
   ...
   alien_bin_requires => {
     'Alien::patch' => 0.06, # needed for %{patch} helper
   },
   alien_build_commands => [
     '%{patch} -p1 < ../../patch/mypackage.patch',
     ...
   ],
   ...
 )->create_build_script;

Create a folder in your distribution root called C<patch> and place the C<mypackage.patch> file in there.  Since
the C<patch> command will be executed in the package root instead of the distribution root, you need to use a
relative path prefixed by C<../..>.  Here we use L<Alien::patch> to provide patch even in environments where it
is not provided.

A more powerful approach to patching is to write a perl subroutine to modify the source after it has been
extracted.  One way to do this is to create a module in your distribution's inc directory that does the
patching (modules in inc can be used during build/test but won't be installed):

 # inc/My/AlienPatch.pm
 package My::AlienPatch;
 
 # add this sub to the main namespace
 # so we don't need to quote or escape
 # anything below
 sub main::alien_patch {
   # is executed in the package root,
   # make what ever changes you need to
   # to the source here.
 }
 
 1;
 
 # Build.PL
 use Alien::Base::ModuleBuild;
 
 Alien::Base::ModuleBuild->new(
   ...
   alien_build_commands => [
     # %x will be replaced by path for calling Perl
     # from the command line
     "%x -I../../inc -MMy::AlienPatch -e alien_patch",
     ...
   ],
   ...
 )->create_build_script;

=head2 How do I build a package that uses I<build system>?

=head3 autoconf

By default L<Alien::Base::ModuleBuild> assumes a package with an autoconf style C<configure> script.  The
default is

 # Build.PL
 use Alien::Base::ModuleBuild;
 Alien::Base::ModuleBuild->new(
   ...
   alien_build_commands => [
     '%c --prefix=%s',
     'make',
   ],
   alien_install_commands => [
     'make install',
   ],
   ...
 )->create_build_script;

There are a couple of short cuts here, C<%c> indicates the platform independent method for executing the
C<configure> script, plus any normal autoconf flags that are appropriate for Perl Alien libraries. The C<%c>
also tells L<Alien::Base::ModuleBuild> to use L<Alien::MSYS> on Windows platforms and to add that as a
dependency.  The C<%s> is a placeholder for the location to which the package will be installed.  This is
normally in a share directory specific to your distribution.

=head3 autoconf-like

If you see an error like this:

 Unknown option "--with-pic".

It may be because your package provides a C<configure> script that provides an autoconf-style interface, but is
not actually autoconf.  L<Alien::Base::ModuleBuild> is aggressive in using the C<--with-pic> option because when
supported by autoconf it produces position independent code (important for reliably building XS extensions), and
when not supported autoconf simply ignores the option. Unfortunately some autoconf-style C<configure> scripts



( run in 0.800 second using v1.01-cache-2.11-cpan-13bb782fe5a )