perlquestion
ELISHEVA
<p>CPAN has two installers, the more "modern" <c>Build.PL</c> backed by [mod://Module::Build] and the "traditional" <c>Makefile.PL</c> backed by [mod://ExtUtils::MakeMaker] and [mod://ExtUtils::Command::MM]. The convention for CPAN modules is to ship a package that supports both the old and the new installers.</p>
<p>The problem I'm running into is this: it is impossible to honor the conventions of both the older and the newer installer at once. When you have libraries that are used by the build/test process but not part of the runtime code, the newer installer (Module::Build) expects you to put them in a subdirectory of the project root, preferably named <c>inc</c>. The older build process expects you to put everything in the project root. This is hardcoded into the software and cannot be changed.</p>
<p>The newer one is more flexible and can accommodate the older conventions, so if I want to support both tools using their native build command processor, I have to go with the older conventions. I like the newer conventions. They seem cleaner and facilitate automation.</p>
<p>The older conventions make automating and customizing the packaging process much more complex. Instead of being able to say "everything in inc is mine", any automation software I write has to scan the root and decide what is mine, and what is generated by the build process. That means a fragile hard coded list of what other products I don't control are liable to put in root or else an easy to forget to maintain list of what I put into root. But even if it weren't fragile, any automation that has to dance around exclusion lists like that is more time consuming to write.</p>
<p>There is a third option suggested in the cb last night: place a <c>use lib 'inc';</c> statement in any file that needs to call support files. If I did that I could do things the [mod://Module::Build] way but still use [mod://ExtUtils::Command::MM]. It is a tried and true method and no less than Michael Schwern uses it. (Note: he's the author of the older installer).</p>
<p>I'm probably sounding like Sam in Green Eggs and Ham right now, but I don't like that idea either. First, it means that I have to go into every file I want to ship and edit it to have that line.(Source filters are out - I don't trust them). Secondly, these support libraries are used in a lot of different projects - sometimes at runtime and sometimes at build/configure. If I have any concerns about the current directory of the caller, I also need to add [mod://Find::Bin] which doesn't work under mod_perl. Finally, as a general rule, I don't like to manipulate <c>@INC</c> in .pm files. That job should be left to calling scripts and configuration files. Separation of concerns and all that. It marries assumptions about file locations with source code that could be used in any number of projects and in any possible role (runtime or support). Also any configuration that requires going into each and every file is bound to be more time consuming than a configuration that doesn't.</p>
<p>I suppose you could say, well, what's it to you: how many files are we talking about? Why do you even need automation? To which I'd counter, does it matter? The more time I spend hand-crafting each project, the fewer projects I can manage at one time. The answers to the questions are interdependent. Philosophically, it bothers me as well: this smells of building to the tool. My TMTOWTDI sense doesn't like it very much at all. Green eggs at least tasted good in the end. This doesn't.</p>
<p>This leaves me with two options: (a) bite the bullet and accept the older conventions. (b) take advantage of a feature of [mod://Module::Build] that generates a traditional Makefile.PL with a twist. Its build targets simply pass commands onto [mod://Module::Build] rather than the [mod://ExtUtils::Command::MM] module used by the older build process.</p>
<p>The only downside I can see to option B is that those using very old legacy perl interpreters might not be able to install my CPAN modules (Module::Build would then become a prereq). [mod://Module::Build] joined the Perl core with release 5.9 started in October 2003. It became part of stable 5.10 in Dec, 2007, over four years ago.</p>
<p>But is four years old, really all that old? On the timescale of new software fads and mobile phone tradeins, four years is ancient history. In the time scale of much more conservative back-end processing - the place where Perl thrives - it is not that old at all.</p>
<p>I don't know if the people testing my CPAN software are in any way representative, but only 3% of testers were even trying to run the older installer. 97% were using [mod://Module::Build]. Is it really worth marrying my code to something I consider ugly and hard to maintain and anti-automation just to satisfy an increasingly legacy need? What do you think?</p>
<p><b>Update 1:</b>[Eliya] suggested a possible resolution to the differing approaches used by [mod://ExtUtils::MakeMaker] and [mod://Module::Build]. Using <c>post_initialize</c> you can add directories to <c>PERL5LIB</c> and get extra paths into <c>@INC</c> that way. With the help of [mod://File::Spec] and [mod://Config] this can be done in a portable way. No conflict, no need for option B below. Yeah! - see [id://888807]</p>
<p><b>Update 2:</b> An anonymous monk reminds me that the portability questions aren't all answered - see [id://888844]. Also moved the updates to the bottom because there still isn't a conclusive answer. At present the options are between Option B above and [eliya]'s solution below.</p>