=head1 NAME

Alien::Base::Authoring - Authoring an C<Alien::> module

=head1 DESCRIPTION

Congratulations! You have made the decision to help the Perl community by providing a C library via CPAN. The L<Alien> namespace has been instrumental in providing C libraries for many years, but authoring those modules has been a commitment that most authors weren't willing to take on. L<Alien::Base> tries to ease that pain by providing most of the needed functionality; usually authors should only need a little boilerplate and configuration!

=head1 STATUS

L<Alien::Base> is under active development and is currently beta release. The author hopes that the API has stabilized, but will not promise that it has. Please resist the temptation to use it for production code until the warning is removed. Of course you are welcomed, and in fact encouraged, to test it with for your favorite library; if you do, you are more than welcome to share your experience with me.

=head1 ECOSYSTEM

The L<Alien::Base> ecosystem is made up of several elements. Some of these elements are the base classes in the distribution itself. Of course, no ecosystem is complete without inhabitants, therefore, it is also important to consider the users of these base classes. This documentation will assume that you are writing C<Alien::MyLibrary> which provides F<libmylibrary.so>. Further it will assume that you or someone else is going to use this module/library to write C<Some::Module::MyLibrary>. Finally an end user might use that module to write F<myscript.pl>.

=head2 Alien::Base::ModuleBuild

L<Alien::Base::ModuleBuild> provides a base class, utility methods and configuration handling for the build/install phase of the library. It is itself a subclass of L<Module::Build>, which is what supports the building and installing of the surrouning C<Alien::> module. C<Alien::MyLibrary>'s F<Build.PL> file will use L<Alien::Base::ModuleBuild> to create its builder object.

 # file: Alien-MyLibrary/Build.PL
 use Alien::Base::ModuleBuild;
 my $builder = Alien::Base::ModuleBuild->new(...);
 $builder->create_build_script;

This is just like you would do for L<Module::Build>, except that there will be a few additional configuration parameters (see L<Alien::Base::ModuleBuild::API>).

L<Alien::Base::ModuleBuild> adds the additional build actions C<alien_code> and C<alien_install>. These actions need never be run directly, the usual C<build> action (usually seen as C<./Build>) and C<install> (C<./Build install>) will call them for you. The C<alien_code> action is responsible for finding, downloading, extracting and building the external libary (the commands specified in builder parameter C<alien_build_commands>). The C<alien_install> action is responsible for installing the library into its final destination.

The C<./Build test> command will invoke any library tests specified in C<alien_test_commands>, though none are defined by default. Finally C<./Build install> will invoke whatever C<alien_install_commands> were specified.

=head2 Alien::Base

L<Alien::Base> is the base class of C<Alien::MyLibrary>. In this context, L<Alien::Base> has two distinct uses. First it is used by C<Alien::MyLibrary> to provide the build information/flags for building C<Some::Module::MyLibrary>. Secondly it is used (again through C<Alien::MyLibrary>) to provide run-time access to F<libmylibrary.so> to C<Some::Module::MyLibrary>.

=head3 Alien::Base for Building

C<Alien::MyLibrary> is called by C<Some::Library::MyLibrary>'s build script, either F<Build.PL> or F<Makefile.PL>. Most of the functionality can be utilized through class method calls, though creating an object can save a few keystrokes.

 # file: Some-Module-MyLibrary/Build.PL
 use Module::Build;
 use Alien::MyLibrary;

 my $alien = Alien::MyLibrary->new;
 my $builder = Module::Build->new(
   ...
   extra_compiler_flags => $alien->cflags(),
   extra_linker_flags   => $alien->libs(),
 );
 $builder->create_build_script;

Additional information can be gotten from the C<config> method.

=head3 Alien::Base for Run-Time Provision

C<Alien::MyLibrary> must be a subclass of L<Alien::Base>. This provides the C<import> method, which does the run-time provisioning so that when the XS file is loaded, it can find F<libmylibrary.so>. The C<import> method does this by pre-loading the library via C<DynaLoader::dl_load_file> which is a platform-independent wrapper for C<dlopen> or your system's equivalent. It no longer appends to C<$ENV{LD_RUN_PATH}>.

 # file: Alien-MyLibrary/lib/Alien/MyLibrary.pm
 package Alien::MyLibrary;

 use parent 'Alien::Base';

 1;

Finally, C<Alien::MyLibrary> must also be called by C<Some::Library::MyLibrary> before C<DynaLoader::bootstrap> or C<XSLoader::load>. The C<use> directive is recommended, however if you must use C<require> then be sure to call the C<import> method too. Without this C<import> call, the loader doesn't know where to find F<libmylibrary.so>.

 # file: Some-Module-MyLibrary/lib/Some/Module/MyLibrary.pm
 package Some::Module::MyLibrary;

 use Alien::MyLibrary;
 our $VERSION = '0.54';

 require XSLoader;
 XSLoader::load('Some::Module::MyLibrary', $VERSION);

 # your code

=head1 EXAMPLES

The example code that was housed in this distribution during alpha phase has been moved to two different CPAN distributions. Those are:

=over

=item *

L<Acme::Alien::DontPanic> -- An example C<Alien::> module which provides F<libdontpanic.so>. It provides the C function C<answer> which is simply:

 int answer () { return 42 }

=item *

L<Acme::Ford::Prefect> -- An XS module which provides the Perl-level access to C<answer>. It relies on F<libdontpanic.so> and uses L<Acme::Alien::DontPanic> to locate/load it.

=back

Additionally, there exists in-production C<Alien::> distributions that serve as de-facto tests of L<Alien::Base>'s networking components:

=item *

L<Alien::LibYAML> -- Builds and installs F<libyaml>, acquiring the library archive from its hosted location via C<Alien::Base::Repository::HTTP>.


=back

Also, the author intends to convert L<Alien::GSL> to use this system as soon as it is production ready, so that C<Alien::> authors can see another "Code in the Wild" example. Until then, a pre-release version of this module is provided in the F<examples> directory as well.
 
=head1 AUTHOR

Joel Berger <joel.a.berger@gmail.com>

=head1 SEE ALSO

=over

=item * 

L<Module::Build>

=item *

L<Alien>

=item *

L<Alien::Base>

=back

=head1 SOURCE REPOSITORY

L<http://github.com/Perl5-Alien/Alien-Base>

=head1 AUTHOR

Joel Berger, E<lt>joel.a.berger@gmail.comE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2012-2014 by Joel Berger

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

=cut
