Which framework should I use to write modules? [closed]

What's the best framework for writing modules -- ExtUtils::MakeMaker (h2xs) or Module::Build?


Solution 1:

NOTE This advice is out of date. Module::Build has been removed from the Perl core but lives on as a CPAN module. The pros and cons still stand, and my opinions about MakeMaker still stand.


As the former maintainer of ExtUtils::MakeMaker, I like to recommend Module::Build because MakeMaker is a horror show. Module::Build is so much better put together. But those aren't your concerns and I'll present my "least hassle for you" answer.

Executive Summary:

Because Module::Build support is not 100% in place through all of Perl, start with MakeMaker. If you want to do any customization at all, switch to Module::Build. Since their basic layout, options and interface are almost identical this will be painless. As seductive as it looks, avoid Module::Install.

Fortunately, Module::Build can emulate MakeMaker which helps some, but doesn't help if you're going to do any customization. See Module::Build::Compat.

For CPAN releases using Module::Build is fine. There's enough Module::Build stuff on CPAN now that everyone's dealt with getting it bootstrapped already.

Finally, the new configure_requires option lets CPAN shells know to install Module::Build before they can start building the module. Unfortunately only the latest CPAN shells know about configure_requires.

Oh, whatever you do don't use h2xs (unless you're writing XS code... and even then think about it).

MakeMaker Pros:

  • Comes with Perl and used by the Perl core (therefore it is actively maintained and will remain so forever)
  • Everything knows what to do with a Makefile.PL.
  • Most module authoring documentation will cover MakeMaker.
  • Uses make (those who know make can debug and patch the build process)

MakeMaker Cons:

  • Requires make (think Windows)
  • Difficult to customize
  • Even harder to customize and make cross platform
  • Difficult to debug when something goes wrong (unless you understand make)

Module::Build Pros:

  • Easier to customize/subclass
  • Pure Perl
  • Easier to debug (it's Perl)
  • Can emulate MakeMaker in several ways
  • The CPAN shell will install Module::Build for you

Module::Build Cons:

  • The Module::Build maintainers (and indeed all of the Perl Toolchain Gang) hate it
  • Older versions of CPAN clients (including CPANPLUS) don't know anything about Module::Build.

Module::Install Pros:

  • Slick interface
  • Bundles itself, you have a known version
  • Everything knows how to deal with a Makefile.PL

Module::Install Cons:

  • Requires make
  • Always uses bundled version, vulnerable to external breakage
  • Difficult to customize outside its interface
  • Mucks with the guts of MakeMaker so a new MakeMaker release will eventually break it.
  • Does not know how to generate a META file using the v2 meta-spec (increasingly a problem with newer tools)

Solution 2:

There are two questions here.

First, never use h2xs. It's old outdated nastiness, though I suppose if you're actually trying to turn a header file into XS code, it might be useful (never done that myself).

2011 update: I strongly recommend taking a look at Dist::Zilla, especially if you think you'll be maintaining more than one module.

For creating a new module, use Module::Starter. It works great, and has some nice plugins for customizing the output.

Second, you're asking what build system you should use. The three contenders are ExtUtils::MakeMaker (EUMM), Module::Build (MB), and Module::Install (MI).

EUMM is a horrid nasty piece of work, but it works, and if you're not customizing your build process at all, works just fine.

MB is the new kid, and it has its detractors. It's big plus is that if you want to heavily customize your install and build process, it's quite possible to do this sanely (and in a cross-platform manner) using MB. It's really not possible using EUMM.

Finally, MI is basically a declarative wrapper on top of EUMM. It also packages itself along with your distro, in an attempt to work around problems with users trying to install modules with old toolchain modules. The downside of the "package self" trick is that if there's a bug in MI itself, you have to re-release all your modules just to fix it.

As far as customization goes, there are some plugins for MI, but if you want to go beyond them you'll be back at the problem of dealing with Makefiles and build tools across a dozen+ platforms, so it really isn't going to help you too much in that realm.

Solution 3:

I just uploaded Distribution::Cooker to CPAN. It's what I use to make new distributions. The nice thing about it is that your distributions can be whatever you like: you're just cooking some templates. I don't care if anyone uses it. For me it's simple, low tech, and doesn't cause extra problems.

You might start with something like Module::Starter to make your starter templates then add your own boilerplate and favorite way of doing things. You choose not only whatever you want in each file, but which files show up in the distro. As you figure out how you like to do things, you simply update your own templates.

As for Makemaker and Module::Build, the future is Module::Build. It's only us old guys using Makemaker anymore. :) There are ways to use both (or pretend to use both) at the same time. Look at the Module::Build, Module::Build::Compat, and Module::Install docs. Module::Build was kicked out of Perl's Standard Library and it's future is uncertain. It's back to Makemaker as a build system.

Although this is a bit of a cop-out answer, try using each just to get a little experience with each.

Solution 4:

You also might want to look at Dist-Zilla which is a new author-only tool to create distributions. Because it just helps build the distribution, it doesn't ship with your code or do any installation, it can do a lot of powerful stuff.