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 )