Alien-Build

 view release on metacpan or  search on metacpan

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

Use the autoconf plugin (L<Alien::Build::Plugin::Build::Autoconf>).  If your package
provides a pkg-config C<.pc> file, then you can also use the PkgConfig plugin
(L<Alien::Build::Plugin::PkgConfig::Negotiate>).

 use alienfile
 plugin PkgConfig => 'libfoo';
 share {
   start_url => 'http://example.org/dist';
   plugin Download => (
     version => qr/libfoo-([0-9\.])\.tar\.gz$/,
   );
   plugin Extract => 'tar.gz';
   plugin 'Build::Autoconf';
 };

If you need to provide custom flags to configure, you can do that too:

 share {
   plugin 'Build::Autoconf';
   build [
     '%{configure} --disable-shared --enable-foo',
     '%{make}',
     '%{make} install',
   ];
 };

If your package requires GNU Make, use C<%{gmake}> instead of C<%{make}>.

=head3 autoconf without configure script

A number of Open Source projects are using autotools, but do not provide the
C<configure> script.  When alienizing these types of packages you have a
few choices:

=over 4

=item build configure using autotools

The Alien L<Alien::Autotools> is designed to provide autotools for building
such packages from source.  The advantage is that this is how the upstream
developers intend on having their package built.  The downside is that it
is also adds more prereqs to your Alien.  The silver lining is that if you
require this Alien in the C<share> block (as you should), then these prereqs
will only be pulled in during a share install when they are needed.

Please see the L<Alien::Autotools> documentation for specifics on how it
can be used in your L<alienfile>.

=item patch the package locally before build

You can use the L<alienfile/patch> directive to patch the alienized package
locally before building.  This can sometimes be challenging because Autotools
uses timestamps in order to decide what needs to be rebuilt, and patching
can sometimes confuse it into thinking more needs to be rebuilt than what
actually does.

=item build configure and tarball

You can also build the configure script during development of your alien,
generate the tarball and provide it somewhere like GitHub and use that
as the source instead of the original source.  This should usually be
a last resort if the other two methods prove too difficult.

=back

=head3 autoconf-like

If you see an error like this:

 Unknown option "--with-pic".

It is because the autoconf plugin uses the C<--with-pic> option by default, since
it makes sense most of the time, and autoconf usually ignores options that it does
not recognize.  Some autoconf style build systems fail when they see an option that
they do not recognize.  You can turn this behavior off for these packages:

 plugin 'Build::Autoconf' => (
   with_pic => 0,
 );

Another thing about the autoconf plugin is that it uses C<DESTDIR> to do a double
staged install.  If you see an error like "nothing was installed into destdir", that
means that your package does not support C<DESTDIR>.  You should instead use the
MSYS plugin and use a command sequence to do the build like this:

 share {
   plugin 'Build::MSYS';
   build [
     # explicitly running configure with "sh" will make sure that
     # it works on windows as well as UNIX.
     'sh configure --prefix=%{.install.prefix} --disable-shared',
     '%{make}',
     '%{make} install',
   ];
 };

=head3 CMake

There is an alien L<Alien::cmake3> that provides C<cmake> 3.x or better (It is preferred to the
older L<Alien::CMake>).  Though it is recommended that you use the C<cmake>
(L<Alien::Build::Plugin::Build::CMake>) plugin instead of using L<Alien::cmake3>.

 use alienfile;
 
 share {
   plugin 'Build::CMake';
   build [
     # this is the default build step, if you do not specify one.
     [ '%{cmake}',
         @{ meta->prop->{plugin_build_cmake}->{args} },
         # ... put extra cmake args here ...
         '.'
     ],
     '%{make}',
     '%{make} install',
   ];
 };

=head3 vanilla Makefiles

L<Alien::Build> provides a helper (C<%{make}>) for the C<make> that is used by Perl and

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

 $cflags = Alien::libfoo->alt('bar')->cflags ;  # compiler flags for 'bar'
 $cflags = Alien::libfoo->alt('baz')->cflags ;  # compiler flags for 'baz'

=head2 How to create an Alien module for packages that do not support pkg-config?

=head3 Packages that provide a configuration script

Many packages provide a command that you can use to get the appropriate version, compiler
and linker flags.  For those packages you can just use the commands in your L<alienfile>.
Something like this:

 use alienfile;
 
 probe [ 'foo-config --version' ];
 
 share {
   ...
 
   build [
     '%{make} PREFIX=%{.runtime.prefix}',
     '%{make} install PREFIX=%{.runtime.prefix}',
   ];
 };
 
 gather [
   [ 'foo-config', '--version', \'%{.runtime.version}' ],
   [ 'foo-config', '--cflags',  \'%{.runtime.cflags}'  ],
   [ 'foo-config', '--libs',    \'%{.runtime.libs}'    ],
 ];

=head3 Packages that require a compile test

Some packages just expect you do know that C<-lfoo> will work.  For those you can use
the C<cbuilder> plugin (L<Alien::Build::Plugin::Probe::CBuilder>).

 use alienfile;
 plugin 'Probe::CBuilder' => (
   cflags => '-I/opt/libfoo/include',
   libs   => '-L/opt/libfoo/lib -lfoo',
 );
 
 share {
   ...
   gather sub {
     my($build) = @_;
     my $prefix = $build->runtime_prop->{prefix};
     $build->runtime_prop->{cflags} = "-I$prefix/include ";
     $build->runtime_prop->{libs}   = "-L$prefix/lib -lfoo ";
   };
 }

This plugin will build a small program with these flags and test that it works.  (There
are also options to provide a program that can make simple tests to ensure the library
works).  If the probe works, it will set the compiler and linker flags.  (There are also
options for extracting the version from the test program).  If you do a share install
you will need to set the compiler and linker flags yourself in the gather step, if you
aren't using a build plugin that will do that for you.

=head2 Can/Should I write a tool oriented Alien module?

Certainly.  The original intent was to provide libraries, but tools are also quite doable using
the L<Alien::Build> toolset.  A good example of how to do this is L<Alien::nasm>.  You will want
to use the 'Probe::CommandLine':

 use alienfile;
 
 plugin 'Probe::CommandLine' => (
   command => 'gzip',
 );

=head2 How do I test my package once it is built (before it is installed)?

Use L<Test::Alien>.  It has extensive documentation, and integrates nicely with L<Alien::Base>.

=head2 How do I patch packages that need alterations?

If you have a diff file you can use patch:

 use alienfile;
 
 probe sub { 'share' }; # replace with appropriate probe
 
 share {
   ...
   patch [ '%{patch} -p1 < %{.install.patch}/mypatch.diff' ];
   build [ ... ] ;
 }
 
 ...

You can also patch using Perl if that is easier:

 use alienfile;
 
 probe sub { 'share' };
 
 share {
   ...
   patch sub {
     my($build) = @_;
     # make changes to source prior to build
   };
   build [ ... ];
 };

=head2 The flags that a plugin produces are wrong!

Sometimes, the compiler or linker flags that the PkgConfig plugin comes up with are not quite
right.  (Frequently this is actually because a package maintainer is providing a broken
C<.pc> file).  (Other plugins may also have problems).  You could replace the plugin's C<gather> step
but a better way is to provide a subroutine callback to be called after the gather stage
is complete.  You can do this with the L<alienfile> C<after> directive:

 use alienfile;
 
 plugin 'PkgConfig' => 'libfoo';
 
 share {
   ...
   after 'gather' => sub {
     my($build) = @_;



( run in 0.336 second using v1.01-cache-2.11-cpan-5b529ec07f3 )