MakeMaker fun

pemungkah on 2006-01-26T19:45:26

Here at Yahoo! we have a very cool install system, yinst; handwaving all the details, it makes it really easy to manage a zillion servers and development machines.

To use it properly, you need to build packages according to its scheme, which doesn't match a standard CPAN distribution. I found myself repeatedly building the config files for the build, doing the build, transferring to our repository, and yesterday the idea hit me that I shouldn't be doing this; the build process should.

A quick look over the ExtUtils::MakeMaker docs showed me that it was actually trivial to add a section to the Makefile.PL to put my special build targets into the Makefile.

sub MY::postamble {
  return <<'MAKE_FRAG';
yman: *.3
        cd build && pod2man ../
> "../man/man3/
.3"

yinst: *.yicf cd build && yinst_create -t release *.yicf

ydist: yman yinst *.tgz cd build && dist_install *.tgz

MAKE_FRAG }


So now the Makefile has my targets in it. "Wait, wait," I hear you say. "What's all that stuff in the angle brackets?" That stuff is part 2 of my plan. In addition to the MakeMaker change, I put together a Module::Starter::Yahoo module that builds a base distribution modelled on the Module::Starter::PBP one, but with the added build directory and some extra mojo to build the Yahoo! build files.

So now I can do this to start up a new module:
module-starter --module=My::New::Module
And when my module's ready to distribute, I do this:
make
make test
make ydist
and poof, my module is built, tested, and distributed in proper format. And of course, if it's CPAN-able, I can just do a make dist instead and then upload to CPAN.

Since I based it on Module::Starter::PBP, I could also use the Perl -MModule::Starter::Yahoo=setup business to get this installed as my base Module::Starter config.

I did find that Module::Starter::PBP wasn't well set up to be subclassed, which meant I had to cut and paste the create_distro method into my code and modify it (it uses hard-coded path components in its File::Spec calls), but not a big deal.

Also, the templating philosohy used in this module is slanted toward "one module, one file" because it's used to build .pm and .t files. I needed to have all of the modules in the .yicf file, so a little fiddling about was necessary there as well. All in all, though, I'm quite happy with the time spent to save time later.

I still have to edit the prereqs into the .yicf file; possibly I should expand the make yinst target to parse Makefile.PL and pull the prereqs out automatically.