# PODNAME: Alien::Build::Manual::FAQ
# ABSTRACT: Frequently Asked Questions about Alien::Build
# VERSION

__END__

=pod

=encoding UTF-8

=head1 NAME

Alien::Build::Manual::FAQ - Frequently Asked Questions about Alien::Build

=head1 VERSION

version 0.42

=head1 SYNOPSIS

 perldoc Alien::Build::Manual::FAQ

=head1 DESCRIPTION

This document serves to answer the most frequently asked questions made by developers
creating L<Alien> modules using L<Alien::Build>.

=head1 QUESTIONS

=head2 What is Alien, Alien::Base and Alien::Build?

Alien in a Perl namespace for defining dependencies in CPAN for libraries and tools which
are not "native" to CPAN.  For a manifesto style description of the Why, and How see
L<Alien>.  L<Alien::Base> is a base class for the L<Alien> runtime.  L<Alien::Build> is
a tool for probing the operating system for existing libraries and tools, and downloading, building
and installing packages.  L<alienfile> is a recipe format for describing how to probe,
download, build and install a package.

=head2 How do I specify a minimum or exact version requirement for packages that use pkg-config?

The various pkg-config plugins all support a minimum_version field:

 use alienfile;
 
 plugin 'PkgConfig', pkg_name => foo, minimum_version => '1.2.3';

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

Depends on how you probe for and build for a package.  Most things can be done by providing
commands.  For example if you have a C<foo> package that provides a C<foo-config> program
to provide the normal C<pkg-config> fields then you could do something like this:

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

=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;
 
 ...
 
 share {
   ...
   patch [ '%{patch} -p1 < %{.install.patch}/mypatch.diff' ];
   build [ ... ] ;
 }
 
 ...

You can also patch using Perl if that is easier:

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

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

=head3 autoconf

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 {
   plugin Download => (
     url => 'http://example.org/dist',
     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-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 L<Alien> for cmake: L<Alien::CMake>, and a helper C<%{cmake}> which will
automatically pull it in as needed.  (Help wanted, an actual working example for this
FAQ).

=head3 vanilla Makefiles

You can use the C<%{make}> or C<%{gmake}> helper (use the latter if your package
requires GNU Make.  You can also use perl configuration to make sure that position
independent code is generated:

 build {
   build [
     [ '%{make}', 'CC=%{perl.config.cc}', 'CFLAGS=%{perl.config.cccdlflags} %{perl.config.optimize}' ],
     [ '%{make}', 'install', 'PREFIX=%{.install.prefix}' ],
   ],
 };

=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 use Alien::Build from Dist::Zilla?

For creating L<Alien::Base> and L<Alien::Build> based dist from L<Dist::Zilla> you can use the
dzil plugin L<Dist::Zilla::Plugin::AlienBuild>.

=head2 I have a question not listed here!

There are a number of forums available to people working on L<Alien>, L<Alien::Base> and
L<Alien::Build> modules:

=over 4

=item C<#native> on irc.perl.org

This is intended for native interfaces in general so is a good place for questions about L<Alien>
generally or L<Alien::Base> and L<Alien::Build> specifically.

=item mailing list

The C<perl5-alien> google group is intended for L<Alien> issues generally, including L<Alien::Base>
and L<Alien::Build>.

L<https://groups.google.com/forum/#!forum/perl5-alien>

=item Open a support ticket

If you have an issue with L<Alie::Build> itself, then please open a support ticket on the project's GitHub issue 
tracker.

L<https://github.com/plicease/Alien-Build/issues>

=back

=head1 SEE ALSO

L<Alien::Build>, L<Alien::Build::MM>, L<Alien::Build::Plugin>, L<alienfile>

=head1 AUTHOR

Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>

Contributors:

Diab Jerius (DJERIUS)

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2017 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
