develooper Front page | perl.perl5.porters | Postings from May 2008

Re: [patch@33919] Module build changes for VMS

Thread Previous | Thread Next
From:
Craig A. Berry
Date:
May 25, 2008 16:42
Subject:
Re: [patch@33919] Module build changes for VMS
Message ID:
p06240803c45f9509159b@[172.16.52.1]
At 4:17 PM -0500 5/25/08, John E. Malmberg wrote:
>Please review these patches for improving module build on VMS.  These were being discussed before the 5.10 release, but not included.

Thanks, I'll have a look.  A few initial comments mixed in below.

>
>Also, I left the makefile name as generated by the tests.  Sometimes it was generated as 'Makefile' and sometimes as 'descrip.mms'.
>
>I am thinking that if the makefile is being generated for is_vms_mms(), then the name should be forced to 'descrip.mms' for consistency, as I do not think gnu make can deal with MMS/MMK syntax.
>
>With these patches, all but the ppm.t tests will pass on VMS.
>
>The xs.t test passes, but the extra output is messing up the test analysis, so for now, I have left it being skipped.
>
>The ppm.t test still has the issue where it is creating a tarball that it then can not detar, and I will try to look at that in a little bit.
>
>
>In Module/Build.pm:
>
>   * Add is_vms_mms method to indicate that VMS is using
>     either MMS or MMK for the make program.
>
>In Module/Build/Base.pm :
>
>   * Use is_vms_mms instead of is_vmsish where needed.
>
>   * fileparse can return an empty path on VMS, and
>     splitdir on an empty path.
>
>   * catdir for directories, catfile for files.
>
>   * Add some VMS specific files to be skipped.
>     Probably more need to be added.
>
>
>In Module/Build/Compat.pm:
>
>   * glob() on VMS does not handle tilde expansion.
>
>   Is there a better way of locating the Module::Build
>   class to find the Module::Build->is_vmsish and
>   Module::Build->_detildefy methods.
>
>   * MCR needs to be added as a prefix for running the
>     Perl from MMS/MMK makefiles.
>
>   * Use is_vms_mms to indicate when a makefile for
>     MMS/MMK is being used or created.
>
>   * Build script is named build.com when MMS/MMK is used.
>
>   * Unlink needs to unlink all versions of a file.
>
>   * MMS/MMK does not support .EXPORT target.
>
>In Module/Build/Platform/VMS.pm:
>
>   * Arguments preceded by '/' must not be quoted.
>
>   * When detildifying a path, remove the trailing '/'.
>
>In Module/Build/t/lib/MBTest.pm:
>
>   * VMS does not use $PATH.  Currently there is
>     no practical way to probe to see if a command or
>     program will work.
>
>
>In Module/Build/t/compat.t:
>
>   * Save test if MMS/MMK is being used.
>
>   * Macros need to be passed differently on the
>     MMS/MMK command line.
>
>   * Makefile can also be named descrip.mms for MMS/MMK.
>
>In Module/Build/t/tilde.t:
>
>   * Convert the $home directory to UNIX format.
>
>-John
>Personal Opinion Only
>
>
>--- /rsync_root/perl/lib/Module/Build/base.pm	Thu Oct 25 04:50:40 2007
>+++ lib/Module/Build/base.pm	Sun May 25 00:50:07 2008
>@@ -2304,7 +2304,7 @@
>  
>   foreach my $file (keys %$files) {
>     my $result = $self->copy_if_modified($file, $script_dir, 'flatten') or next;
>-    $self->fix_shebang_line($result) unless $self->is_vmsish;
>+    $self->fix_shebang_line($result) unless $self->is_vms_mms;

So if we're using GNU make rather than MMS or MMK we have a shebang
line in Perl?  Not sure how that's possible.

>     $self->make_executable($result);
>   }
> }
>@@ -2392,7 +2392,7 @@
> 
> sub localize_file_path {
>   my ($self, $path) = @_;
>-  $path =~ s/\.\z// if $self->is_vmsish;
>+  $path =~ s/\.\z// if $self->is_vms_mms;
>   return File::Spec->catfile( split m{/}, $path );
> }
> 
>@@ -2674,10 +2674,15 @@
> 
>     my ($name, $path) = File::Basename::fileparse($pods->{$pod},
>                                                  file_qr('\.(?:pm|plx?|pod)$'));
>+    if ($self->is_vmsish) {
>+      #path can show up empty on VMS.
>+      $path = File::Spec->curdir if ($path eq '');
>+    }
>     my @dirs = File::Spec->splitdir( File::Spec->canonpath( $path ) );
>+   
>     pop( @dirs ) if $dirs[-1] eq File::Spec->curdir;
> 
>-    my $fulldir = File::Spec->catfile($htmldir, @rootdirs, @dirs);
>+    my $fulldir = File::Spec->catdir($htmldir, @rootdirs, @dirs);
>     my $outfile = File::Spec->catfile($fulldir, "${name}.html");
>     my $infile  = File::Spec->abs2rel($pod);
> 
>@@ -2879,7 +2884,7 @@
> 	File::Spec->abs2rel( File::Spec->rel2abs( $file ),
> 			     File::Spec->rel2abs( $dir  ) );
>       my $to_file  =
>-	File::Spec->catdir( $ppm, 'blib',
>+	File::Spec->catfile( $ppm, 'blib',
> 			    exists( $types{$type} ) ? $types{$type} : $type,
> 			    $rel_file );
>       $self->copy_if_modified( from => $file, to => $to_file );
>@@ -3179,10 +3184,18 @@
> \bblibdirs$
> ^MANIFEST\.SKIP$
> 
>+# Avoid VMS specific MakeMaker generated files
>+\bDescript.MMS$
>+\bDESCRIPT.MMS$
>+\bdescript.mms$

It's "descrip" not "descript".

>+
> # Avoid Module::Build generated and utility files.
> \bBuild$
> \bBuild.bat$
> \b_build
>+\bBuild.com$
>+\bBUILD.COM$
>+\bbuild.com$
> 
> # Avoid Devel::Cover generated files
> \bcover_db
>--- /rsync_root/perl/lib/Module/Build/Compat.pm	Thu Oct 25 04:50:40 2007
>+++ lib/Module/Build/Compat.pm	Sat May 24 22:11:04 2008
>@@ -171,7 +171,15 @@
> 		       die "Malformed argument '$arg'");
> 
>     # Do tilde-expansion if it looks like a tilde prefixed path
>-    ( $val ) = glob( $val ) if $val =~ /^~/;
>+    if ($val =~ /^~/) {
>+      my $class = 'Module::Build';
>+      if ($class->is_vmsish) {
>+        # VMS does not glob a ~ yet
>+        ( $val ) = $class->_detildefy($val)
>+      } else {
>+        ( $val ) = glob( $val );
>+      }
>+    }

It may be ok to use _detildefy everywhere -- we'd have to test it on
something non-VMS.  Most likely the following will get you the class,
which is currently just being thrown away:

--- Compat.pm;-0        Thu Oct 25 04:50:40 2007
+++ Compat.pm   Sun May 25 18:23:27 2008
@@ -162,7 +162,7 @@ sub subclass_dir {
 }

 sub makefile_to_build_args {
-  shift;
+  my $self = shift;
   my @out;
   foreach my $arg (@_) {
     next if $arg eq '';
[end]

You could then use $self where you have $class (haven't tested that,
but that's how nearly all these methods work).

> 
>     if (exists $makefile_to_build{$key}) {
>       my $trans = $makefile_to_build{$key};
>@@ -216,10 +224,24 @@
>   my $class = $args{build_class};
> 
>   my $perl = $class->find_perl_interpreter;
>+
>+  # VMS MMS/MMK usually needs to use MCR to run the Perl image
>+  $perl = 'MCR ' . $perl if $class->is_vms_mms;
>+

This doesn't seem necessary to me since it's going to be spawning a
subprocess to run Perl; the subprocess-handling code already prepends
MCR when needed.

>   my $noop = ($class->is_windowsish ? 'rem>nul'  :
>-	      $class->is_vmsish     ? 'Continue' :
>+	      $class->is_vms_mms    ? 'Continue' :
> 	      'true');
>-  my $Build = 'Build --makefile_env_macros 1';
>+
>+  # VMS MMS/MMK has different file type.
>+  my $filetype = $class->is_vms_mms ? '.COM' : '';
>+
>+  my $Build = 'Build' . $filetype . ' --makefile_env_macros 1';
>+
>+  my $unlink_makefile = "unlink -e shift $args{makefile}";
>+
>+  # VMS MMK/MMS has multiple file versions
>+  $unlink_makefile = "\"1 while unlink \'$args{makefile}\'\""
>+      if $class->is_vms_mms;
> 
>   # Start with a couple special actions
>   my $maketext = <<"EOF";
>@@ -227,7 +249,7 @@
> 	$perl $Build
> realclean : force_do_it
> 	$perl $Build realclean
>-	$perl -e unlink -e shift $args{makefile}
>+	$perl -e $unlink_makefile
> 
> force_do_it :
> 	@ $noop
>@@ -241,7 +263,10 @@
> EOF
>   }
>  
>-  $maketext .= "\n.EXPORT : " . join(' ', keys %makefile_to_build) . "\n\n";
>+  # VMS MMS/MMK doe not support .EXPORT
>+
>+  $maketext .= "\n.EXPORT : " . join(' ', keys %makefile_to_build) . "\n\n"
>+     unless $class->is_vms_mms;
>  
>   return $maketext;
> }
>--- /rsync_root/perl/lib/Module/Build/t/compat.t	Thu Feb 21 08:04:41 2008
>+++ lib/Module/Build/t/compat.t	Sun May 25 14:32:41 2008
>@@ -21,6 +21,7 @@
> }
> ok 1, "Loaded";
> 
>+my $vms_mms = ($^O eq 'VMS') && ($Config{make} =~ /MMS|K/i);

Um, anything with a K in it is considered MMK?  I don't think that's
what you wanted.  See

http://perldoc.perl.org/perlrequick.html#Grouping-things-and-hierarchical-matching



> 
> #########################
> 
>@@ -171,11 +172,23 @@
>   like $output, qr/(?:# ok \d+\s+)+/, 'Should be verbose';
> 
>   # Make sure various Makefile arguments are supported
>-  $output = stdout_of( sub { $ran_ok = $mb->do_system(@make, 'test', 'TEST_VERBOSE=0') } );
>+  my $arg = 'TEST_VERBOSE=0';
>+  if ($vms_mms) {
>+    $arg = '/macro=(' . $arg . ')';
>+  }
>+  $output = stdout_of( sub { $ran_ok = $mb->do_system(@make, 'test', $arg) });
>+
>   ok $ran_ok, "make test without verbose ran ok";
>   $output =~ s/^/# /gm;  # Don't confuse our own test output
>+  my $regex2 = '(?:[\d.]+\s*m?s\s*)?(?:# \[[\d:]+\]\s*)?';
>+  my $regex = qr/(?:# .+basic\.+ok\s+$regex2)# All tests /;
>+
>+  # VMS spreads the output over multiple liines.
>+  if ($^O eq 'VMS') {
>+    $regex = qr/(?:# .+basic\.+(?:\s.*)?ok\s+$regex2)# All tests /s;
>+  }
>   like $output,
>-       qr/(?:# .+basic\.+ok\s+(?:[\d.]+\s*m?s\s*)?(?:# \[[\d:]+\]\s*)?)# All tests/,
>+       $regex,
>       'Should be non-verbose';
> 
>   $mb->delete_filetree($libdir);
>@@ -270,13 +283,24 @@
>     $label .= " (postargs: $postargs)";
>   }
>   ok $result, $label;
>-  ok -e 'Makefile', "Makefile exists";
>- 
>+
>+  my $makefile = 'Makefile';
>+  if ($vms_mms) {
>+    # VMS MMS/MMK can have either Makefile or descrip.mms as the created file.
>+    my $make_test = -e $makefile;
>+    unless ($make_test) {
>+      $makefile = 'descrip.mms';
>+      $make_test = -e $makefile;
>+    }
>+    ok $make_test, "$makefile exists - Looking for Makefile or descrip.mms";
>+  } else {
>+      ok -e 'Makefile', "Makefile exists";
>+  }
>   if ($cleanup) {
>     $output = stdout_of( sub {
>       $build->do_system(@make, 'realclean');
>     });
>-    ok ! -e 'Makefile', "Makefile cleaned up";
>+    ok ! -e $makefile, "$makefile cleaned up";
>   }
>   else {
>     pass '(skipping cleanup)'; # keep test count constant
>@@ -287,10 +311,19 @@
>   my %requires = %{ $_[0] };
>   delete $requires{perl}; # until EU::MM supports this
>   SKIP: {
>-    skip 'Makefile not found', 1 unless -e 'Makefile';
>-    my $prereq_pm = find_makefile_prereq_pm();
>+    my $makefile = 'Makefile';
>+    if ($vms_mms) {
>+      # VMS MMS/MMK can have either Makefile or descrip.mms as the created file.
>+      my $make_test = -e $makefile;
>+      unless ($make_test) {
>+        $makefile = 'descrip.mms';
>+        $make_test = -e $makefile;
>+      }
>+    }
>+    skip 'Makefile not found', 1 unless -e $makefile;
>+    my $prereq_pm = find_makefile_prereq_pm($makefile);
>     is_deeply $prereq_pm, \%requires,
>-      "Makefile has correct PREREQ_PM line";
>+      "$makefile has correct PREREQ_PM line";
>   }
> }
> 
>@@ -313,8 +346,9 @@
> # Following subroutine adapted from code in CPAN.pm
> # by Andreas Koenig and A. Speer.
> sub find_makefile_prereq_pm {
>-  my $fh = IO::File->new( 'Makefile', 'r' )
>-    or die "Can't read Makefile: $!";
>+  my $makefile = shift;
>+  my $fh = IO::File->new( $makefile, 'r' )
>+    or die "Can't read $makefile: $!";
>   my $req = {};
>   local($/) = "\n";
>   while (<$fh>) {
>--- /rsync_root/perl/lib/Module/Build/t/lib/MBTest.pm	Fri Oct 26 19:01:41 2007
>+++ lib/Module/Build/t/lib/MBTest.pm	Sat May 24 18:07:44 2008
>@@ -131,6 +131,10 @@
> 
> sub find_in_path {
>   my $thing = shift;
>+
>+  # VMS does not use path, and it is very complex to check to
>+  # see if a command will work before just trying it.
>+  return $thing if ($^O eq 'VMS');
>  
>   my @path = split $Config{path_sep}, $ENV{PATH};
>   my @exe_ext = exe_exts();
>--- /rsync_root/perl/lib/Module/Build.pm	Thu Feb 21 08:04:41 2008
>+++ lib/Module/Build.pm	Sat May 24 18:00:26 2008
>@@ -10,6 +10,7 @@
> use File::Spec ();
> use File::Path ();
> use File::Basename ();
>+use Config;
> 
> use Module::Build::Base;
> 
>@@ -99,6 +100,17 @@
> sub is_vmsish { return ((os_type() || '') eq 'VMS') }
> sub is_windowsish { return ((os_type() || '') eq 'Windows') }
> sub is_unixish { return ((os_type() || '') eq 'Unix') }
>+
>+# VMS has both Unix like make and its Module Management System
>+# or MMS and usually the difference in the desired
>+# behavior for module build is really dependent on which one
>+# is in use.  MMK is a freeware clone of MMS.
>+
>+# TODO: When perl is launched from GNV utilities, it will be
>+#       assuming that a Unix make will be used.
>+#       For now default to what Perl was build with.
>+
>+sub is_vms_mms { return (is_vmsish && ($Config{make} =~ /MMS|K/i)) }

Note regex comment above.

> 
> 1;
> 
>--- /rsync_root/perl/lib/Module/Build/t/tilde.t	Fri Nov 16 17:46:01 2007
>+++ lib/Module/Build/t/tilde.t	Sat Nov  3 01:52:24 2007
>@@ -39,7 +39,12 @@
> 
> SKIP: {
>     my $home = $ENV{HOME} ? $ENV{HOME} : undef;
>-    skip "Needs case and syntax tweaks for VMS", 14 if $^O eq 'VMS';
>+
>+    if ($^O eq 'VMS') {
>+        # Convert the path to UNIX format, trim off the trailing slash
>+        $home = VMS::Filespec::unixify($home);
>+        $home =~ s#/$##;
>+    }
>     unless (defined $home) {
>       my @info = eval { getpwuid $> };
>       skip "No home directory for tilde-expansion tests", 14 if $@;
>@@ -83,12 +88,20 @@
> 
> # Again, with named users
> SKIP: {
>-    skip "Needs case and syntax tweaks for VMS", 1 if $^O eq 'VMS';
>     my @info = eval { getpwuid $> };
>     skip "No home directory for tilde-expansion tests", 1 if $@;
>     my ($me, $home) = @info[0,7];
>+
>+    my $expected = "$home/foo";
>+
>+    if ($^O eq 'VMS') {
>+        # Convert the path to UNIX format and trim off the trailing slash
>+        $home = VMS::Filespec::unixify($home);
>+        $home =~ s#/$##;
>+	$expected = $home . '/../[^/]+' . '/foo';
>+    }
>    
>-    is( run_sample( $p => "~$me/foo")->$p(),  "$home/foo" );
>+    like( run_sample( $p => "~$me/foo")->$p(),  qr($expected)i );
> }
> 
> 
>--- /rsync_root/perl/lib/Module/Build/Platform/VMS.pm	Thu Oct 25 04:50:40 2007
>+++ lib/Module/Build/Platform/VMS.pm	Sun May 25 00:08:06 2008
>@@ -136,7 +136,9 @@
>                    ? 1
>                    : 0;
> 
>-  map { $_ = q(").$_.q(") if !/^\"/ && length($_) > 0 }
>+  # Do not quote qualifiers that begin with '/' or already
>+  # quoted arguments.
>+  map { $_ = q(").$_.q(") if !/^[\"|\/]/ && length($_) > 0 }
>      ($got_arrayref ? @{$args[0]}
>                     : @args
>      );
>@@ -304,6 +306,7 @@
> 
>         # Trivial case of just ~ by it self
>         if ($spec eq '') {
>+            $home =~ s#/$##;
>             return $home;
>         }
> 
>@@ -334,8 +337,8 @@
>             my @backup = File::Spec::Unix->splitdir(File::Spec::Unix->updir);
> 
>             $newdirs = File::Spec::Unix->catdir(@hdirs, @backup, @dirs);
>-
>         }
>+        $newdirs =~ s#/$##;
>        
>         # Now put the two cases back together
>         $arg = File::Spec::Unix->catpath($hvol, $newdirs, $file);


-- 
________________________________________
Craig A. Berry
mailto:craigberry@mac.com

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser

Thread Previous | 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