develooper Front page | perl.perl5.porters | Postings from January 2001

How to patch ExtUtils::MakeMaker?

Thread Next
From:
Raphael Manfredi
Date:
January 3, 2001 08:05
Subject:
How to patch ExtUtils::MakeMaker?
Message ID:
12706.978537823@nice.ram.loc
I'm preparing a patch for MakeMaker, because I need to extend pm_to_blib()
to allow on-the-fly filtering of .pm files, something needed for the
Devel::Datum module, and all the modules pending submission that use this
module.

I had retrieved the latest version from CPAN, even though the module is
a standard one, and then I worked on it and patched it (my patch is appended
here).

However, I've been extremely SURPRISED to see that the latest version of
the module on CPAN is NOT the one included in Perl.  When I installed my
patched version (5.41), WriteMakefile complained that 'PL_FILES' was not
a known parameter name!  Because the version included with 5.005_03 is
5.43something....

And of course, my patch does not apply nicely via "patch" on the versions
contained in the distributions, although it's trivial to apply it by hand.

My questions are therefore:

* Against what do I need to prepare the patch?
* Is it possible to retrofit this into the current stable version?
* Shouldn't the version on CPAN be removed in MakeMaker is to be packaged
  within perl, and only there?

The following new (yet unreleased) modules that rely on this MakeMaker
feature (because they use Devel::Datum, and therefore require this filtering
phase) are:

    Devel::Datum
    Net::MsgLink
    Pod::PP
    Getargs::Long
    VDBM
    CGI::MxScreen

I cannot release any of them without this kind of on-the-fly filtering.

Naturally, the scheme implemented by the patch below is only the framework.
One then needs to manually activate it, by defining a MY::pm_to_blib to
patch the call and add a third argument, for instance:

        package MY;
        sub pm_to_blib {
            my $output = shift->SUPER::pm_to_blib(@_);
            $output =~ s/(\)")$/,'\$(DATUM_STRIP_FILTER)'$1/m;
            $output;
        }

Seemed generic enough to warrant inclusion in MakeMaker anyway.

Raphael

Only in MakeMaker-5.41.new: Makefile
Only in MakeMaker-5.41.new: blib
diff -ru MakeMaker-5.41/lib/ExtUtils/Install.pm MakeMaker-5.41.new/lib/ExtUtils/Install.pm
--- MakeMaker-5.41/lib/ExtUtils/Install.pm	Sat Jun 28 17:16:50 1997
+++ MakeMaker-5.41.new/lib/ExtUtils/Install.pm	Wed Jan  3 15:55:57 2001
@@ -225,8 +225,22 @@
     }
 }
 
+sub run_filter {
+    my ($cmd, $src, $dest) = @_;
+    local *SRC, *CMD;
+    open(CMD, "|$cmd >$dest") || die "Cannot fork: $!";
+    open(SRC, $src)           || die "Cannot open $src: $!";
+    my $buf;
+    my $sz = 1024;
+    while (my $len = sysread(SRC, $buf, $sz)) {
+	syswrite(CMD, $buf, $len);
+    }
+    close SRC;
+    close CMD or die "Filter command '$cmd' failed for $src";
+}
+
 sub pm_to_blib {
-    my($fromto,$autodir) = @_;
+    my($fromto,$autodir,$pm_filter) = @_;
 
     use File::Basename qw(dirname);
     use File::Copy qw(copy);
@@ -249,23 +263,36 @@
     my $umask = umask 0022 unless $Is_VMS;
     mkpath($autodir,0,0755);
     foreach (keys %$fromto) {
-	next if -f $fromto->{$_} && -M $fromto->{$_} < -M $_;
-	unless (my_cmp($_,$fromto->{$_})){
-	    print "Skip $fromto->{$_} (unchanged)\n";
+	my $dest = $fromto->{$_};
+	next if -f $dest && -M $dest < -M $_;
+
+	# When a pm_filter is defined, we need to pre-process the source first
+	# to determine whether it has changed or not.  Therefore, only perform
+	# the comparison check when there's no filter to be ran.
+
+	my $need_filtering = defined $pm_filter && length $pm_filter && /\.pm$/;
+
+	if (!$need_filtering && 0 == my_cmp($_,$dest)) {
+	    print "Skip $dest (unchanged)\n";
 	    next;
 	}
-	if (-f $fromto->{$_}){
-	    forceunlink($fromto->{$_});
+	if (-f $dest){
+	    forceunlink($dest);
+	} else {
+	    mkpath(dirname($dest),0,0755);
+	}
+	if ($need_filtering) {
+	    run_filter($pm_filter, $_, $dest);
+	    print "$pm_filter <$_ >$dest\n";
 	} else {
-	    mkpath(dirname($fromto->{$_}),0,0755);
+	    copy($_,$dest);
+	    print "cp $_ $dest\n";
 	}
-	copy($_,$fromto->{$_});
 	my($mode,$atime,$mtime) = (stat)[2,8,9];
-	utime($atime,$mtime+$Is_VMS,$fromto->{$_});
-	chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$fromto->{$_});
-	print "cp $_ $fromto->{$_}\n";
+	utime($atime,$mtime+$Is_VMS,$dest);
+	chmod(0444 | ( $mode & 0111 ? 0111 : 0 ),$dest);
 	next unless /\.pm$/;
-	autosplit($fromto->{$_},$autodir);
+	autosplit($dest,$autodir);
     }
     umask $umask unless $Is_VMS;
 }
@@ -340,6 +367,8 @@
 pm_to_blib() takes a hashref as the first argument and copies all keys
 of the hash to the corresponding values efficiently. Filenames with
 the extension pm are autosplit. Second argument is the autosplit
-directory.
+directory.  If third argument is not empty, it is taken as a filter command
+to be ran on each .pm file, the output of the command being what is finally
+copied, and the source for auto-splitting.
 
 =cut
diff -ru MakeMaker-5.41/lib/ExtUtils/MakeMaker.pm MakeMaker-5.41.new/lib/ExtUtils/MakeMaker.pm
--- MakeMaker-5.41/lib/ExtUtils/MakeMaker.pm	Sat Jun 28 17:25:49 1997
+++ MakeMaker-5.41.new/lib/ExtUtils/MakeMaker.pm	Wed Jan  3 15:46:20 2001
@@ -286,7 +286,7 @@
     push @Overridable, qw[
 
  dir_target libscan makeaperl needs_linking subdir_x test_via_harness
- test_via_script
+ test_via_script pm_to_blib
 
 			 ];
 
Only in MakeMaker-5.41.new: pm_to_blib


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About