=pod

=for comment
DO NOT EDIT. This Pod was generated by Swim v0.1.30.
See http://github.com/ingydotnet/swim-pm#readme

=encoding utf8

=head1 NAME

Inline::Module::Tutorial - Make "XS" modules for CPAN, the easy way

=head1 OVERVIEW

This tutorial will teach you how to write "extension" modules for CPAN using
L<Inline::Module>. The normal way to do this is with "XS", Perl's mechanism
for binding C and C++ code to Perl. Inline::Module lets you do this much
easier, avoiding the need to learn XS, but delivering results that are as
robust as hand-written XS.

=head1 BASICS

The tutorial starts by showing you how an example module (that is actually on
CPAN), was created with Inline::Module. The module is called
L<Acme::Math::XS>, and its purpose (besides trivial math functions) is to
demonstrate how to do this.

=head2 The Makefile.PL

No matter which framework you use to make modules (L<ExtUtils::MakeMaker>,
L<Dist::Zilla>) etc, you'll need to add a little metadata to the controls. For
now we'll just show C<Makefile.PL> way:

    use ExtUtils::MakeMaker;
    WriteMakefile(
      NAME => 'Acme::Math::XS',
      ...
    );

    use lib 'inc';
    use Inline::Module;
    FixMakefile(
      module => 'Acme::Math::XS',
      inline => 'Acme::Math::XS::Inline',
      ilsm => 'Inline::C',
    );

So you need to use C<Inline::Module> and call C<FixMakefile> after
C<WriteMakefile>. The arguments specify the information the L<Inline::Module>
needs to do the right things.

NOTE: You also need to add C<inc> to @INC, even if doesn't exist while you are
      developing and testing. It will exist when you ship it to CPAN, and the
      C<make install> process needs it to work properly.

=head2 The Module

Next we'll "inline" some C code into a Perl module called
C<lib/Acme/Math/XS.pm>. Here is the real module, but condensed a bit:

    use strict; use warnings;
    package Acme::Math::XS;
    our $VERSION = '1.2.3';
    use Exporter 'import';
    our @EXPORT = qw(add subtract);
    use Acme::Math::XS::Inline C => <<'...';
    long add(long a, long b) { return a + b; }
    long subtract(long a, long b) { return a - b; }
    ...
    1;

Normally you use L<Inline::C> like this:

    use Inline C => '<... c code ...>';

but here we just change C<Inline> to C<Acme::Math::XS::Inline>. This is the
key part of how Inline::Module works. Since we want to I<use> Inline but not
I<depend> on it when the user installs this module, we do this trick. The
C<::Inline> module is a little generated stub that knows how to do all the
right magics.

=head2 The Inline Stub Module

Next you'll need to actually generate the stub module. You only need to do
this once. Run this command:

    perl-inline-module generate Acme::Math::XS::Inline

You'll get a C<lib/Acme/Math/XS/Inline.pm> that looks like this:

    use strict; use warnings;
    package Acme::Math::XS::Inline;
    use base 'Inline';
    use Inline::Module 'v1' => '1.23';
    1;

The astute tutorialist will note that this module depends in C<Inline> and
C<Inline::Module>, and that's a no-no. That's because this stub is used for
author side development and testing, and another stub replaces it at module
release time.

That stub will look like this:

    use strict; use warnings;
    package Acme::Math::XS::Inline;
    use base 'DynaLoader';
    bootstrap Acme::Math::XS::Inline;
    1;

And everything is fine. We are just using Dynaloader, the age old loader of
extension libraries. As long the shared library stuff gets built into the
C<blib> directory at user build time (and it does!) we are good to go.

=head2 Testing

There are a few ways to test stuff and I'll describe them here. They should be
familiar to most module authors.

=over

=item C<prove -lv t/>

This is the easiest and most common method of testing for B<non>-XS module
authors. Since Inline is involved, the compilation steps just work.

With XS, you typically need to run C<perl Makefile.PL && make> first, and you
also need to add the C<-b> flag to C<prove> to tell it to look in the new
C<blib>. Then you need to continually make sure to repeat this every time you
change C code. With Inline, you can relax a bit.

=item C<perl Makefile.PL && make test>

You can also use the XS style. It all works out the same.

=item C<prove -bv t/>

In this style, you are just invoking the C<blib> results directly, and Inline
is not involved. Use this if you want to know that no nothing is up a sleeve,
but don't forget that auto-compilation can't happen this way.

=back

=head2 Making a Distribution (Tarball)

Now it's time to make the final product and ship it to CPAN. The mechanics are
dead simple:

    perl Makefile.PL
    make dist

Same as any other module. Some magic is happening though to make it all work.
You asked for this magic in your C<Makefile.PL> changes!

C<Inline::Module> modifies 2 targets in the Makefile:

=over

=item C<distdir>

This is the target that buils the distribution directory (before it is
tarred up).

=item C<pure_all>

This odd sounding rule is actually the primary/default rule. It gets invoked
when you run:

    make

without arguments. In other words, the build step.

=back

In the C<distdir> phase, we need to:

=over

=item * Add the C<Inline> modules that control building, under C<inc/>:

=over

=item * Inline::Module

=item * Inline::Module::Makemaker

=item * Inline

=item * Inline::C

=item * a couple helper modules

=back

=back

We also need to move the test/build C<lib/Acme/Math/XS/Inline.pm> under
C<inc/> and put the C<Dynaloader> version in its place under C<lib>.

The C<pure_all> phase is simply tweaked to rearrange the exact location of
things that get generated under C<blib>. Then they are ready to be installed
properly/normally by C<make install>.

=head2 Ship It

Assuming you've done all the other parts of normal CPAN modules authoring, we
are done here. Upload your module and watch CPAN Testers for results on tons
of different platforms.

=head1 USING OTHER CPAN BUILD PLATFORMS

This section will describe how to do everything we just did, using the other
popular CPAN build systems, like L<Dist::Zilla>.

=head2 L<Dist::Zilla>

Let's start with this one, since it is so popular…

B<To be continued…>

=head2 L<Module::Build>

B<To be continued…>

=head2 L<Module::Install>

B<To be continued…>

=head2 L<Zilla::Dist>

B<To be continued…>

=head2 L<Distar>

B<To be continued…>

=head1 EXTERNAL FILES

How to do this, but have your C/C++ in external files…

=head1 EXTERNAL LIBRARIES

How to write modules that bind exteral libraries (like C<libyaml>)…

=head1 INLINE::CPP SPECIFICS

Things that change when you use C<C++>…

=head1 USING LANGUAGES OTHER THAN C<C> AND C<C++>

It I<may> be possible (though highly experimental) to use other Inline
Language Support Modules (ILSMs), like Java or Python. This section will talk
about that…

=head1 DOCUMENT STATUS

This document reflects the current state of C<Inline::Module>. At this time,
it is brand new, and thus many sections can't be written yet. This will change
soon, and this document will be kept up to date with all the changes.

=head1 AUTHORS

=over

=item * Ingy döt Net <ingy@cpan.org>

=item * David Oswald <davido@cpan.org>

=back

=head1 COPYRIGHT

Copyright 2014. Ingy döt Net.

=cut
