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