b56b1b8cf5fd8bc8089cd14fdcaf9cdc6f8d0155
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / MM_VMS.pm
1 #   MM_VMS.pm
2 #   MakeMaker default methods for VMS
3 #   This package is inserted into @ISA of MakeMaker's MM before the
4 #   built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under VMS.
5 #
6 #   Author:  Charles Bailey  bailey@genetics.upenn.edu
7
8 package ExtUtils::MM_VMS;
9 $ExtUtils::MM_VMS::Revision=$ExtUtils::MM_VMS::Revision = '5.39 (31-Jan-1997)';
10 unshift @MM::ISA, 'ExtUtils::MM_VMS';
11
12 use Carp qw( &carp );
13 use Config;
14 require Exporter;
15 use VMS::Filespec;
16 use File::Basename;
17
18 Exporter::import('ExtUtils::MakeMaker', '$Verbose', '&neatvalue');
19
20 =head1 NAME
21
22 ExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
23
24 =head1 SYNOPSIS
25
26  use ExtUtils::MM_VMS; # Done internally by ExtUtils::MakeMaker if needed
27
28 =head1 DESCRIPTION
29
30 See ExtUtils::MM_Unix for a documentation of the methods provided
31 there. This package overrides the implementation of these methods, not
32 the semantics.
33
34 =head2 Methods always loaded
35
36 =item eliminate_macros
37
38 Expands MM[KS]/Make macros in a text string, using the contents of
39 identically named elements of C<%$self>, and returns the result
40 as a file specification in Unix syntax.
41
42 =cut
43
44 sub eliminate_macros {
45     my($self,$path) = @_;
46     unless ($path) {
47         print "eliminate_macros('') = ||\n" if $Verbose >= 3;
48         return '';
49     }
50     my($npath) = unixify($path);
51     my($complex) = 0;
52     my($head,$macro,$tail);
53
54     # perform m##g in scalar context so it acts as an iterator
55     while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#g) { 
56         if ($self->{$2}) {
57             ($head,$macro,$tail) = ($1,$2,$3);
58             if (ref $self->{$macro}) {
59               carp "Can't expand macro containing " . ref $self->{$macro};
60               $npath = "$head\cB$macro\cB$tail";
61               $complex = 1;
62             }
63             else { ($macro = unixify($self->{$macro})) =~ s#/$##; }
64             $npath = "$head$macro$tail";
65         }
66     }
67     if ($complex) { $npath =~ s#\cB(.*?)\cB#\$($1)#g; }
68     print "eliminate_macros($path) = |$npath|\n" if $Verbose >= 3;
69     $npath;
70 }
71
72 =item fixpath
73
74 Catchall routine to clean up problem MM[SK]/Make macros.  Expands macros
75 in any directory specification, in order to avoid juxtaposing two
76 VMS-syntax directories when MM[SK] is run.  Also expands expressions which
77 are all macro, so that we can tell how long the expansion is, and avoid
78 overrunning DCL's command buffer when MM[KS] is running.
79
80 If optional second argument has a TRUE value, then the return string is
81 a VMS-syntax directory specification, otherwise it is a VMS-syntax file
82 specification.
83
84 =cut
85
86 sub fixpath {
87     my($self,$path,$force_path) = @_;
88     unless ($path) {
89         print "eliminate_macros('') = ||\n" if $Verbose >= 3;
90         return '';
91     }
92     my($fixedpath,$prefix,$name);
93
94     if ($path =~ m#^\$\(.+\)$# || $path =~ m#[/:>\]]#) { 
95         if ($force_path or $path =~ /(?:DIR\)|\])$/) {
96             $fixedpath = vmspath($self->eliminate_macros($path));
97         }
98         else {
99             $fixedpath = vmsify($self->eliminate_macros($path));
100         }
101     }
102     elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#)) && $self->{$prefix}) {
103         my($vmspre) = vmspath($self->eliminate_macros("\$($prefix)")) || ''; # is it a dir or just a name?
104         $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
105         $fixedpath = vmspath($fixedpath) if $force_path;
106     }
107     else {
108         $fixedpath = $path;
109         $fixedpath = vmspath($fixedpath) if $force_path;
110     }
111     # Convert names without directory or type to paths
112     if (!$force_path and $fixedpath !~ /[:>(.\]]/) { $fixedpath = vmspath($fixedpath); }
113     # Trim off root dirname if it's had other dirs inserted in front of it.
114     $fixedpath =~ s/\.000000([\]>])/$1/;
115     print "fixpath($path) = |$fixedpath|\n" if $Verbose >= 3;
116     $fixedpath;
117 }
118
119 =item catdir
120
121 Concatenates a list of file specifications, and returns the result as a
122 VMS-syntax directory specification.
123
124 =cut
125
126 sub catdir {
127     my($self,@dirs) = @_;
128     my($dir) = pop @dirs;
129     @dirs = grep($_,@dirs);
130     my($rslt);
131     if (@dirs) {
132       my($path) = (@dirs == 1 ? $dirs[0] : $self->catdir(@dirs));
133       my($spath,$sdir) = ($path,$dir);
134       $spath =~ s/.dir$//; $sdir =~ s/.dir$//; 
135       $sdir = $self->eliminate_macros($sdir) unless $sdir =~ /^[\w\-]+$/;
136       $rslt = $self->fixpath($self->eliminate_macros($spath)."/$sdir",1);
137     }
138     else { 
139       if ($dir =~ /^\$\([^\)]+\)$/) { $rslt = $dir; }
140       else                          { $rslt = vmspath($dir); }
141     }
142     print "catdir(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3;
143     $rslt;
144 }
145
146 =item catfile
147
148 Concatenates a list of file specifications, and returns the result as a
149 VMS-syntax directory specification.
150
151 =cut
152
153 sub catfile {
154     my($self,@files) = @_;
155     my($file) = pop @files;
156     @files = grep($_,@files);
157     my($rslt);
158     if (@files) {
159       my($path) = (@files == 1 ? $files[0] : $self->catdir(@files));
160       my($spath) = $path;
161       $spath =~ s/.dir$//;
162       if ( $spath =~ /^[^\)\]\/:>]+\)$/ && basename($file) eq $file) { $rslt = "$spath$file"; }
163       else {
164           $rslt = $self->eliminate_macros($spath);
165           $rslt = vmsify($rslt.($rslt ? '/' : '').unixify($file));
166       }
167     }
168     else { $rslt = vmsify($file); }
169     print "catfile(",join(',',@_[1..$#_]),") = |$rslt|\n" if $Verbose >= 3;
170     $rslt;
171 }
172
173 =item wraplist
174
175 Converts a list into a string wrapped at approximately 80 columns.
176
177 =cut
178
179 sub wraplist {
180     my($self) = shift;
181     my($line,$hlen) = ('',0);
182     my($word);
183
184     foreach $word (@_) {
185       # Perl bug -- seems to occasionally insert extra elements when
186       # traversing array (scalar(@array) doesn't show them, but
187       # foreach(@array) does) (5.00307)
188       next unless $word =~ /\w/;
189       $line .= ', ' if length($line);
190       if ($hlen > 80) { $line .= "\\\n\t"; $hlen = 0; }
191       $line .= $word;
192       $hlen += length($word) + 2;
193     }
194     $line;
195 }
196
197 =item curdir (override)
198
199 Returns a string representing of the current directory.
200
201 =cut
202
203 sub curdir {
204     return '[]';
205 }
206
207 =item rootdir (override)
208
209 Returns a string representing of the root directory.
210
211 =cut
212
213 sub rootdir {
214     return '';
215 }
216
217 =item updir (override)
218
219 Returns a string representing of the parent directory.
220
221 =cut
222
223 sub updir {
224     return '[-]';
225 }
226
227 package ExtUtils::MM_VMS;
228
229 sub ExtUtils::MM_VMS::ext;
230 sub ExtUtils::MM_VMS::guess_name;
231 sub ExtUtils::MM_VMS::find_perl;
232 sub ExtUtils::MM_VMS::path;
233 sub ExtUtils::MM_VMS::maybe_command;
234 sub ExtUtils::MM_VMS::maybe_command_in_dirs;
235 sub ExtUtils::MM_VMS::perl_script;
236 sub ExtUtils::MM_VMS::file_name_is_absolute;
237 sub ExtUtils::MM_VMS::replace_manpage_separator;
238 sub ExtUtils::MM_VMS::init_others;
239 sub ExtUtils::MM_VMS::constants;
240 sub ExtUtils::MM_VMS::cflags;
241 sub ExtUtils::MM_VMS::const_cccmd;
242 sub ExtUtils::MM_VMS::pm_to_blib;
243 sub ExtUtils::MM_VMS::tool_autosplit;
244 sub ExtUtils::MM_VMS::tool_xsubpp;
245 sub ExtUtils::MM_VMS::xsubpp_version;
246 sub ExtUtils::MM_VMS::tools_other;
247 sub ExtUtils::MM_VMS::dist;
248 sub ExtUtils::MM_VMS::c_o;
249 sub ExtUtils::MM_VMS::xs_c;
250 sub ExtUtils::MM_VMS::xs_o;
251 sub ExtUtils::MM_VMS::top_targets;
252 sub ExtUtils::MM_VMS::dlsyms;
253 sub ExtUtils::MM_VMS::dynamic_lib;
254 sub ExtUtils::MM_VMS::dynamic_bs;
255 sub ExtUtils::MM_VMS::static_lib;
256 sub ExtUtils::MM_VMS::manifypods;
257 sub ExtUtils::MM_VMS::processPL;
258 sub ExtUtils::MM_VMS::installbin;
259 sub ExtUtils::MM_VMS::subdir_x;
260 sub ExtUtils::MM_VMS::clean;
261 sub ExtUtils::MM_VMS::realclean;
262 sub ExtUtils::MM_VMS::dist_basics;
263 sub ExtUtils::MM_VMS::dist_core;
264 sub ExtUtils::MM_VMS::dist_dir;
265 sub ExtUtils::MM_VMS::dist_test;
266 sub ExtUtils::MM_VMS::install;
267 sub ExtUtils::MM_VMS::perldepend;
268 sub ExtUtils::MM_VMS::makefile;
269 sub ExtUtils::MM_VMS::test;
270 sub ExtUtils::MM_VMS::test_via_harness;
271 sub ExtUtils::MM_VMS::test_via_script;
272 sub ExtUtils::MM_VMS::makeaperl;
273 sub ExtUtils::MM_VMS::ext;
274 sub ExtUtils::MM_VMS::nicetext;
275
276 #use SelfLoader;
277 sub AUTOLOAD {
278     my $code;
279     if (defined fileno(DATA)) {
280         my $fh = select DATA;
281         my $o = $/;                     # For future reads from the file.
282         $/ = "\n__END__\n";
283         $code = <DATA>;
284         $/ = $o;
285         select $fh;
286         close DATA;
287         eval $code;
288         if ($@) {
289             $@ =~ s/ at .*\n//;
290             Carp::croak $@;
291         }
292     } else {
293         warn "AUTOLOAD called unexpectedly for $AUTOLOAD"; 
294     }
295     defined(&$AUTOLOAD) or die "Myloader inconsistency error";
296     goto &$AUTOLOAD;
297 }
298
299 1;
300
301 #__DATA__
302
303
304 # This isn't really an override.  It's just here because ExtUtils::MM_VMS
305 # appears in @MM::ISA before ExtUtils::Liblist, so if there isn't an ext()
306 # in MM_VMS, then AUTOLOAD is called, and bad things happen.  So, we just
307 # mimic inheritance here and hand off to ExtUtils::Liblist.
308 sub ext {
309   ExtUtils::Liblist::ext(@_);
310 }
311
312
313 =head2 SelfLoaded methods
314
315 Those methods which override default MM_Unix methods are marked
316 "(override)", while methods unique to MM_VMS are marked "(specific)".
317 For overridden methods, documentation is limited to an explanation
318 of why this method overrides the MM_Unix method; see the ExtUtils::MM_Unix
319 documentation for more details.
320
321 =item guess_name (override)
322
323 Try to determine name of extension being built.  We begin with the name
324 of the current directory.  Since VMS filenames are case-insensitive,
325 however, we look for a F<.pm> file whose name matches that of the current
326 directory (presumably the 'main' F<.pm> file for this extension), and try
327 to find a C<package> statement from which to obtain the Mixed::Case
328 package name.
329
330 =cut
331
332 sub guess_name {
333     my($self) = @_;
334     my($defname,$defpm,@pm,%xs,$pm);
335     local *PM;
336
337     $defname = basename(fileify($ENV{'DEFAULT'}));
338     $defname =~ s![\d\-_]*\.dir.*$!!;  # Clip off .dir;1 suffix, and package version
339     $defpm = $defname;
340     # Fallback in case for some reason a user has copied the files for an
341     # extension into a working directory whose name doesn't reflect the
342     # extension's name.  We'll use the name of a unique .pm file, or the
343     # first .pm file with a matching .xs file.
344     if (not -e "${defpm}.pm") {
345       @pm = map { s/.pm$//; $_ } glob('*.pm');
346       if (@pm == 1) { ($defpm = $pm[0]) =~ s/.pm$//; }
347       elsif (@pm) {
348         %xs = map { s/.xs$//; ($_,1) } glob('*.xs');
349         if (%xs) { foreach $pm (@pm) { $defpm = $pm, last if exists $xs{$pm}; } }
350       }
351     }
352     if (open(PM,"${defpm}.pm")){
353         while (<PM>) {
354             if (/^\s*package\s+([^;]+)/i) {
355                 $defname = $1;
356                 last;
357             }
358         }
359         print STDOUT "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
360                      "defaulting package name to $defname\n"
361             if eof(PM);
362         close PM;
363     }
364     else {
365         print STDOUT "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
366                      "defaulting package name to $defname\n";
367     }
368     $defname =~ s#[\d.\-_]+$##;
369     $defname;
370 }
371
372 =item find_perl (override)
373
374 Use VMS file specification syntax and CLI commands to find and
375 invoke Perl images.
376
377 =cut
378
379 sub find_perl {
380     my($self, $ver, $names, $dirs, $trace) = @_;
381     my($name,$dir,$vmsfile,@sdirs,@snames,@cand);
382     my($inabs) = 0;
383     # Check in relative directories first, so we pick up the current
384     # version of Perl if we're running MakeMaker as part of the main build.
385     @sdirs = sort { my($absa) = $self->file_name_is_absolute($a);
386                     my($absb) = $self->file_name_is_absolute($b);
387                     if ($absa && $absb) { return $a cmp $b }
388                     else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
389                   } @$dirs;
390     # Check miniperl before perl, and check names likely to contain
391     # version numbers before "generic" names, so we pick up an
392     # executable that's less likely to be from an old installation.
393     @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!;  # basename
394                      my($bb) = $b =~ m!([^:>\]/]+)$!;
395                      my($ahasdir) = (length($a) - length($ba) > 0);
396                      my($bhasdir) = (length($b) - length($bb) > 0);
397                      if    ($ahasdir and not $bhasdir) { return 1; }
398                      elsif ($bhasdir and not $ahasdir) { return -1; }
399                      else { $bb =~ /\d/ <=> $ba =~ /\d/
400                             or substr($ba,0,1) cmp substr($bb,0,1)
401                             or length($bb) <=> length($ba) } } @$names;
402     # Image names containing Perl version use '_' instead of '.' under VMS
403     foreach $name (@snames) { $name =~ s/\.(\d+)$/_$1/; }
404     if ($trace >= 2){
405         print "Looking for perl $ver by these names:\n";
406         print "\t@snames,\n";
407         print "in these dirs:\n";
408         print "\t@sdirs\n";
409     }
410     foreach $dir (@sdirs){
411         next unless defined $dir; # $self->{PERL_SRC} may be undefined
412         $inabs++ if $self->file_name_is_absolute($dir);
413         if ($inabs == 1) {
414             # We've covered relative dirs; everything else is an absolute
415             # dir (probably an installed location).  First, we'll try potential
416             # command names, to see whether we can avoid a long MCR expression.
417             foreach $name (@snames) { push(@cand,$name) if $name =~ /^[\w\-\$]+$/; }
418             $inabs++; # Should happen above in next $dir, but just in case . . .
419         }
420         foreach $name (@snames){
421             if ($name !~ m![/:>\]]!) { push(@cand,$self->catfile($dir,$name)); }
422             else                     { push(@cand,$self->fixpath($name));      }
423         }
424     }
425     foreach $name (@cand) {
426         print "Checking $name\n" if ($trace >= 2);
427         # If it looks like a potential command, try it without the MCR
428         if ($name =~ /^[\w\-\$]+$/ &&
429             `$name -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) {
430             print "Using PERL=$name\n" if $trace;
431             return $name;
432         }
433         next unless $vmsfile = $self->maybe_command($name);
434         $vmsfile =~ s/;[\d\-]*$//;  # Clip off version number; we can use a newer version as well
435         print "Executing $vmsfile\n" if ($trace >= 2);
436         if (`MCR $vmsfile -e "require $ver; print ""VER_OK\n"""` =~ /VER_OK/) {
437             print "Using PERL=MCR $vmsfile\n" if $trace;
438             return "MCR $vmsfile";
439         }
440     }
441     print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
442     0; # false and not empty
443 }
444
445 =item path (override)
446
447 Translate logical name DCL$PATH as a searchlist, rather than trying
448 to C<split> string value of C<$ENV{'PATH'}>.
449
450 =cut
451
452 sub path {
453     my(@dirs,$dir,$i);
454     while ($dir = $ENV{'DCL$PATH;' . $i++}) { push(@dirs,$dir); }
455     @dirs;
456 }
457
458 =item maybe_command (override)
459
460 Follows VMS naming conventions for executable files.
461 If the name passed in doesn't exactly match an executable file,
462 appends F<.Exe> to check for executable image, and F<.Com> to check
463 for DCL procedure.  If this fails, checks F<Sys$System:> for an
464 executable file having the name specified.  Finally, appends F<.Exe>
465 and checks again.
466
467 =cut
468
469 sub maybe_command {
470     my($self,$file) = @_;
471     return $file if -x $file && ! -d _;
472     return "$file.exe" if -x "$file.exe";
473     return "$file.com" if -x "$file.com";
474     if ($file !~ m![/:>\]]!) {
475         my($shrfile) = 'Sys$System:' . $file;
476         return $file if -x $shrfile && ! -d _;
477         return "$file.exe" if -x "$shrfile.exe";
478     }
479     return 0;
480 }
481
482 =item maybe_command_in_dirs (override)
483
484 Uses DCL argument quoting on test command line.
485
486 =cut
487
488 sub maybe_command_in_dirs {     # $ver is optional argument if looking for perl
489     my($self, $names, $dirs, $trace, $ver) = @_;
490     my($name, $dir);
491     foreach $dir (@$dirs){
492         next unless defined $dir; # $self->{PERL_SRC} may be undefined
493         foreach $name (@$names){
494             my($abs,$tryabs);
495             if ($self->file_name_is_absolute($name)) {
496                 $abs = $name;
497             } else {
498                 $abs = $self->catfile($dir, $name);
499             }
500             print "Checking $abs for $name\n" if ($trace >= 2);
501             next unless $tryabs = $self->maybe_command($abs);
502             print "Substituting $tryabs instead of $abs\n" 
503                 if ($trace >= 2 and $tryabs ne $abs);
504             $abs = $tryabs;
505             if (defined $ver) {
506                 print "Executing $abs\n" if ($trace >= 2);
507                 if (`$abs -e 'require $ver; print "VER_OK\n" ' 2>&1` =~ /VER_OK/) {
508                     print "Using $abs\n" if $trace;
509                     return $abs;
510                 }
511             } else { # Do not look for perl
512                 return $abs;
513             }
514         }
515     }
516 }
517
518 =item perl_script (override)
519
520 If name passed in doesn't specify a readable file, appends F<.pl> and
521 tries again, since it's customary to have file types on all files
522 under VMS.
523
524 =cut
525
526 sub perl_script {
527     my($self,$file) = @_;
528     return $file if -r $file && ! -d _;
529     return "$file.pl" if -r "$file.pl" && ! -d _;
530     return '';
531 }
532
533 =item file_name_is_absolute (override)
534
535 Checks for VMS directory spec as well as Unix separators.
536
537 =cut
538
539 sub file_name_is_absolute {
540     my($self,$file) = @_;
541     # If it's a logical name, expand it.
542     $file = $ENV{$file} while $file =~ /^[\w\$\-]+$/ and $ENV{$file};
543     $file =~ m!^/! or $file =~ m![<\[][^.\-\]>]! or $file =~ /:[^<\[]/;
544 }
545
546 =item replace_manpage_separator
547
548 Use as separator a character which is legal in a VMS-syntax file name.
549
550 =cut
551
552 sub replace_manpage_separator {
553     my($self,$man) = @_;
554     $man = unixify($man);
555     $man =~ s#/+#__#g;
556     $man;
557 }
558
559 =item init_others (override)
560
561 Provide VMS-specific forms of various utility commands, then hand
562 off to the default MM_Unix method.
563
564 =cut
565
566 sub init_others {
567     my($self) = @_;
568
569     $self->{NOOP} = 'Continue';
570     $self->{FIRST_MAKEFILE} ||= 'Descrip.MMS';
571     $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS';
572     $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE};
573     $self->{NOECHO} ||= '@ ';
574     $self->{RM_F} = '$(PERL) -e "foreach (@ARGV) { 1 while ( -d $_ ? rmdir $_ : unlink $_)}"';
575     $self->{RM_RF} = '$(PERL) "-I$(PERL_LIB)" -e "use File::Path; @dirs = map(VMS::Filespec::unixify($_),@ARGV); rmtree(\@dirs,0,0)"';
576     $self->{TOUCH} = '$(PERL) -e "$t=time; foreach (@ARGV) { -e $_ ? utime($t,$t,@ARGV) : (open(F,qq(>$_)),close F)}"';
577     $self->{CHMOD} = '$(PERL) -e "chmod @ARGV"';  # expect Unix syntax from MakeMaker
578     $self->{CP} = 'Copy/NoConfirm';
579     $self->{MV} = 'Rename/NoConfirm';
580     $self->{UMASK_NULL} = '! ';  
581     &ExtUtils::MM_Unix::init_others;
582 }
583
584 =item constants (override)
585
586 Fixes up numerous file and directory macros to insure VMS syntax
587 regardless of input syntax.  Also adds a few VMS-specific macros
588 and makes lists of files comma-separated.
589
590 =cut
591
592 sub constants {
593     my($self) = @_;
594     my(@m,$def,$macro);
595
596     if ($self->{DEFINE} ne '') {
597         my(@defs) = split(/\s+/,$self->{DEFINE});
598         foreach $def (@defs) {
599             next unless $def;
600             if ($def =~ s/^-D//) {       # If it was a Unix-style definition
601                 $def =~ s/='(.*)'$/=$1/;  # then remove shell-protection ''
602                 $def =~ s/^'(.*)'$/$1/;   # from entire term or argument
603             }
604             if ($def =~ /=/) {
605                 $def =~ s/"/""/g;  # Protect existing " from DCL
606                 $def = qq["$def"]; # and quote to prevent parsing of =
607             }
608         }
609         $self->{DEFINE} = join ',',@defs;
610     }
611
612     if ($self->{OBJECT} =~ /\s/) {
613         $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g;
614         $self->{OBJECT} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{OBJECT})));
615     }
616     $self->{LDFROM} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{LDFROM})));
617
618
619     # Fix up directory specs
620     $self->{ROOTEXT} = $self->{ROOTEXT} ? $self->fixpath($self->{ROOTEXT},1)
621                                         : '[]';
622     foreach $macro ( qw [
623             INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB INST_EXE INSTALLPRIVLIB
624             INSTALLARCHLIB INSTALLSCRIPT INSTALLBIN PERL_LIB PERL_ARCHLIB
625             PERL_INC PERL_SRC FULLEXT INST_MAN1DIR INSTALLMAN1DIR
626             INST_MAN3DIR INSTALLMAN3DIR INSTALLSITELIB INSTALLSITEARCH
627             SITELIBEXP SITEARCHEXP ] ) {
628         next unless defined $self->{$macro};
629         $self->{$macro} = $self->fixpath($self->{$macro},1);
630     }
631     $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC},q(VMS))
632         if ($self->{PERL_SRC});
633                         
634
635
636     # Fix up file specs
637     foreach $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKE_APERL_FILE MYEXTLIB] ) {
638         next unless defined $self->{$macro};
639         $self->{$macro} = $self->fixpath($self->{$macro});
640     }
641
642     foreach $macro (qw/
643               AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION
644               INST_BIN INST_EXE INST_LIB INST_ARCHLIB INST_SCRIPT PREFIX
645               INSTALLDIRS INSTALLPRIVLIB  INSTALLARCHLIB INSTALLSITELIB
646               INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB
647               PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB
648               FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC PERL_VMS
649               PERL_INC PERL FULLPERL
650               / ) {
651         next unless defined $self->{$macro};
652         push @m, "$macro = $self->{$macro}\n";
653     }
654
655
656     push @m, q[
657 VERSION_MACRO = VERSION
658 DEFINE_VERSION = "$(VERSION_MACRO)=""$(VERSION)"""
659 XS_VERSION_MACRO = XS_VERSION
660 XS_DEFINE_VERSION = "$(XS_VERSION_MACRO)=""$(XS_VERSION)"""
661
662 MAKEMAKER = ],$self->catfile($self->{PERL_LIB},'ExtUtils','MakeMaker.pm'),qq[
663 MM_VERSION = $ExtUtils::MakeMaker::VERSION
664 MM_REVISION = $ExtUtils::MakeMaker::Revision
665 MM_VMS_REVISION = $ExtUtils::MM_VMS::Revision
666
667 # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
668 # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
669 # PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
670 # DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
671 ];
672
673     for $tmp (qw/
674               FULLEXT VERSION_FROM OBJECT LDFROM
675               / ) {
676         next unless defined $self->{$tmp};
677         push @m, "$tmp = ",$self->fixpath($self->{$tmp}),"\n";
678     }
679
680     for $tmp (qw/
681               BASEEXT PARENT_NAME DLBASE INC DEFINE LINKTYPE
682               / ) {
683         next unless defined $self->{$tmp};
684         push @m, "$tmp = $self->{$tmp}\n";
685     }
686
687     for $tmp (qw/ XS MAN1PODS MAN3PODS PM /) {
688         next unless defined $self->{$tmp};
689         my(%tmp,$key);
690         for $key (keys %{$self->{$tmp}}) {
691             $tmp{$self->fixpath($key)} = $self->fixpath($self->{$tmp}{$key});
692         }
693         $self->{$tmp} = \%tmp;
694     }
695
696     for $tmp (qw/ C O_FILES H /) {
697         next unless defined $self->{$tmp};
698         my(@tmp,$val);
699         for $val (@{$self->{$tmp}}) {
700             push(@tmp,$self->fixpath($val));
701         }
702         $self->{$tmp} = \@tmp;
703     }
704
705     push @m,'
706
707 # Handy lists of source code files:
708 XS_FILES = ',$self->wraplist(', ', sort keys %{$self->{XS}}),'
709 C_FILES  = ',$self->wraplist(', ', @{$self->{C}}),'
710 O_FILES  = ',$self->wraplist(', ', @{$self->{O_FILES}} ),'
711 H_FILES  = ',$self->wraplist(', ', @{$self->{H}}),'
712 MAN1PODS = ',$self->wraplist(', ', sort keys %{$self->{MAN1PODS}}),'
713 MAN3PODS = ',$self->wraplist(', ', sort keys %{$self->{MAN3PODS}}),'
714
715 ';
716
717     for $tmp (qw/
718               INST_MAN1DIR INSTALLMAN1DIR MAN1EXT INST_MAN3DIR INSTALLMAN3DIR MAN3EXT
719               /) {
720         next unless defined $self->{$tmp};
721         push @m, "$tmp = $self->{$tmp}\n";
722     }
723
724 push @m,"
725 .SUFFIXES :
726 .SUFFIXES : \$(OBJ_EXT) .c .cpp .cxx .xs
727
728 # Here is the Config.pm that we are using/depend on
729 CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM)
730
731 # Where to put things:
732 INST_LIBDIR      = $self->{INST_LIBDIR}
733 INST_ARCHLIBDIR  = $self->{INST_ARCHLIBDIR}
734
735 INST_AUTODIR     = $self->{INST_AUTODIR}
736 INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR}
737 ";
738
739     if ($self->has_link_code()) {
740         push @m,'
741 INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT)
742 INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
743 INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
744 ';
745     } else {
746         push @m,'
747 INST_STATIC =
748 INST_DYNAMIC =
749 INST_BOOT =
750 EXPORT_LIST = $(BASEEXT).opt
751 PERL_ARCHIVE = ',($ENV{'PERLSHR'} ? $ENV{'PERLSHR'} : 'Sys$Share:PerlShr.Exe'),'
752 ';
753     }
754
755     $self->{TO_INST_PM} = [ sort keys %{$self->{PM}} ];
756     $self->{PM_TO_BLIB} = [ %{$self->{PM}} ];
757     push @m,'
758 TO_INST_PM = ',$self->wraplist(', ',@{$self->{TO_INST_PM}}),'
759
760 PM_TO_BLIB = ',$self->wraplist(', ',@{$self->{PM_TO_BLIB}}),'
761 ';
762
763     join('',@m);
764 }
765
766 =item cflags (override)
767
768 Bypass shell script and produce qualifiers for CC directly (but warn
769 user if a shell script for this extension exists).  Fold multiple
770 /Defines into one, since some C compilers pay attention to only one
771 instance of this qualifier on the command line.
772
773 =cut
774
775 sub cflags {
776     my($self,$libperl) = @_;
777     my($quals) = $Config{'ccflags'};
778     my($name,$sys,@m);
779     my($optimize) = '/Optimize';
780
781     ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
782     print STDOUT "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
783          " required to modify CC command for $self->{'BASEEXT'}\n"
784     if ($Config{$name});
785
786     # Deal with $self->{DEFINE} here since some C compilers pay attention
787     # to only one /Define clause on command line, so we have to
788     # conflate the ones from $Config{'cc'} and $self->{DEFINE}
789     if ($quals =~ m:(.*)/define=\(?([^\(\/\)\s]+)\)?(.*)?:i) {
790         $quals = "$1/Define=($2," . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
791                  "\$(DEFINE_VERSION),\$(XS_DEFINE_VERSION))$3";
792     }
793     else {
794         $quals .= '/Define=(' . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
795                   '$(DEFINE_VERSION),$(XS_DEFINE_VERSION))';
796     }
797
798     $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
799     if ($libperl =~ /libperl(\w+)\./i) {
800         my($type) = uc $1;
801         my(%map) = ( 'D'  => 'DEBUGGING', 'E' => 'EMBED', 'M' => 'MULTIPLICITY',
802                      'DE' => 'DEBUGGING,EMBED', 'DM' => 'DEBUGGING,MULTIPLICITY',
803                      'EM' => 'EMBED,MULTIPLICITY', 'DEM' => 'DEBUGGING,EMBED,MULTIPLICITY' );
804         $quals =~ s:/define=\(([^\)]+)\):/Define=($1,$map{$type}):i
805     }
806
807     # Likewise with $self->{INC} and /Include
808     my($incstr) = '/Include=($(PERL_INC)';
809     if ($self->{'INC'}) {
810         my(@includes) = split(/\s+/,$self->{INC});
811         foreach (@includes) {
812             s/^-I//;
813             $incstr .= ', '.$self->fixpath($_,1);
814         }
815     }
816     $quals .= "$incstr)";
817
818     $optimize = '/Debug/NoOptimize'
819         if ($self->{OPTIMIZE} =~ /-g/ or $self->{OPTIMIZE} =~ m!/Debug!i);
820
821     return $self->{CFLAGS} = qq{
822 CCFLAGS = $quals
823 OPTIMIZE = $optimize
824 PERLTYPE =
825 SPLIT =
826 LARGE =
827 };
828 }
829
830 =item const_cccmd (override)
831
832 Adds directives to point C preprocessor to the right place when
833 handling #include E<lt>sys/foo.hE<gt> directives.  Also constructs CC
834 command line a bit differently than MM_Unix method.
835
836 =cut
837
838 sub const_cccmd {
839     my($self,$libperl) = @_;
840     my(@m);
841
842     return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
843     return '' unless $self->needs_linking();
844     if ($Config{'vms_cc_type'} eq 'gcc') {
845         push @m,'
846 .FIRST
847         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
848     }
849     elsif ($Config{'vms_cc_type'} eq 'vaxc') {
850         push @m,'
851 .FIRST
852         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
853         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
854     }
855     else {
856         push @m,'
857 .FIRST
858         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
859                 ($Config{'arch'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
860         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
861     }
862
863     push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
864
865     $self->{CONST_CCCMD} = join('',@m);
866 }
867
868 =item pm_to_blib (override)
869
870 DCL I<still> accepts a maximum of 255 characters on a command
871 line, so we write the (potentially) long list of file names
872 to a temp file, then persuade Perl to read it instead of the
873 command line to find args.
874
875 =cut
876
877 sub pm_to_blib {
878     my($self) = @_;
879     my($line,$from,$to,@m);
880     my($autodir) = $self->catdir('$(INST_LIB)','auto');
881     my(@files) = @{$self->{PM_TO_BLIB}};
882
883     push @m, q{
884
885 # Dummy target to match Unix target name; we use pm_to_blib.ts as
886 # timestamp file to avoid repeated invocations under VMS
887 pm_to_blib : pm_to_blib.ts
888         $(NOECHO) $(NOOP)
889
890 # As always, keep under DCL's 255-char limit
891 pm_to_blib.ts : $(TO_INST_PM)
892         $(NOECHO) $(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp
893 };
894
895     $line = '';  # avoid uninitialized var warning
896     while ($from = shift(@files),$to = shift(@files)) {
897         $line .= " $from $to";
898         if (length($line) > 128) {
899             push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n");
900             $line = '';
901         }
902     }
903     push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line;
904
905     push(@m,q[  $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',<STDIN>)},'].$autodir.q[')" <.MM_tmp]);
906     push(@m,qq[
907         \$(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
908         \$(NOECHO) \$(TOUCH) pm_to_blib.ts
909 ]);
910
911     join('',@m);
912 }
913
914 =item tool_autosplit (override)
915
916 Use VMS-style quoting on command line.
917
918 =cut
919
920 sub tool_autosplit{
921     my($self, %attribs) = @_;
922     my($asl) = "";
923     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
924     q{
925 # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
926 AUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
927 };
928 }
929
930 =item tool_sxubpp (override)
931
932 Use VMS-style quoting on xsubpp command line.
933
934 =cut
935
936 sub tool_xsubpp {
937     my($self) = @_;
938     return '' unless $self->needs_linking;
939     my($xsdir) = $self->catdir($self->{PERL_LIB},'ExtUtils');
940     # drop back to old location if xsubpp is not in new location yet
941     $xsdir = $self->catdir($self->{PERL_SRC},'ext') unless (-f $self->catfile($xsdir,'xsubpp'));
942     my(@tmdeps) = '$(XSUBPPDIR)typemap';
943     if( $self->{TYPEMAPS} ){
944         my $typemap;
945         foreach $typemap (@{$self->{TYPEMAPS}}){
946                 if( ! -f  $typemap ){
947                         warn "Typemap $typemap not found.\n";
948                 }
949                 else{
950                         push(@tmdeps, $self->fixpath($typemap));
951                 }
952         }
953     }
954     push(@tmdeps, "typemap") if -f "typemap";
955     my(@tmargs) = map("-typemap $_", @tmdeps);
956     if( exists $self->{XSOPT} ){
957         unshift( @tmargs, $self->{XSOPT} );
958     }
959
960     my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,'xsubpp'));
961
962     # What are the correct thresholds for version 1 && 2 Paul?
963     if ( $xsubpp_version > 1.923 ){
964         $self->{XSPROTOARG} = '' unless defined $self->{XSPROTOARG};
965     } else {
966         if (defined $self->{XSPROTOARG} && $self->{XSPROTOARG} =~ /\-prototypes/) {
967             print STDOUT qq{Warning: This extension wants to pass the switch "-prototypes" to xsubpp.
968         Your version of xsubpp is $xsubpp_version and cannot handle this.
969         Please upgrade to a more recent version of xsubpp.
970 };
971         } else {
972             $self->{XSPROTOARG} = "";
973         }
974     }
975
976     "
977 XSUBPPDIR = $xsdir
978 XSUBPP = \$(PERL) \"-I\$(PERL_ARCHLIB)\" \"-I\$(PERL_LIB)\" \$(XSUBPPDIR)xsubpp
979 XSPROTOARG = $self->{XSPROTOARG}
980 XSUBPPDEPS = @tmdeps
981 XSUBPPARGS = @tmargs
982 ";
983 }
984
985 =item xsubpp_version (override)
986
987 Test xsubpp exit status according to VMS rules ($sts & 1 ==E<gt> good)
988 rather than Unix rules ($sts == 0 ==E<gt> good).
989
990 =cut
991
992 sub xsubpp_version
993 {
994     my($self,$xsubpp) = @_;
995     my ($version) ;
996     return '' unless $self->needs_linking;
997
998     # try to figure out the version number of the xsubpp on the system
999
1000     # first try the -v flag, introduced in 1.921 & 2.000a2
1001
1002     my $command = "$self->{PERL} \"-I$self->{PERL_LIB}\" $xsubpp -v";
1003     print "Running: $command\n" if $Verbose;
1004     $version = `$command` ;
1005     warn "Running '$command' exits with status " . $? unless ($? & 1);
1006     chop $version ;
1007
1008     return $1 if $version =~ /^xsubpp version (.*)/ ;
1009
1010     # nope, then try something else
1011
1012     my $counter = '000';
1013     my ($file) = 'temp' ;
1014     $counter++ while -e "$file$counter"; # don't overwrite anything
1015     $file .= $counter;
1016
1017     local(*F);
1018     open(F, ">$file") or die "Cannot open file '$file': $!\n" ;
1019     print F <<EOM ;
1020 MODULE = fred PACKAGE = fred
1021
1022 int
1023 fred(a)
1024         int     a;
1025 EOM
1026
1027     close F ;
1028
1029     $command = "$self->{PERL} $xsubpp $file";
1030     print "Running: $command\n" if $Verbose;
1031     my $text = `$command` ;
1032     warn "Running '$command' exits with status " . $? unless ($? & 1);
1033     unlink $file ;
1034
1035     # gets 1.2 -> 1.92 and 2.000a1
1036     return $1 if $text =~ /automatically by xsubpp version ([\S]+)\s*/  ;
1037
1038     # it is either 1.0 or 1.1
1039     return 1.1 if $text =~ /^Warning: ignored semicolon/ ;
1040
1041     # none of the above, so 1.0
1042     return "1.0" ;
1043 }
1044
1045 =item tools_other (override)
1046
1047 Adds a few MM[SK] macros, and shortens some the installatin commands,
1048 in order to stay under DCL's 255-character limit.  Also changes
1049 EQUALIZE_TIMESTAMP to set revision date of target file to one second
1050 later than source file, since MMK interprets precisely equal revision
1051 dates for a source and target file as a sign that the target needs
1052 to be updated.
1053
1054 =cut
1055
1056 sub tools_other {
1057     my($self) = @_;
1058     qq!
1059 # Assumes \$(MMS) invokes MMS or MMK
1060 # (It is assumed in some cases later that the default makefile name
1061 # (Descrip.MMS for MM[SK]) is used.)
1062 USEMAKEFILE = /Descrip=
1063 USEMACROS = /Macro=(
1064 MACROEND = )
1065 MAKEFILE = Descrip.MMS
1066 SHELL = Posix
1067 TOUCH = $self->{TOUCH}
1068 CHMOD = $self->{CHMOD}
1069 CP = $self->{CP}
1070 MV = $self->{MV}
1071 RM_F  = $self->{RM_F}
1072 RM_RF = $self->{RM_RF}
1073 SAY = Write Sys\$Output
1074 UMASK_NULL = $self->{UMASK_NULL}
1075 NOOP = $self->{NOOP}
1076 NOECHO = $self->{NOECHO}
1077 MKPATH = Create/Directory
1078 EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])"
1079 !. ($self->{PARENT} ? '' : 
1080 qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}"
1081 MOD_INSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "install({split(' ',<STDIN>)},1);"
1082 DOC_INSTALL = \$(PERL) -e "\@ARGV=split(/\\|/,<STDIN>);print '=head2 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];while(\$key=shift && \$val=shift){print qq[=item *\\n\\nC<\$key: \$val>\\n\\n];}print qq[=back\\n\\n]"
1083 UNINSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1,1);"
1084 !);
1085 }
1086
1087 =item dist (override)
1088
1089 Provide VMSish defaults for some values, then hand off to
1090 default MM_Unix method.
1091
1092 =cut
1093
1094 sub dist {
1095     my($self, %attribs) = @_;
1096     $attribs{VERSION}      ||= $self->{VERSION_SYM};
1097     $attribs{ZIPFLAGS}     ||= '-Vu';
1098     $attribs{COMPRESS}     ||= 'gzip';
1099     $attribs{SUFFIX}       ||= '-gz';
1100     $attribs{SHAR}         ||= 'vms_share';
1101     $attribs{DIST_DEFAULT} ||= 'zipdist';
1102
1103     return ExtUtils::MM_Unix::dist($self,%attribs);
1104 }
1105
1106 =item c_o (override)
1107
1108 Use VMS syntax on command line.  In particular, $(DEFINE) and
1109 $(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
1110
1111 =cut
1112
1113 sub c_o {
1114     my($self) = @_;
1115     return '' unless $self->needs_linking();
1116     '
1117 .c$(OBJ_EXT) :
1118         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1119
1120 .cpp$(OBJ_EXT) :
1121         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
1122
1123 .cxx$(OBJ_EXT) :
1124         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
1125
1126 ';
1127 }
1128
1129 =item xs_c (override)
1130
1131 Use MM[SK] macros.
1132
1133 =cut
1134
1135 sub xs_c {
1136     my($self) = @_;
1137     return '' unless $self->needs_linking();
1138     '
1139 .xs.c :
1140         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
1141 ';
1142 }
1143
1144 =item xs_o (override)
1145
1146 Use MM[SK] macros, and VMS command line for C compiler.
1147
1148 =cut
1149
1150 sub xs_o {      # many makes are too dumb to use xs_c then c_o
1151     my($self) = @_;
1152     return '' unless $self->needs_linking();
1153     '
1154 .xs$(OBJ_EXT) :
1155         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
1156         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1157 ';
1158 }
1159
1160 =item top_targets (override)
1161
1162 Use VMS quoting on command line for Version_check.
1163
1164 =cut
1165
1166 sub top_targets {
1167     my($self) = shift;
1168     my(@m);
1169     push @m, '
1170 all :: pure_all manifypods
1171         $(NOECHO) $(NOOP)
1172
1173 pure_all :: config pm_to_blib subdirs linkext
1174         $(NOECHO) $(NOOP)
1175
1176 subdirs :: $(MYEXTLIB)
1177         $(NOECHO) $(NOOP)
1178
1179 config :: $(MAKEFILE) $(INST_LIBDIR).exists
1180         $(NOECHO) $(NOOP)
1181
1182 config :: $(INST_ARCHAUTODIR).exists
1183         $(NOECHO) $(NOOP)
1184
1185 config :: $(INST_AUTODIR).exists
1186         $(NOECHO) $(NOOP)
1187 ';
1188
1189     push @m, q{
1190 config :: Version_check
1191         $(NOECHO) $(NOOP)
1192
1193 } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC};
1194
1195
1196     push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
1197     if (%{$self->{MAN1PODS}}) {
1198         push @m, q[
1199 config :: $(INST_MAN1DIR).exists
1200         $(NOECHO) $(NOOP)
1201 ];
1202         push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
1203     }
1204     if (%{$self->{MAN3PODS}}) {
1205         push @m, q[
1206 config :: $(INST_MAN3DIR).exists
1207         $(NOECHO) $(NOOP)
1208 ];
1209         push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
1210     }
1211
1212     push @m, '
1213 $(O_FILES) : $(H_FILES)
1214 ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
1215
1216     push @m, q{
1217 help :
1218         perldoc ExtUtils::MakeMaker
1219 };
1220
1221     push @m, q{
1222 Version_check :
1223         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1224         "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')"
1225 };
1226
1227     join('',@m);
1228 }
1229
1230 =item dlsyms (override)
1231
1232 Create VMS linker options files specifying universal symbols for this
1233 extension's shareable image, and listing other shareable images or 
1234 libraries to which it should be linked.
1235
1236 =cut
1237
1238 sub dlsyms {
1239     my($self,%attribs) = @_;
1240
1241     return '' unless $self->needs_linking();
1242
1243     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1244     my($vars)  = $attribs{DL_VARS}  || $self->{DL_VARS}  || [];
1245     my($srcdir)= $attribs{PERL_SRC} || $self->{PERL_SRC} || '';
1246     my(@m);
1247
1248     unless ($self->{SKIPHASH}{'dynamic'}) {
1249         push(@m,'
1250 dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt
1251         $(NOECHO) $(NOOP)
1252 ');
1253         if ($srcdir) {
1254            my($popt) = $self->catfile($srcdir,'perlshr.opt');
1255            my($lopt) = $self->catfile($srcdir,'crtl.opt');
1256            push(@m,"# Depend on \$(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists
1257 rtls.opt : $popt $lopt \$(BASEEXT).opt
1258         Copy/Log $popt Sys\$Disk:[]rtls.opt
1259         Append/Log $lopt Sys\$Disk:[]rtls.opt
1260 ");
1261         }
1262         else {
1263             push(@m,'
1264 # rtls.opt is built in the same step as $(BASEEXT).opt
1265 rtls.opt : $(BASEEXT).opt
1266         $(TOUCH) $(MMS$TARGET)
1267 ');
1268         }
1269     }
1270
1271     push(@m,'
1272 static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1273         $(NOECHO) $(NOOP)
1274 ') unless $self->{SKIPHASH}{'static'};
1275
1276     push(@m,'
1277 $(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
1278         $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1279
1280 $(BASEEXT).opt : Makefile.PL
1281         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Mksymlists;" -
1282         ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
1283         neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),')"
1284         $(PERL) -e "print ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)
1285 ');
1286
1287     if (length $self->{LDLOADLIBS}) {
1288         my($lib); my($line) = '';
1289         foreach $lib (split ' ', $self->{LDLOADLIBS}) {
1290             $lib =~ s%\$%\\\$%g;  # Escape '$' in VMS filespecs
1291             if (length($line) + length($lib) > 160) {
1292                 push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n";
1293                 $line = $lib . '\n';
1294             }
1295             else { $line .= $lib . '\n'; }
1296         }
1297         push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n" if $line;
1298     }
1299
1300     join('',@m);
1301
1302 }
1303
1304 =item dynamic_lib (override)
1305
1306 Use VMS Link command.
1307
1308 =cut
1309
1310 sub dynamic_lib {
1311     my($self, %attribs) = @_;
1312     return '' unless $self->needs_linking(); #might be because of a subdir
1313
1314     return '' unless $self->has_link_code();
1315
1316     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
1317     my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1318     my(@m);
1319     push @m,"
1320
1321 OTHERLDFLAGS = $otherldflags
1322 INST_DYNAMIC_DEP = $inst_dynamic_dep
1323
1324 ";
1325     push @m, '
1326 $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1327         $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
1328         $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.Exe
1329         Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option
1330 ';
1331
1332     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1333     join('',@m);
1334 }
1335
1336 =item dynamic_bs (override)
1337
1338 Use VMS-style quoting on Mkbootstrap command line.
1339
1340 =cut
1341
1342 sub dynamic_bs {
1343     my($self, %attribs) = @_;
1344     return '
1345 BOOTSTRAP =
1346 ' unless $self->has_link_code();
1347     '
1348 BOOTSTRAP = '."$self->{BASEEXT}.bs".'
1349
1350 # As MakeMaker mkbootstrap might not write a file (if none is required)
1351 # we use touch to prevent make continually trying to remake it.
1352 # The DynaLoader only reads a non-empty file.
1353 $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists
1354         $(NOECHO) $(SAY) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
1355         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1356         -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
1357         $(NOECHO) $(TOUCH) $(MMS$TARGET)
1358
1359 $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists
1360         $(NOECHO) $(RM_RF) $(INST_BOOT)
1361         - $(CP) $(BOOTSTRAP) $(INST_BOOT)
1362 ';
1363 }
1364
1365 =item static_lib (override)
1366
1367 Use VMS commands to manipulate object library.
1368
1369 =cut
1370
1371 sub static_lib {
1372     my($self) = @_;
1373     return '' unless $self->needs_linking();
1374
1375     return '
1376 $(INST_STATIC) :
1377         $(NOECHO) $(NOOP)
1378 ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
1379
1380     my(@m);
1381     push @m,'
1382 # Rely on suffix rule for update action
1383 $(OBJECT) : $(INST_ARCHAUTODIR).exists
1384
1385 $(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
1386 ';
1387     # If this extension has it's own library (eg SDBM_File)
1388     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1389     push(@m, '  $(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1390
1391     push(@m,'
1392         If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
1393         Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
1394         $(NOECHO) $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;"
1395 ');
1396     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1397     join('',@m);
1398 }
1399
1400
1401 # sub installpm_x { # called by installpm perl file
1402 #     my($self, $dist, $inst, $splitlib) = @_;
1403 #     if ($inst =~ m!#!) {
1404 #       warn "Warning: MM[SK] would have problems processing this file: $inst, SKIPPED\n";
1405 #       return '';
1406 #     }
1407 #     $inst = $self->fixpath($inst);
1408 #     $dist = $self->fixpath($dist);
1409 #     my($instdir) = $inst =~ /([^\)]+\))[^\)]*$/ ? $1 : dirname($inst);
1410 #     my(@m);
1411
1412 #     push(@m, "
1413 # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists
1414 # ",'   $(NOECHO) $(RM_F) $(MMS$TARGET)
1415 #       $(NOECHO) $(CP) ',"$dist $inst",'
1416 #       $(CHMOD) 644 $(MMS$TARGET)
1417 # ');
1418 #     push(@m, '        $(AUTOSPLITFILE) $(MMS$TARGET) ',
1419 #               $self->catdir($splitlib,'auto')."\n\n")
1420 #         if ($splitlib and $inst =~ /\.pm$/);
1421 #     push(@m,$self->dir_target($instdir));
1422
1423 #     join('',@m);
1424 # }
1425
1426 =item manifypods (override)
1427
1428 Use VMS-style quoting on command line, and VMS logical name
1429 to specify fallback location at build time if we can't find pod2man.
1430
1431 =cut
1432
1433
1434 sub manifypods {
1435     my($self, %attribs) = @_;
1436     return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}};
1437     my($dist);
1438     my($pod2man_exe);
1439     if (defined $self->{PERL_SRC}) {
1440         $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man');
1441     } else {
1442         $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man');
1443     }
1444     if (not ($pod2man_exe = $self->perl_script($pod2man_exe))) {
1445         # No pod2man but some MAN3PODS to be installed
1446         print <<END;
1447
1448 Warning: I could not locate your pod2man program.  As a last choice,
1449          I will look for the file to which the logical name POD2MAN
1450          points when MMK is invoked.
1451
1452 END
1453         $pod2man_exe = "pod2man";
1454     }
1455     my(@m);
1456     push @m,
1457 qq[POD2MAN_EXE = $pod2man_exe\n],
1458 q[POD2MAN = $(PERL) -we "%m=@ARGV;for (keys %m){" -
1459 -e "system(""MCR $^X $(POD2MAN_EXE) $_ >$m{$_}"");}"
1460 ];
1461     push @m, "\nmanifypods : \$(MAN1PODS) \$(MAN3PODS)\n";
1462     if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) {
1463         my($pod);
1464         foreach $pod (sort keys %{$self->{MAN1PODS}}) {
1465             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1466             push @m, "$pod $self->{MAN1PODS}{$pod}\n";
1467         }
1468         foreach $pod (sort keys %{$self->{MAN3PODS}}) {
1469             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1470             push @m, "$pod $self->{MAN3PODS}{$pod}\n";
1471         }
1472     }
1473     join('', @m);
1474 }
1475
1476 =item processPL (override)
1477
1478 Use VMS-style quoting on command line.
1479
1480 =cut
1481
1482 sub processPL {
1483     my($self) = @_;
1484     return "" unless $self->{PL_FILES};
1485     my(@m, $plfile);
1486     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
1487         my $vmsplfile = vmsify($plfile);
1488         my $vmsfile = vmsify($self->{PL_FILES}->{$plfile});
1489         push @m, "
1490 all :: $vmsfile
1491         \$(NOECHO) \$(NOOP)
1492
1493 $vmsfile :: $vmsplfile
1494 ",'     $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $vmsplfile
1495 ";
1496     }
1497     join "", @m;
1498 }
1499
1500 =item installbin (override)
1501
1502 Stay under DCL's 255 character command line limit once again by
1503 splitting potentially long list of files across multiple lines
1504 in C<realclean> target.
1505
1506 =cut
1507
1508 sub installbin {
1509     my($self) = @_;
1510     return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
1511     return '' unless @{$self->{EXE_FILES}};
1512     my(@m, $from, $to, %fromto, @to, $line);
1513     my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}};
1514     for $from (@exefiles) {
1515         my($path) = '$(INST_SCRIPT)' . basename($from);
1516         local($_) = $path;  # backward compatibility
1517         $to = $self->libscan($path);
1518         print "libscan($from) => '$to'\n" if ($Verbose >=2);
1519         $fromto{$from} = vmsify($to);
1520     }
1521     @to = values %fromto;
1522     push @m, "
1523 EXE_FILES = @exefiles
1524
1525 all :: @to
1526         \$(NOECHO) \$(NOOP)
1527
1528 realclean ::
1529 ";
1530     $line = '';  #avoid unitialized var warning
1531     foreach $to (@to) {
1532         if (length($line) + length($to) > 80) {
1533             push @m, "\t\$(RM_F) $line\n";
1534             $line = $to;
1535         }
1536         else { $line .= " $to"; }
1537     }
1538     push @m, "\t\$(RM_F) $line\n\n" if $line;
1539
1540     while (($from,$to) = each %fromto) {
1541         last unless defined $from;
1542         my $todir;
1543         if ($to =~ m#[/>:\]]#) { $todir = dirname($to); }
1544         else                   { ($todir = $to) =~ s/[^\)]+$//; }
1545         $todir = $self->fixpath($todir,1);
1546         push @m, "
1547 $to : $from \$(MAKEFILE) ${todir}.exists
1548         \$(CP) $from $to
1549
1550 ", $self->dir_target($todir);
1551     }
1552     join "", @m;
1553 }
1554
1555 =item subdir_x (override)
1556
1557 Use VMS commands to change default directory.
1558
1559 =cut
1560
1561 sub subdir_x {
1562     my($self, $subdir) = @_;
1563     my(@m,$key);
1564     $subdir = $self->fixpath($subdir,1);
1565     push @m, '
1566
1567 subdirs ::
1568         olddef = F$Environment("Default")
1569         Set Default ',$subdir,'
1570         - $(MMS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
1571         Set Default \'olddef\'
1572 ';
1573     join('',@m);
1574 }
1575
1576 =item clean (override)
1577
1578 Split potentially long list of files across multiple commands (in
1579 order to stay under the magic command line limit).  Also use MM[SK]
1580 commands for handling subdirectories.
1581
1582 =cut
1583
1584 sub clean {
1585     my($self, %attribs) = @_;
1586     my(@m,$dir);
1587     push @m, '
1588 # Delete temporary files but do not touch installed files. We don\'t delete
1589 # the Descrip.MMS here so that a later make realclean still has it to use.
1590 clean ::
1591 ';
1592     foreach $dir (@{$self->{DIR}}) { # clean subdirectories first
1593         my($vmsdir) = $self->fixpath($dir,1);
1594         push( @m, '     If F$Search("'.$vmsdir.'$(MAKEFILE)").nes."" Then \\',"\n\t",
1595               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n");
1596     }
1597     push @m, '  $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp
1598 ';
1599
1600     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
1601     # Unlink realclean, $attribs{FILES} is a string here; it may contain
1602     # a list or a macro that expands to a list.
1603     if ($attribs{FILES}) {
1604         my($word,$key,@filist);
1605         if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; }
1606         else { @filist = split /\s+/, $attribs{FILES}; }
1607         foreach $word (@filist) {
1608             if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') {
1609                 push(@otherfiles, @{$self->{$key}});
1610             }
1611             else { push(@otherfiles, $attribs{FILES}); }
1612         }
1613     }
1614     push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]);
1615     push(@otherfiles,$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
1616     my($file,$line);
1617     $line = '';  #avoid unitialized var warning
1618     foreach $file (@otherfiles) {
1619         $file = $self->fixpath($file);
1620         if (length($line) + length($file) > 80) {
1621             push @m, "\t\$(RM_RF) $line\n";
1622             $line = "$file";
1623         }
1624         else { $line .= " $file"; }
1625     }
1626     push @m, "\t\$(RM_RF) $line\n" if $line;
1627     push(@m, "  $attribs{POSTOP}\n") if $attribs{POSTOP};
1628     join('', @m);
1629 }
1630
1631 =item realclean (override)
1632
1633 Guess what we're working around?  Also, use MM[SK] for subdirectories.
1634
1635 =cut
1636
1637 sub realclean {
1638     my($self, %attribs) = @_;
1639     my(@m);
1640     push(@m,'
1641 # Delete temporary files (via clean) and also delete installed files
1642 realclean :: clean
1643 ');
1644     foreach(@{$self->{DIR}}){
1645         my($vmsdir) = $self->fixpath($_,1);
1646         push(@m, '      If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t",
1647               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) realclean`;"',"\n");
1648     }
1649     push @m,'   $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
1650 ';
1651     # We can't expand several of the MMS macros here, since they don't have
1652     # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
1653     # combination of macros).  In order to stay below DCL's 255 char limit,
1654     # we put only 2 on a line.
1655     my($file,$line,$fcnt);
1656     my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old };
1657     if ($self->has_link_code) {
1658         push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
1659     }
1660     push(@files, values %{$self->{PM}});
1661     $line = '';  #avoid unitialized var warning
1662     foreach $file (@files) {
1663         $file = $self->fixpath($file);
1664         if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
1665             push @m, "\t\$(RM_F) $line\n";
1666             $line = "$file";
1667             $fcnt = 0;
1668         }
1669         else { $line .= " $file"; }
1670     }
1671     push @m, "\t\$(RM_F) $line\n" if $line;
1672     if ($attribs{FILES}) {
1673         my($word,$key,@filist,@allfiles);
1674         if (ref $attribs{FILES} eq 'ARRAY') { @filist = @{$attribs{FILES}}; }
1675         else { @filist = split /\s+/, $attribs{FILES}; }
1676         foreach $word (@filist) {
1677             if (($key) = $word =~ m#^\$\((.*)\)$# and ref $self->{$key} eq 'ARRAY') {
1678                 push(@allfiles, @{$self->{$key}});
1679             }
1680             else { push(@allfiles, $attribs{FILES}); }
1681         }
1682         $line = '';
1683         foreach $file (@allfiles) {
1684             $file = $self->fixpath($file);
1685             if (length($line) + length($file) > 80) {
1686                 push @m, "\t\$(RM_RF) $line\n";
1687                 $line = "$file";
1688             }
1689             else { $line .= " $file"; }
1690         }
1691         push @m, "\t\$(RM_RF) $line\n" if $line;
1692     }
1693     push(@m, "  $attribs{POSTOP}\n")                     if $attribs{POSTOP};
1694     join('', @m);
1695 }
1696
1697 =item dist_basics (override)
1698
1699 Use VMS-style quoting on command line.
1700
1701 =cut
1702
1703 sub dist_basics {
1704     my($self) = @_;
1705 '
1706 distclean :: realclean distcheck
1707         $(NOECHO) $(NOOP)
1708
1709 distcheck :
1710         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()"
1711
1712 skipcheck :
1713         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&skipcheck\'; skipcheck()"
1714
1715 manifest :
1716         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&mkmanifest\'; mkmanifest()"
1717 ';
1718 }
1719
1720 =item dist_core (override)
1721
1722 Syntax for invoking F<VMS_Share> differs from that for Unix F<shar>,
1723 so C<shdist> target actions are VMS-specific.
1724
1725 =cut
1726
1727 sub dist_core {
1728     my($self) = @_;
1729 q[
1730 dist : $(DIST_DEFAULT)
1731         $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'"
1732
1733 zipdist : $(DISTVNAME).zip
1734         $(NOECHO) $(NOOP)
1735
1736 $(DISTVNAME).zip : distdir
1737         $(PREOP)
1738         $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) $(SRC)
1739         $(RM_RF) $(DISTVNAME)
1740         $(POSTOP)
1741
1742 $(DISTVNAME).tar$(SUFFIX) : distdir
1743         $(PREOP)
1744         $(TO_UNIX)
1745         $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar $(SRC)
1746         $(RM_RF) $(DISTVNAME)
1747         $(COMPRESS) $(DISTVNAME).tar
1748         $(POSTOP)
1749
1750 shdist : distdir
1751         $(PREOP)
1752         $(SHARE) $(SRC) $(DISTVNAME).share
1753         $(RM_RF) $(DISTVNAME)
1754         $(POSTOP)
1755 ];
1756 }
1757
1758 =item dist_dir (override)
1759
1760 Use VMS-style quoting on command line.
1761
1762 =cut
1763
1764 sub dist_dir {
1765     my($self) = @_;
1766 q{
1767 distdir :
1768         $(RM_RF) $(DISTVNAME)
1769         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest '/mani/';" \\
1770         -e "manicopy(maniread(),'$(DISTVNAME)','$(DIST_CP)');"
1771 };
1772 }
1773
1774 =item dist_test (override)
1775
1776 Use VMS commands to change default directory, and use VMS-style
1777 quoting on command line.
1778
1779 =cut
1780
1781 sub dist_test {
1782     my($self) = @_;
1783 q{
1784 disttest : distdir
1785         startdir = F$Environment("Default")
1786         Set Default [.$(DISTVNAME)]
1787         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL
1788         $(MMS)
1789         $(MMS) test
1790         Set Default 'startdir'
1791 };
1792 }
1793
1794 # --- Test and Installation Sections ---
1795
1796 =item install (override)
1797
1798 Work around DCL's 255 character limit several times,and use
1799 VMS-style command line quoting in a few cases.
1800
1801 =cut
1802
1803 sub install {
1804     my($self, %attribs) = @_;
1805     my(@m,@docfiles);
1806
1807     if ($self->{EXE_FILES}) {
1808         my($line,$file) = ('','');
1809         foreach $file (@{$self->{EXE_FILES}}) {
1810             $line .= "$file ";
1811             if (length($line) > 128) {
1812                 push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]);
1813                 $line = '';
1814             }
1815         }
1816         push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]) if $line;
1817     }
1818
1819     push @m, q[
1820 install :: all pure_install doc_install
1821         $(NOECHO) $(NOOP)
1822
1823 install_perl :: all pure_perl_install doc_perl_install
1824         $(NOECHO) $(NOOP)
1825
1826 install_site :: all pure_site_install doc_site_install
1827         $(NOECHO) $(NOOP)
1828
1829 install_ :: install_site
1830         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1831
1832 pure_install :: pure_$(INSTALLDIRS)_install
1833         $(NOECHO) $(NOOP)
1834
1835 doc_install :: doc_$(INSTALLDIRS)_install
1836         $(NOECHO) $(SAY) "Appending installation info to $(INSTALLARCHLIB)perllocal.pod"
1837
1838 pure__install : pure_site_install
1839         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1840
1841 doc__install : doc_site_install
1842         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1843
1844 # This hack brought to you by DCL's 255-character command line limit
1845 pure_perl_install ::
1846         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1847         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1848         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp
1849         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp
1850         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1851         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1852         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1853         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1854         $(MOD_INSTALL) <.MM_tmp
1855         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1856         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[
1857
1858 # Likewise
1859 pure_site_install ::
1860         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1861         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1862         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp
1863         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp
1864         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1865         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1866         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1867         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1868         $(MOD_INSTALL) <.MM_tmp
1869         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1870         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1871
1872 # Ditto
1873 doc_perl_install ::
1874         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp
1875         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1876         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1877 ],@docfiles,
1878 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1879         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1880         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1881         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1882         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1883         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1884
1885 # And again
1886 doc_site_install ::
1887         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp
1888         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1889         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1890 ],@docfiles,
1891 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1892         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1893         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1894         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1895         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1896         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1897
1898 ];
1899
1900     push @m, q[
1901 uninstall :: uninstall_from_$(INSTALLDIRS)dirs
1902         $(NOECHO) $(NOOP)
1903
1904 uninstall_from_perldirs ::
1905         $(NOECHO) $(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1906         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1907         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1908         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1909
1910 uninstall_from_sitedirs ::
1911         $(NOECHO) $(UNINSTALL) ],$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist'),"\n",q[
1912         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1913         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1914         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1915 ];
1916
1917     join('',@m);
1918 }
1919
1920 =item perldepend (override)
1921
1922 Use VMS-style syntax for files; it's cheaper to just do it directly here
1923 than to have the MM_Unix method call C<catfile> repeatedly.  Also use
1924 config.vms as source of original config data if the Perl distribution
1925 is available; config.sh is an ancillary file under VMS.  Finally, if
1926 we have to rebuild Config.pm, use MM[SK] to do it.
1927
1928 =cut
1929
1930 sub perldepend {
1931     my($self) = @_;
1932     my(@m);
1933
1934     push @m, '
1935 $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
1936 $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
1937 $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
1938 $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
1939 $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
1940 $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
1941 $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
1942
1943 ' if $self->{OBJECT}; 
1944
1945     if ($self->{PERL_SRC}) {
1946         my(@macros);
1947         my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)';
1948         push(@macros,'__AXP__=1') if $Config{'arch'} eq 'VMS_AXP';
1949         push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
1950         push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
1951         push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
1952         push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
1953         $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1954         push(@m,q[
1955 # Check for unpropagated config.sh changes. Should never happen.
1956 # We do NOT just update config.h because that is not sufficient.
1957 # An out of date config.h is not fatal but complains loudly!
1958 #$(PERL_INC)config.h : $(PERL_SRC)config.sh
1959 $(PERL_INC)config.h : $(PERL_VMS)config.vms
1960         $(NOECHO) Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms"
1961
1962 #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1963 $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl
1964         $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl"
1965         olddef = F$Environment("Default")
1966         Set Default $(PERL_SRC)
1967         $(MMS)],$mmsquals,q[ $(MMS$TARGET)
1968         Set Default 'olddef'
1969 ]);
1970     }
1971
1972     push(@m, join(" ", map($self->fixpath($_),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1973       if %{$self->{XS}};
1974
1975     join('',@m);
1976 }
1977
1978 =item makefile (override)
1979
1980 Use VMS commands and quoting.
1981
1982 =cut
1983
1984 sub makefile {
1985     my($self) = @_;
1986     my(@m,@cmd);
1987     # We do not know what target was originally specified so we
1988     # must force a manual rerun to be sure. But as it should only
1989     # happen very rarely it is not a significant problem.
1990     push @m, q[
1991 $(OBJECT) : $(FIRST_MAKEFILE)
1992 ] if $self->{OBJECT};
1993
1994     push @m,q[
1995 # We take a very conservative approach here, but it\'s worth it.
1996 # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
1997 $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
1998         $(NOECHO) $(SAY) "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
1999         $(NOECHO) $(SAY) "Cleaning current config before rebuilding $(MAKEFILE) ..."
2000         - $(MV) $(MAKEFILE) $(MAKEFILE)_old
2001         - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean
2002         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
2003         $(NOECHO) $(SAY) "$(MAKEFILE) has been rebuilt."
2004         $(NOECHO) $(SAY) "Please run $(MMS) to build the extension."
2005 ];
2006
2007     join('',@m);
2008 }
2009
2010 =item test (override)
2011
2012 Use VMS commands for handling subdirectories.
2013
2014 =cut
2015
2016 sub test {
2017     my($self, %attribs) = @_;
2018     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
2019     my(@m);
2020     push @m,"
2021 TEST_VERBOSE = 0
2022 TEST_TYPE = test_\$(LINKTYPE)
2023 TEST_FILE = test.pl
2024 TESTDB_SW = -d
2025
2026 test :: \$(TEST_TYPE)
2027         \$(NOECHO) \$(NOOP)
2028
2029 testdb :: testdb_\$(LINKTYPE)
2030         \$(NOECHO) \$(NOOP)
2031
2032 ";
2033     foreach(@{$self->{DIR}}){
2034       my($vmsdir) = $self->fixpath($_,1);
2035       push(@m, '        If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
2036            '; print `$(MMS) $(PASTHRU2) test`'."\n");
2037     }
2038     push(@m, "\t\$(NOECHO) \$(SAY) \"No tests defined for \$(NAME) extension.\"\n")
2039         unless $tests or -f "test.pl" or @{$self->{DIR}};
2040     push(@m, "\n");
2041
2042     push(@m, "test_dynamic :: pure_all\n");
2043     push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests;
2044     push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl";
2045     push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl");
2046     push(@m, "\n");
2047
2048     push(@m, "testdb_dynamic :: pure_all\n");
2049     push(@m, $self->test_via_script('$(FULLPERL) "$(TESTDB_SW)"', '$(TEST_FILE)'));
2050     push(@m, "\n");
2051
2052     # Occasionally we may face this degenerate target:
2053     push @m, "test_ : test_dynamic\n\n";
2054  
2055     if ($self->needs_linking()) {
2056         push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
2057         push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
2058         push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
2059         push(@m, "\n");
2060         push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
2061         push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
2062         push(@m, "\n");
2063     }
2064     else {
2065         push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n";
2066         push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n";
2067     }
2068
2069     join('',@m);
2070 }
2071
2072 =item test_via_harness (override)
2073
2074 Use VMS-style quoting on command line.
2075
2076 =cut
2077
2078 sub test_via_harness {
2079     my($self,$perl,$tests) = @_;
2080     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\'."\n\t".
2081     '-e "use Test::Harness qw(&runtests $verbose); $verbose=$(TEST_VERBOSE); runtests @ARGV;" \\'."\n\t$tests\n";
2082 }
2083
2084 =item test_via_script (override)
2085
2086 Use VMS-style quoting on command line.
2087
2088 =cut
2089
2090 sub test_via_script {
2091     my($self,$perl,$script) = @_;
2092     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '.$script.'
2093 ';
2094 }
2095
2096 =item makeaperl (override)
2097
2098 Undertake to build a new set of Perl images using VMS commands.  Since
2099 VMS does dynamic loading, it's not necessary to statically link each
2100 extension into the Perl image, so this isn't the normal build path.
2101 Consequently, it hasn't really been tested, and may well be incomplete.
2102
2103 =cut
2104
2105 sub makeaperl {
2106     my($self, %attribs) = @_;
2107     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
2108       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
2109     my(@m);
2110     push @m, "
2111 # --- MakeMaker makeaperl section ---
2112 MAP_TARGET    = $target
2113 ";
2114     return join '', @m if $self->{PARENT};
2115
2116     my($dir) = join ":", @{$self->{DIR}};
2117
2118     unless ($self->{MAKEAPERL}) {
2119         push @m, q{
2120 $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
2121         $(NOECHO) $(SAY) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
2122         $(NOECHO) $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
2123                 Makefile.PL DIR=}, $dir, q{ \
2124                 MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
2125                 MAKEAPERL=1 NORECURS=1
2126
2127 $(MAP_TARGET) :: $(MAKE_APERL_FILE)
2128         $(MMS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
2129 };
2130         push @m, map( " \\\n\t\t$_", @ARGV );
2131         push @m, "\n";
2132
2133         return join '', @m;
2134     }
2135
2136
2137     my($linkcmd,@staticopts,@staticpkgs,$extralist,$targdir,$libperldir);
2138
2139     # The front matter of the linkcommand...
2140     $linkcmd = join ' ', $Config{'ld'},
2141             grep($_, @Config{qw(large split ldflags ccdlflags)});
2142     $linkcmd =~ s/\s+/ /g;
2143
2144     # Which *.olb files could we make use of...
2145     local(%olbs);
2146     $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
2147     require File::Find;
2148     File::Find::find(sub {
2149         return unless m/\Q$self->{LIB_EXT}\E$/;
2150         return if m/^libperl/;
2151
2152         if( exists $self->{INCLUDE_EXT} ){
2153                 my $found = 0;
2154                 my $incl;
2155                 my $xx;
2156
2157                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2158                 $xx =~ s,/?$_,,;
2159                 $xx =~ s,/,::,g;
2160
2161                 # Throw away anything not explicitly marked for inclusion.
2162                 # DynaLoader is implied.
2163                 foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
2164                         if( $xx eq $incl ){
2165                                 $found++;
2166                                 last;
2167                         }
2168                 }
2169                 return unless $found;
2170         }
2171         elsif( exists $self->{EXCLUDE_EXT} ){
2172                 my $excl;
2173                 my $xx;
2174
2175                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2176                 $xx =~ s,/?$_,,;
2177                 $xx =~ s,/,::,g;
2178
2179                 # Throw away anything explicitly marked for exclusion
2180                 foreach $excl (@{$self->{EXCLUDE_EXT}}){
2181                         return if( $xx eq $excl );
2182                 }
2183         }
2184
2185         $olbs{$ENV{DEFAULT}} = $_;
2186     }, grep( -d $_, @{$searchdirs || []}));
2187
2188     # We trust that what has been handed in as argument will be buildable
2189     $static = [] unless $static;
2190     @olbs{@{$static}} = (1) x @{$static};
2191  
2192     $extra = [] unless $extra && ref $extra eq 'ARRAY';
2193     # Sort the object libraries in inverse order of
2194     # filespec length to try to insure that dependent extensions
2195     # will appear before their parents, so the linker will
2196     # search the parent library to resolve references.
2197     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
2198     # references from [.intuit.dwim]dwim.obj can be found
2199     # in [.intuit]intuit.olb).
2200     for (sort keys %olbs) {
2201         next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
2202         my($dir) = $self->fixpath($_,1);
2203         my($extralibs) = $dir . "extralibs.ld";
2204         my($extopt) = $dir . $olbs{$_};
2205         $extopt =~ s/$self->{LIB_EXT}$/.opt/;
2206         if (-f $extralibs ) {
2207             open LIST,$extralibs or warn $!,next;
2208             push @$extra, <LIST>;
2209             close LIST;
2210         }
2211         if (-f $extopt) {
2212             open OPT,$extopt or die $!;
2213             while (<OPT>) {
2214                 next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
2215                 # ExtUtils::Miniperl expects Unix paths
2216                 (my($pkg) = "$1_$1$self->{LIB_EXT}") =~ s#_*#/#g;
2217                 push @staticpkgs,$pkg;
2218             }
2219             push @staticopts, $extopt;
2220         }
2221     }
2222
2223     $target = "Perl.Exe" unless $target;
2224     ($shrtarget,$targdir) = fileparse($target);
2225     $shrtarget =~ s/^([^.]*)/$1Shr/;
2226     $shrtarget = $targdir . $shrtarget;
2227     $target = "Perlshr.$Config{'dlext'}" unless $target;
2228     $tmp = "[]" unless $tmp;
2229     $tmp = $self->fixpath($tmp,1);
2230     if (@$extra) {
2231         $extralist = join(' ',@$extra);
2232         $extralist =~ s/[,\s\n]+/, /g;
2233     }
2234     else { $extralist = ''; }
2235     if ($libperl) {
2236         unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
2237             print STDOUT "Warning: $libperl not found\n";
2238             undef $libperl;
2239         }
2240     }
2241     unless ($libperl) {
2242         if (defined $self->{PERL_SRC}) {
2243             $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
2244         } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
2245         } else {
2246             print STDOUT "Warning: $libperl not found
2247     If you're going to build a static perl binary, make sure perl is installed
2248     otherwise ignore this warning\n";
2249         }
2250     }
2251     $libperldir = $self->fixpath((fileparse($libperl))[1],1);
2252
2253     push @m, '
2254 # Fill in the target you want to produce if it\'s not perl
2255 MAP_TARGET    = ',$self->fixpath($target),'
2256 MAP_SHRTARGET = ',$self->fixpath($shrtarget),"
2257 MAP_LINKCMD   = $linkcmd
2258 MAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '','
2259 # We use the linker options files created with each extension, rather than
2260 #specifying the object files directly on the command line.
2261 MAP_STATIC    = ',@staticopts ? join(' ', @staticopts) : '','
2262 MAP_OPTS    = ',@staticopts ? ','.join(',', map($_.'/Option', @staticopts)) : '',"
2263 MAP_EXTRA     = $extralist
2264 MAP_LIBPERL = ",$self->fixpath($libperl),'
2265 ';
2266
2267
2268     push @m,'
2269 $(MAP_SHRTARGET) : $(MAP_LIBPERL) $(MAP_STATIC) ',"${libperldir}Perlshr_Attr.Opt",'
2270         $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",'
2271 $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",'
2272         $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
2273         $(NOECHO) $(SAY) "To install the new ""$(MAP_TARGET)"" binary, say"
2274         $(NOECHO) $(SAY) "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
2275         $(NOECHO) $(SAY) "To remove the intermediate files, say
2276         $(NOECHO) $(SAY) "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
2277 ';
2278     push @m,'
2279 ',"${tmp}perlmain.c",' : $(MAKEFILE)
2280         $(NOECHO) $(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET)
2281 ';
2282
2283     push @m, q[
2284 # More from the 255-char line length limit
2285 doc_inst_perl :
2286         $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp
2287         $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp
2288         $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
2289         $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp
2290         $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
2291         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
2292 ];
2293
2294     push @m, "
2295 inst_perl : pure_inst_perl doc_inst_perl
2296         \$(NOECHO) \$(NOOP)
2297
2298 pure_inst_perl : \$(MAP_TARGET)
2299         $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
2300         $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
2301
2302 clean :: map_clean
2303         \$(NOECHO) \$(NOOP)
2304
2305 map_clean :
2306         \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE)
2307         \$(RM_F) ${tmp}PerlShr.Opt \$(MAP_TARGET)
2308 ";
2309
2310     join '', @m;
2311 }
2312   
2313 # --- Output postprocessing section ---
2314
2315 =item nicetext (override)
2316
2317 Insure that colons marking targets are preceded by space, in order
2318 to distinguish the target delimiter from a colon appearing as
2319 part of a filespec.
2320
2321 =cut
2322
2323 sub nicetext {
2324
2325     my($self,$text) = @_;
2326     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
2327     $text;
2328 }
2329
2330 1;
2331
2332 __END__
2333