Alien-Build

 view release on metacpan or  search on metacpan

lib/Alien/Build/Manual/AlienAuthor.pod  view on Meta::CPAN

 Alien::Build::Plugin::Core::Download> candidate *https://www.libfoo.org/download/libfoo-1.2.4.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.3.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.2.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.1.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.2.0.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.9.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.8.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  https://www.libfoo.org/download/libfoo-1.1.7.tar.gz
 Alien::Build::Plugin::Core::Download> candidate  ...
 Alien::Build::Plugin::Core::Download> setting version based on archive to 1.2.4
 Alien::Build::Plugin::Core::Download> downloaded libfoo-1.2.4.tar.gz
 App::af::install>  [ before build ] + bash
 /tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$ ls
 CHANGES Makefile autoconf.ac lib
 /tmp/fbVPu4LRTs/build_5AVn/libfoo-1.2.4$

There are a lot of other useful things that you can do with the C<af>
command.  See L<af> for details.

=head2 Integrating with MakeMaker

Once you have a working L<alienfile> you can write your C<Makefile.PL>.

 use ExtUtils::MakeMaker;
 use Alien::Build::MM;
 
 my $abmm = Alien::Build::MM->new;
 
 WriteMakefile($abmm->mm_args(
   ABSTRACT           => 'Discover or download and install libfoo',
   DISTNAME           => 'Alien-Libfoo',
   NAME               => 'Alien::Libfoo',
   VERSION_FROM       => 'lib/Alien/Libfoo.pm',
   CONFIGURE_REQUIRES => {
     'Alien::Build::MM' => 0,
   },
   BUILD_REQUIRES => {
     'Alien::Build::MM' => 0,
   },
   PREREQ_PM => {
     'Alien::Base' => 0,
   },
   # If you are going to write the recommended
   # tests you will will want these:
   TEST_REQUIRES => {
     'Test::Alien' => 0,
     'Test2::V0'   => 0,
   },
 ));
 
 sub MY::postamble {
   $abmm->mm_postamble;
 }

The C<lib/Alien/Libfoo.pm> that goes along with it is very simple:

 package Alien::Libfoo;
 
 use strict;
 use warnings;
 use parent qw( Alien::Base );
 
 1;

You are done and can install it normally:

 % perl Makefile.PL
 % make
 % make test
 % make install

=head2 Integrating with Module::Build

Please don't!  Okay if you have to there is L<Alien::Build::MB>.

=head2 Non standard configuration

L<Alien::Base> support most of the things that your L<Alien> will need,
like compiler flags (cflags), linker flags (libs) and binary directory
(bin_dir).  Your library or tool may have other configuration items
which are not supported by default.  You can store the values in the
L<alienfile> into the runtime properties:

 gather [
   # standard:
   [ 'foo-config --version libfoo', \'%{.runtime.version}' ],
   [ 'foo-config --cflags  libfoo', \'%{.runtime.cflags}'  ],
   [ 'foo-config --libs    libfoo', \'%{.runtime.libs}'    ],
   # non-standard
   [ 'foo-config --bar-baz libfoo', \'%{.runtime.bar_baz}' ],
 ];

then you can expose them in your L<Alien::Base> subclass:

 package Alien::Libfoo;
 
 use strict;
 use warnings;
 use parent qw( Alien::Base );
 
 sub bar_baz {
   my($self) = @_;
   $self->runtime_prop->{bar_baz},
 };
 
 1;

=head2 Testing

(optional, but highly recommended)

You should write a test using L<Test::Alien> to make sure that your
alien will work with any XS modules that are going to use it:

 use Test2::V0;
 use Test::Alien;
 use Alien::Libfoo;
 
 alien_ok 'Alien::Libfoo';
 
 xs_ok do { local $/; <DATA> }, with_subtest {
   is Foo::something(), 1, 'Foo::something() returns 1';
 };
 
 done_testing;
 
 __DATA__
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
 #include <foo.h>
 
 MODULE = Foo PACKAGE = Foo
 
 int something()

You can also use L<Test::Alien> to test tools instead of libraries:

 use Test2::V0;
 use Test::Alien;
 use Alien::Libfoo;
 
 alien_ok 'Alien::Libfoo';
 run_ok(['foo', '--version'])
   ->exit_is(0);
 
 done_testing;

You can also write tests specifically for L<FFI::Platypus>, if your
alien is going to be used to write FFI bindings.  (the test below
is the FFI equivalent to the XS example above).

 use Test2::V0;
 use Test::Alien;
 use Alien::Libfoo;
 
 alien_ok 'Alien::Libfoo';
 ffi_ok { symbols => [ 'something' ] }, with_subtest {
   # $ffi is an instance of FFI::Platypus with the lib



( run in 0.508 second using v1.01-cache-2.11-cpan-524268b4103 )