Alien-V8

 view release on metacpan or  search on metacpan

inc/inc_Module-Build/Module/Build/Cookbook.pm  view on Meta::CPAN

New versions of CPAN.pm understand how to use a F<Build.PL> script,
but old versions don't.  If authors want to help users who have old
versions, some form of F<Makefile.PL> should be supplied.  The easiest
way to accomplish this is to use the C<create_makefile_pl> parameter to
C<< Module::Build->new() >> in the C<Build.PL> script, which can
create various flavors of F<Makefile.PL> during the C<dist> action.

As a best practice, we recommend using the "traditional" style of
F<Makefile.PL> unless your distribution has needs that can't be
accomplished that way.

The C<Module::Build::Compat> module, which is part of
C<Module::Build>'s distribution, is responsible for creating these
F<Makefile.PL>s.  Please see L<Module::Build::Compat> for the details.


=head2 Changing the order of the build process

The C<build_elements> property specifies the steps C<Module::Build>
will take when building a distribution.  To change the build order,
change the order of the entries in that property:

  # Process pod files first
  my @e = @{$build->build_elements};
  my ($i) = grep {$e[$_] eq 'pod'} 0..$#e;
  unshift @e, splice @e, $i, 1;

Currently, C<build_elements> has the following default value:

  [qw( PL support pm xs pod script )]

Do take care when altering this property, since there may be
non-obvious (and non-documented!) ordering dependencies in the
C<Module::Build> code.


=head2 Adding new file types to the build process

Sometimes you might have extra types of files that you want to install
alongside the standard types like F<.pm> and F<.pod> files.  For
instance, you might have a F<Bar.dat> file containing some data
related to the C<Foo::Bar> module and you'd like for it to end up as
F<Foo/Bar.dat> somewhere in perl's C<@INC> path so C<Foo::Bar> can
access it easily at runtime.  The following code from a sample
C<Build.PL> file demonstrates how to accomplish this:

  use Module::Build;
  my $build = Module::Build->new
    (
     module_name => 'Foo::Bar',
     ...other stuff here...
    );
  $build->add_build_element('dat');
  $build->create_build_script;

This will find all F<.dat> files in the F<lib/> directory, copy them
to the F<blib/lib/> directory during the C<build> action, and install
them during the C<install> action.

If your extra files aren't located in the C<lib/> directory in your
distribution, you can explicitly say where they are, just as you'd do
with F<.pm> or F<.pod> files:

  use Module::Build;
  my $build = new Module::Build
    (
     module_name => 'Foo::Bar',
     dat_files => {'some/dir/Bar.dat' => 'lib/Foo/Bar.dat'},
     ...other stuff here...
    );
  $build->add_build_element('dat');
  $build->create_build_script;

If your extra files actually need to be created on the user's machine,
or if they need some other kind of special processing, you'll probably
want to subclass C<Module::Build> and create a special method to
process them, named C<process_${kind}_files()>:

  use Module::Build;
  my $class = Module::Build->subclass(code => <<'EOF');
    sub process_dat_files {
      my $self = shift;
      ... locate and process *.dat files,
      ... and create something in blib/lib/
    }
  EOF
  my $build = $class->new
    (
     module_name => 'Foo::Bar',
     ...other stuff here...
    );
  $build->add_build_element('dat');
  $build->create_build_script;

If your extra files don't go in F<lib/> but in some other place, see
L<"Adding new elements to the install process"> for how to actually
get them installed.

Please note that these examples use some capabilities of Module::Build
that first appeared in version 0.26.  Before that it could
still be done, but the simple cases took a bit more work.


=head2 Adding new elements to the install process

By default, Module::Build creates seven subdirectories of the F<blib>
directory during the build process: F<lib>, F<arch>, F<bin>,
F<script>, F<bindoc>, F<libdoc>, and F<html> (some of these may be
missing or empty if there's nothing to go in them).  Anything copied
to these directories during the build will eventually be installed
during the C<install> action (see L<Module::Build/"INSTALL PATHS">.

If you need to create a new custom type of installable element, e.g. C<conf>,
then you need to tell Module::Build where things in F<blib/conf/>
should be installed.  To do this, use the C<install_path> parameter to
the C<new()> method:

  my $build = Module::Build->new
    (
     ...other stuff here...
     install_path => { conf => $installation_path }
    );

Or you can call the C<install_path()> method later:

  $build->install_path(conf => $installation_path);

The user may also specify the path on the command line:

  perl Build.PL --install_path conf=/foo/path/etc

The important part, though, is that I<somehow> the install path needs
to be set, or else nothing in the F<blib/conf/> directory will get
installed, and a runtime error during the C<install> action will
result.

See also L<"Adding new file types to the build process"> for how to
create the stuff in F<blib/conf/> in the first place.


=head1 EXAMPLES ON CPAN

Several distributions on CPAN are making good use of various features
of Module::Build.  They can serve as real-world examples for others.


=head2 SVN-Notify-Mirror

L<http://search.cpan.org/~jpeacock/SVN-Notify-Mirror/>

John Peacock, author of the C<SVN-Notify-Mirror> distribution, says:

=over 4

=item 1. Using C<auto_features>, I check to see whether two optional
modules are available - SVN::Notify::Config and Net::SSH;

=item 2. If the S::N::Config module is loaded, I automatically
generate test files for it during Build (using the C<PL_files>
property).

=item 3. If the C<ssh_feature> is available, I ask if the user wishes
to perform the ssh tests (since it requires a little preliminary
setup);

=item 4. Only if the user has C<ssh_feature> and answers yes to the
testing, do I generate a test file.

I'm sure I could not have handled this complexity with EU::MM, but it
was very easy to do with M::B.

=back


=head2 Modifying an action

Sometimes you might need an to have an action, say C<./Build install>,
do something unusual.  For instance, you might need to change the
ownership of a file or do something else peculiar to your application.

You can subclass C<Module::Build> on the fly using the C<subclass()>
method and override the methods that perform the actions.  You may
need to read through C<Module::Build::Authoring> and
C<Module::Build::API> to find the methods you want to override.  All
"action" methods are implemented by a method called "ACTION_" followed
by the action's name, so here's an example of how it would work for
the C<install> action:

  # Build.PL
  use Module::Build;
  my $class = Module::Build->subclass(
      class => "Module::Build::Custom",
      code => <<'SUBCLASS' );

  sub ACTION_install {
      my $self = shift;
      # YOUR CODE HERE
      $self->SUPER::ACTION_install;
  }
  SUBCLASS

  $class->new(
      module_name => 'Your::Module',
      # rest of the usual Module::Build parameters
  )->create_build_script;


=head2 Adding an action

You can add a new C<./Build> action simply by writing the method for
it in your subclass.  Use C<depends_on> to declare that another action
must have been run before your action.

For example, let's say you wanted to be able to write C<./Build
commit> to test your code and commit it to Subversion.

  # Build.PL
  use Module::Build;
  my $class = Module::Build->subclass(
      class => "Module::Build::Custom",
      code => <<'SUBCLASS' );

  sub ACTION_commit {
      my $self = shift;

      $self->depends_on("test");
      $self->do_system(qw(svn commit));
  }
  SUBCLASS


=head2 Bundling Module::Build

Note: This section probably needs an update as the technology improves
(see contrib/bundle.pl in the distribution).

Suppose you want to use some new-ish features of Module::Build,
e.g. newer than the version of Module::Build your users are likely to
already have installed on their systems.  The first thing you should
do is set C<configure_requires> to your minimum version of
Module::Build.  See L<Module::Build::Authoring>.

But not every build system honors C<configure_requires> yet.  Here's
how you can ship a copy of Module::Build, but still use a newer
installed version to take advantage of any bug fixes and upgrades.

First, install Module::Build into F<Your-Project/inc/Module-Build>.
CPAN will not index anything in the F<inc> directory so this copy will
not show up in CPAN searches.

    cd Module-Build
    perl Build.PL --install_base /path/to/Your-Project/inc/Module-Build
    ./Build test
    ./Build install

You should now have all the Module::Build .pm files in
F<Your-Project/inc/Module-Build/lib/perl5>.

Next, add this to the top of your F<Build.PL>.

    my $Bundled_MB = 0.30;  # or whatever version it was.

    # Find out what version of Module::Build is installed or fail quietly.
    # This should be cross-platform.
    my $Installed_MB =
        `$^X -e "eval q{require Module::Build; print Module::Build->VERSION} or exit 1";

    # some operating systems put a newline at the end of every print.
    chomp $Installed_MB;

    $Installed_MB = 0 if $?;

    # Use our bundled copy of Module::Build if it's newer than the installed.
    unshift @INC, "inc/Module-Build/lib/perl5" if $Bundled_MB > $Installed_MB;



( run in 0.308 second using v1.01-cache-2.11-cpan-483215c6ad5 )