In another edition of "I cut and paste from my email", I was responding to a user who doesn't understand what the problem is with using Makefiles to generate Perl modules.
Well, he asked...
> I could never follow the arguments against Makefiles or Makefile generators.
Fortunately I wrote a talk alllll about it called
MakeMaker Is DOOMED!
The make dependency is only part of the problem. There's a small mountain of compatibility issues (which make dialect? which shell? what tools are available? are they GNU or BSD or some broken 3rd party thing? did you know that according to POSIX "cp -r" is deprecated?! or that it considers tar a legacy tool and we should all use something called pax?) in which you wind up rewriting a lot of things in Perl anyway... painfully squeezed through a shell one-liner like dough through a pasta maker.
A shell that often can only safely handle 1024 characters (some versions of Windows, old Unixen, VMS only gives us 255)... oh, and you don't really know how long that command might wind up being because it contains make variables which can change at runtime so you just sort of have to guess and hope nobody uses too many modules or something.
And god forbid you have a filename with a space or special character in it. Now you need to escape everything... but you don't know how a variable is going to be used. Maybe it'll be used by the shell...
Maybe it'll already be quoted.
$(PERL) -e 'print $(VARIABLE)'
I'm sorry, I got the wrong quoting. Single quotes don't work on most Windows makes so I have to double quote them.
$(PERL) -e "print $(VARIABLE)"
But double quotes expand variables on Unix, and I don't know what's inside $(VARIABLE). What a conundrum! Now I need to write a portable method to write portable one-liners so I can put portable Perl code in my very unportable Makefile.
And what's the odds a module author is going to consider any of that when they extend MakeMaker?
Even if you wrote your own make-like build tool that solved all the compatibility problems and everyone magically had installed you'd still be up shit creek. You're taking a dynamic situation with lots of state and turning it into a bunch of static one liners with no state. Its like writing down the instructions about how to build a custom tailored car for an idiot child to do. You wind up saying "fuck it, we're not even going to try doing that".
See this recent perfectly sensible ticket I had to reject for a concrete example of something which should be easy but is almost impossible in MakeMaker.
Finally, to customize how their modules are built you're asking Perl programmers to write make (through the funhouse mirror of MakeMaker), something they're totally unfamiliar with. The days of Perl programmers being old C programmers is long gone. Any alternative build system has the same problem except NOBODY will know it. Perl programmers know how to write Perl.
Aren't you glad you asked?
There is one thing MakeMaker has over Module::Build. You can skim the Makefile to figure out what its going to do (except for all the logic that went into generating the Makefile in the first place). This makes it more visible to those who know make, for everyone else its just more magical gibberish. Module::Build is more visible to those who know Perl and know to look in Module::Build::Base. It would be nice of MB had an equivalent to "make -d" to report what's going on, what actions are being called and what dependencies are being resolved.