Module::Build Double::Plus::Good

For my latest Perl projects I have switched from ExtUtils::MakeMaker with its Makefile.PL to Module::Build.

So far I have been using it quite naively, but this time I had special requirements:

I am packaging a server (TM::IP), so there are not only Perl packages and a client-side script (ts), but also the daemon code and the configuration files:

  • tmipd should eventually go into into /usr/sbin/tmipd
  • The configuration files obviously into /etc/tmipd/. And I have also a daemontool run script to park there.

The Build.PL script

The boilerplate itself is quite standard:

use strict;
use warnings;
use Module::Build;

my $builder = Module::Build->new(
    module_name         => 'TM::IP',
    license             => 'perl',
    dist_author         => 'Robert Barta <....>',
    dist_version_from   => 'lib/TM/',
    build_requires => {
    add_to_cleanup      => [ 'TM-IP-*' ],
    create_makefile_pl => 'traditional',


I still continue to generate the Makefile.PL files.

To cater for the above additional file types (everything else is taken care of by Module::Build), you have to register them with the builder (according to the Cookbook):

$builder->add_build_element ('conf');
$builder->add_build_element ('sbin');

Inside the builder I detailed where each of the files has to go under the locally generated blib directory:

my $builder = Module::Build->new(
    conf_files   => { 'etc/log4perl.conf'   => 'etc/log4perl.conf',
                      'etc/tmipd.conf'      => 'etc/tmipd.conf',
                      'utils/run.supervise' => 'etc/supervise/run',
    sbin_files   => { 'sbin/tmipd' => 'sbin/tmipd' },

To ensure that these eventually end up in their proper file system places, I added another mapping:

install_path => { 'etc'  => '/etc/tmipd',
                  'sbin' => '/usr/sbin' },

To test the setup I used

./Build clean ; perl Build.PL ;  ./Build fakeinstall

Cleaning is good, trust me.

A Plot Twist

My deployment platform is Debian. Fullstop.

Consequently, I am a heavy user of dh-make-perl. That has evolved consistently over the years and makes automated debianization of (private) Perl code manageable.

The usual incantation is:

dh-make-perl --build TM-IP/

after which it will auto-create the debian subdirectory and will then emulate the installation process to learn about the files involved. Then it will run your test suite and only if that succeeds it will build the .deb file.

Being Offline

I was doing all this on the bus, having no Internet connection. That is relevant as dh-make-perl (or one of its packages) is trying to connect to the Debian/Perl ticket system. And will abort after a timeout.

That's annoying. But it can be suppressed by setting in the environment

export NO_NETWORK=1

It is amazing what you learn when reading the code ;-)

Damned Tests

The other annoying things is that you always have to await the end of the test suite. If you do plenty of testing you are punished with waiting for quite some time.

At every run :-/

But the man page of dh-make-perl will tell you that you can turn off testing:

export DEB_BUILD_OPTIONS=nocheck

Phew. Thanks.

Looking The Wrong Way

The last hiccup I had was that dh-make-perl seemed to look at Makefile.PL first. Maybe this is documented somewhere, but I was already in SHM (Sherlock Holmes Mode).

So - for the purpose of debianization - I commented out the


line before re-running dh-make-perl. Make sure that you do not have a loose Makefile.PL lying around.

Posted In


Have you considered Dist::Zilla? Did it fall short? If so, how can it better fit your needs. I'd be really interested to see how well it cooperates with dh-makeperl.

I just switched to Dist::Zilla, and it basically rox my sox. I prefer writing perl and letting the computer handle writing my makefiles.

Andrew Grangaard (not verified) | Tue, 04/06/2010 - 19:19

Re: Dist::Zilla

Have you considered Dist::Zilla? Did it fall short?

Hmm, never heard of it before. But it sure looks interesting.

Will investigate. Thx!

rho | Tue, 04/06/2010 - 20:05

Re: Dist::Zilla

Dist::Zilla is a "distribution compiler". It generates a Makefile.PL or Build.PL for you from a simpler configuration file (and a lot of really nice DWIMmery). Unfortunately, it doesn't (yet) support the kind of custom installation targets you describe.

-- dagolden

dagolden (not verified) | Tue, 04/06/2010 - 22:53