Sign In/My Account | View Cart  
advertisement


Listen Print

Module::Build
by Dave Rolsky | Pages: 1, 2, 3

Consider what happens if we know that we need some piece of functionality first present in DBD::mysql 2.1013. But perhaps a release after this, 2.1014, introduced a new bug that breaks our application. If this bug is fixed in version 2.1015, we could simply require version 2.1015, but this is not ideal. There's no reason to force someone who already has 2.1013 to upgrade because of a bug in a version they don't have.

Fortunately, Module::Build provides a more flexible version specification option that handles exactly this situation, so we can write:

  Module::Build->new
      ( module_name => 'My::Module',
        license => 'perl',
        requires => { 'CGI' => 0,
                      'DBD::mysql' => '>= 2.1013, != 2.1014',
                    },
      )->create_build_script;

This says that we need a version greater than 2.1013 that is not version 2.1014. Users who have version 2.1013 or version 2.1015 or greater are not forced to upgrade, but anyone with 2.1014 will be.

If we knew that version 3.0 didn't work with your module, we could change our specification:

  Module::Build->new
      ( module_name => 'My::Module',
        license => 'perl',
        requires => { 'CGI' => 0,
                      'DBD::mysql' => '>= 2.1013, != 2.1014, < 3.0',
                    },
      )->create_build_script;

If the user does have version 3.0 or greater installed, it will at least let them know that it won't work with our module. Unfortunately, the only possible way to use our module at this point is for the end user to manually downgrade their installation of DBD::mysql, since Perl does not allow multiple versions of a module to co-exist peacefully. Still, this is better than letting the module be installed, only to fail at runtime when it tries to use an outdated API for DBD::mysql.

There are also other options related to prerequisites, such as "recommends" and "build_requires", which can be helpful for prerequisites that are required to build the module but don't need to be present after installation. There is also a "conflicts" option which can be used to warn a user about potential conflicts between the module they are installing and one they already have.

Action!

As of release 1.15, Module::Build implements the following actions, most of which are based on existing ExtUtils::MakeMaker functionality:

  • build

    This is the default action, and is what happens if you run ./Build without any additional arguments. It is responsible for creating the blib/ directory and copying files into it, as well as compiling XS and C files. If you have any scripts like lib/My/Module.pm.PL, these are also run during this action.

  • test, testdb

    Runs the module's tests using the Test::Harness module. The "testdb" action can be used to run the tests under Perl's debugger. Equivalently, a "debugger" parameter can be passed to the "test" action to get the same effect.

  • clean, realclean

    Both actions delete any files created by the "build" action. The "realclean" action also deletes the existing Build script.

  • diff

    This action is used to compare the files about to be installed with any corresponding files that already exist. This feature is unique to Module::Build.

  • install

    Installs the module files. As of version 0.15, this doesn't yet create or install any man pages.

  • fakeinstall

    Tells you what the "install" would do.

  • dist

    Creates a gzip'd tarball of your distribution.

  • manifest
    Creates a MANIFEST file for your distribution.
  • distcheck

    Tells you what files are in the build directory but not in the MANIFEST file, and vice versa.

  • skipcheck

    Tells you what files will not be added to the MANIFEST by the "manifest" action, based on the contents of your MANIFEST.SKIP file.

  • distclean

    This is a shortcut for "realclean" followed by "distcheck".

  • distdir

    Creates a directory based on your distribution name and version, and then copies all the files listed in MANIFEST to that directory. This directory is what people will see when they download and unpack your distribution.

    Module::Build also creates a file called META.yaml which contains meta-data about your distribution. In the future, it may be possible to use a command line tool (written in Perl, of course) to read this file and use its contents to install your distribution, without running the Build.PL script. It also makes the meta-data more readily available to tools like search.cpan.org or the CPAN shell.

  • disttest

    This performs the "distdir" action, switches to the newly created directory, and then runs perl Build.PL, ./Build, and ./Build test. This lets you make sure that your distribution is actually installable.

  • help

    Tells you what actions are available. If additional actions are implemented in a distribution, then these are listed here.

Any of these options can be overridden through straightforward subclassing, so our HTML::Mason example from earlier in this article might be written something like this:

  package MyFancyBuilder;
  use base 'Module::Build';
  sub ACTION_test {
      my $self = shift;
      # %MY::APACHE is set in makeconfig.pl.
      $ENV{PORT}             = $MY::APACHE{port}       || 8228;
      $ENV{APACHE_DIR}       = $MY::APACHE{apache_dir} || ";
      $ENV{MASON_VERBOSE}  ||= $self->{properties}{verbose};
      # _is_maintainer_mode would be another method of our subclass
      $ENV{MASON_MAINTAINER} = $self->_is_maintainer_mode();
      return $self->SUPER::ACTION_test(@_);
  }

This version is actually readable, and is unlikely to break regardless of changes in the Module::Build internals. This highlights just how difficult it was to accomplish a simple task using ExtUtils::MakeMaker, and how natural the pure-Perl solution can be.

The Larger Picture and Backwards Compatibility

One difficulty in getting Module::Build into widespread use is the fact that support for ExtUtils::MakeMaker is so tightly integrated into CPAN installers.

While the version of CPAN.pm which ships with 5.8 does not know how to deal with Build.PL, the latest versoin available from CPAN does. It will even install Module::Build for you. As of January 2008, CPANPLUS, another CPAN shell, understands Build.PL but will not install Module::Build for you, but this will be remedied in a future release.

However, old versions of CPAN.pm are still in extremely widespread use, and users won't necessarily upgrade CPAN.pm before attempting to install a distribution that relies on Module::Build.

Pages: 1, 2, 3

Next Pagearrow