Particularly the concept of writing a cross-platform Makefile. Its like cross-platform GUI code, nearly impossible. Here's a little microcosm of my pain.
I want to run a make target in a subdirectory. On Unix that's easy.
cd dir && $(MAKE) target FOO=bar
And that even works on NT. But what about Win9x and nmake (ie. the "free as in beer" Windows native make that most people get)? It doesn't understand &&. Futhermore each line of the shell can effect another. So you have to do this.
cd dir
$(MAKE) target FOO=bar
cd ..
I'll be merciful and skip explaining what dmake brings to the party.
But then there's another make variant, MMS/K for VMS. And with completely alien shell conventions. There its...
set default [.dir]
$(MAKE) target FOO=bar
set default [-]
But that's not quite right. You can't just pass args to make on VMS, oh no. The need special macro magic.
set default [.dir]
$(MAKE) target /macro=(FOO=bar)
set default [-]
And $(MAKE) isn't set. Its $(MMS). Lovely.
MAKE = $(MMS)
set default [.dir]
$(MAKE) target /macro=(FOO=bar)
set default [-]
This difference alone accounts for a huge wad of duplication in MakeMaker. I'm whittling away at it with a cd() method.
my $make_command = $mm->cd($dir, @commands);
Then I can plunk that $make_command into a Makefile and be reasonably sure it'll be the right thing for the current platform. This alone knocked out most of MM_Win95.pm. MM_VMS is proving more tenacious, I haven't decided what to do yet about the /macro= wackiness and other MMS argument passing anomalies. Probably yet another method.
Now before you think "why do you bother with VMS?", let me say that I get more help and patches from vmsperl than I do from Windows users. And despite all its faults I can at least telnet to a VMS machine to test things out, DEC/Compaq/HP helpfully provides several for such purposes (http://www.testdrive.hp.com/). But rjbs is setting up a Windows machine for me to VNC into and I got an offer on Perlmonks for some sort of email-based Windows smoke acount. So hopefully that will make life a little easier.
Re:abstract the abstract
schwern on 2004-12-18T00:36:42
See MM_Any->oneliner(). It makes the job barely tolerable. Here's an example from generating the clean target.
# Equivalent to 'cd $dir && $(TESTF) $(FIRST_MAKEFILE) && $(MAKE) clean'
for my $dir (@{$self->{DIR}}) {
my $subclean = $self->oneliner(sprintf 'CODE', $dir);
chdir '%s'; system '$(MAKE) clean' if -f '$(FIRST_MAKEFILE)';
CODE
$clean.= "\t$subclean\n";
}
But you can't move everything to running individual perl scripts, its too bloody slow. And there's something depressingly Sisyphusian about a Perl module to write a Makefile full of shell scripts which are ultimately Perl one-liners.