13383e9411bd000e1221728dc53fef976a99d461
[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.38 (19-Nov-1996)';
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             $def =~ s/^-D//;
593             $def = "\"$def\"" if $def =~ /=/;
594         }
595         $self->{DEFINE} = join ',',@defs;
596     }
597
598     if ($self->{OBJECT} =~ /\s/) {
599         $self->{OBJECT} =~ s/(\\)?\n+\s+/ /g;
600         $self->{OBJECT} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{OBJECT})));
601     }
602     $self->{LDFROM} = join(' ',map($self->fixpath($_),split(/,?\s+/,$self->{LDFROM})));
603
604
605     # Fix up directory specs
606     $self->{ROOTEXT} = $self->{ROOTEXT} ? $self->fixpath($self->{ROOTEXT},1)
607                                         : '[]';
608     foreach $macro ( qw [
609             INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB INST_EXE INSTALLPRIVLIB
610             INSTALLARCHLIB INSTALLSCRIPT INSTALLBIN PERL_LIB PERL_ARCHLIB
611             PERL_INC PERL_SRC FULLEXT INST_MAN1DIR INSTALLMAN1DIR
612             INST_MAN3DIR INSTALLMAN3DIR INSTALLSITELIB INSTALLSITEARCH
613             SITELIBEXP SITEARCHEXP ] ) {
614         next unless defined $self->{$macro};
615         $self->{$macro} = $self->fixpath($self->{$macro},1);
616     }
617     $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC},q(VMS))
618         if ($self->{PERL_SRC});
619                         
620
621
622     # Fix up file specs
623     foreach $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKE_APERL_FILE MYEXTLIB] ) {
624         next unless defined $self->{$macro};
625         $self->{$macro} = $self->fixpath($self->{$macro});
626     }
627
628     foreach $macro (qw/
629               AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION
630               INST_BIN INST_EXE INST_LIB INST_ARCHLIB INST_SCRIPT PREFIX
631               INSTALLDIRS INSTALLPRIVLIB  INSTALLARCHLIB INSTALLSITELIB
632               INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB
633               PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB
634               FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC PERL_VMS
635               PERL_INC PERL FULLPERL
636               / ) {
637         next unless defined $self->{$macro};
638         push @m, "$macro = $self->{$macro}\n";
639     }
640
641
642     push @m, q[
643 VERSION_MACRO = VERSION
644 DEFINE_VERSION = "$(VERSION_MACRO)=""$(VERSION)"""
645 XS_VERSION_MACRO = XS_VERSION
646 XS_DEFINE_VERSION = "$(XS_VERSION_MACRO)=""$(XS_VERSION)"""
647
648 MAKEMAKER = ],$self->catfile($self->{PERL_LIB},'ExtUtils','MakeMaker.pm'),qq[
649 MM_VERSION = $ExtUtils::MakeMaker::VERSION
650 MM_REVISION = $ExtUtils::MakeMaker::Revision
651 MM_VMS_REVISION = $ExtUtils::MM_VMS::Revision
652
653 # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
654 # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
655 # PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
656 # DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
657 ];
658
659     for $tmp (qw/
660               FULLEXT VERSION_FROM OBJECT LDFROM
661               / ) {
662         next unless defined $self->{$tmp};
663         push @m, "$tmp = ",$self->fixpath($self->{$tmp}),"\n";
664     }
665
666     for $tmp (qw/
667               BASEEXT PARENT_NAME DLBASE INC DEFINE LINKTYPE
668               / ) {
669         next unless defined $self->{$tmp};
670         push @m, "$tmp = $self->{$tmp}\n";
671     }
672
673     for $tmp (qw/ XS MAN1PODS MAN3PODS PM /) {
674         next unless defined $self->{$tmp};
675         my(%tmp,$key);
676         for $key (keys %{$self->{$tmp}}) {
677             $tmp{$self->fixpath($key)} = $self->fixpath($self->{$tmp}{$key});
678         }
679         $self->{$tmp} = \%tmp;
680     }
681
682     for $tmp (qw/ C O_FILES H /) {
683         next unless defined $self->{$tmp};
684         my(@tmp,$val);
685         for $val (@{$self->{$tmp}}) {
686             push(@tmp,$self->fixpath($val));
687         }
688         $self->{$tmp} = \@tmp;
689     }
690
691     push @m,'
692
693 # Handy lists of source code files:
694 XS_FILES = ',$self->wraplist(', ', sort keys %{$self->{XS}}),'
695 C_FILES  = ',$self->wraplist(', ', @{$self->{C}}),'
696 O_FILES  = ',$self->wraplist(', ', @{$self->{O_FILES}} ),'
697 H_FILES  = ',$self->wraplist(', ', @{$self->{H}}),'
698 MAN1PODS = ',$self->wraplist(', ', sort keys %{$self->{MAN1PODS}}),'
699 MAN3PODS = ',$self->wraplist(', ', sort keys %{$self->{MAN3PODS}}),'
700
701 ';
702
703     for $tmp (qw/
704               INST_MAN1DIR INSTALLMAN1DIR MAN1EXT INST_MAN3DIR INSTALLMAN3DIR MAN3EXT
705               /) {
706         next unless defined $self->{$tmp};
707         push @m, "$tmp = $self->{$tmp}\n";
708     }
709
710 push @m,"
711 .SUFFIXES : \$(OBJ_EXT) .c .cpp .cxx .xs
712
713 # Here is the Config.pm that we are using/depend on
714 CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h \$(VERSION_FROM)
715
716 # Where to put things:
717 INST_LIBDIR      = $self->{INST_LIBDIR}
718 INST_ARCHLIBDIR  = $self->{INST_ARCHLIBDIR}
719
720 INST_AUTODIR     = $self->{INST_AUTODIR}
721 INST_ARCHAUTODIR = $self->{INST_ARCHAUTODIR}
722 ";
723
724     if ($self->has_link_code()) {
725         push @m,'
726 INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT)$(LIB_EXT)
727 INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
728 INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
729 ';
730     } else {
731         push @m,'
732 INST_STATIC =
733 INST_DYNAMIC =
734 INST_BOOT =
735 EXPORT_LIST = $(BASEEXT).opt
736 PERL_ARCHIVE = ',($ENV{'PERLSHR'} ? $ENV{'PERLSHR'} : 'Sys$Share:PerlShr.Exe'),'
737 ';
738     }
739
740     $self->{TO_INST_PM} = [ sort keys %{$self->{PM}} ];
741     $self->{PM_TO_BLIB} = [ %{$self->{PM}} ];
742     push @m,'
743 TO_INST_PM = ',$self->wraplist(', ',@{$self->{TO_INST_PM}}),'
744
745 PM_TO_BLIB = ',$self->wraplist(', ',@{$self->{PM_TO_BLIB}}),'
746 ';
747
748     join('',@m);
749 }
750
751 =item cflags (override)
752
753 Bypass shell script and produce qualifiers for CC directly (but warn
754 user if a shell script for this extension exists).  Fold multiple
755 /Defines into one, since some C compilers pay attention to only one
756 instance of this qualifier on the command line.
757
758 =cut
759
760 sub cflags {
761     my($self,$libperl) = @_;
762     my($quals) = $Config{'ccflags'};
763     my($name,$sys,@m);
764     my($optimize) = '/Optimize';
765
766     ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
767     print STDOUT "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
768          " required to modify CC command for $self->{'BASEEXT'}\n"
769     if ($Config{$name});
770
771     # Deal with $self->{DEFINE} here since some C compilers pay attention
772     # to only one /Define clause on command line, so we have to
773     # conflate the ones from $Config{'cc'} and $self->{DEFINE}
774     if ($quals =~ m:(.*)/define=\(?([^\(\/\)\s]+)\)?(.*)?:i) {
775         $quals = "$1/Define=($2," . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
776                  "\$(DEFINE_VERSION),\$(XS_DEFINE_VERSION))$3";
777     }
778     else {
779         $quals .= '/Define=(' . ($self->{DEFINE} ? "$self->{DEFINE}," : '') .
780                   '$(DEFINE_VERSION),$(XS_DEFINE_VERSION))';
781     }
782
783     $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
784     if ($libperl =~ /libperl(\w+)\./i) {
785         my($type) = uc $1;
786         my(%map) = ( 'D'  => 'DEBUGGING', 'E' => 'EMBED', 'M' => 'MULTIPLICITY',
787                      'DE' => 'DEBUGGING,EMBED', 'DM' => 'DEBUGGING,MULTIPLICITY',
788                      'EM' => 'EMBED,MULTIPLICITY', 'DEM' => 'DEBUGGING,EMBED,MULTIPLICITY' );
789         $quals =~ s:/define=\(([^\)]+)\):/Define=($1,$map{$type}):i
790     }
791
792     # Likewise with $self->{INC} and /Include
793     my($incstr) = '/Include=($(PERL_INC)';
794     if ($self->{'INC'}) {
795         my(@includes) = split(/\s+/,$self->{INC});
796         foreach (@includes) {
797             s/^-I//;
798             $incstr .= ', '.$self->fixpath($_,1);
799         }
800     }
801     $quals .= "$incstr)";
802
803     $optimize = '/Debug/NoOptimize'
804         if ($self->{OPTIMIZE} =~ /-g/ or $self->{OPTIMIZE} =~ m!/Debug!i);
805
806     return $self->{CFLAGS} = qq{
807 CCFLAGS = $quals
808 OPTIMIZE = $optimize
809 PERLTYPE =
810 SPLIT =
811 LARGE =
812 };
813 }
814
815 =item const_cccmd (override)
816
817 Adds directives to point C preprocessor to the right place when
818 handling #include E<lt>sys/foo.hE<gt> directives.  Also constructs CC
819 command line a bit differently than MM_Unix method.
820
821 =cut
822
823 sub const_cccmd {
824     my($self,$libperl) = @_;
825     my(@m);
826
827     return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
828     return '' unless $self->needs_linking();
829     if ($Config{'vms_cc_type'} eq 'gcc') {
830         push @m,'
831 .FIRST
832         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
833     }
834     elsif ($Config{'vms_cc_type'} eq 'vaxc') {
835         push @m,'
836 .FIRST
837         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
838         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
839     }
840     else {
841         push @m,'
842 .FIRST
843         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
844                 ($Config{'arch'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
845         ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
846     }
847
848     push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
849
850     $self->{CONST_CCCMD} = join('',@m);
851 }
852
853 =item pm_to_blib (override)
854
855 DCL I<still> accepts a maximum of 255 characters on a command
856 line, so we write the (potentially) long list of file names
857 to a temp file, then persuade Perl to read it instead of the
858 command line to find args.
859
860 =cut
861
862 sub pm_to_blib {
863     my($self) = @_;
864     my($line,$from,$to,@m);
865     my($autodir) = $self->catdir('$(INST_LIB)','auto');
866     my(@files) = @{$self->{PM_TO_BLIB}};
867
868     push @m, q{
869
870 # Dummy target to match Unix target name; we use pm_to_blib.ts as
871 # timestamp file to avoid repeated invocations under VMS
872 pm_to_blib : pm_to_blib.ts
873         $(NOECHO) $(NOOP)
874
875 # As always, keep under DCL's 255-char limit
876 pm_to_blib.ts : $(TO_INST_PM)
877         $(NOECHO) $(PERL) -e "print '},shift(@files),q{ },shift(@files),q{'" >.MM_tmp
878 };
879
880     $line = '';  # avoid uninitialized var warning
881     while ($from = shift(@files),$to = shift(@files)) {
882         $line .= " $from $to";
883         if (length($line) > 128) {
884             push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n");
885             $line = '';
886         }
887     }
888     push(@m,"\t\$(NOECHO) \$(PERL) -e \"print '$line'\" >>.MM_tmp\n") if $line;
889
890     push(@m,q[  $(PERL) "-I$(PERL_LIB)" "-MExtUtils::Install" -e "pm_to_blib({split(' ',<STDIN>)},'].$autodir.q[')" <.MM_tmp]);
891     push(@m,qq[
892         \$(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
893         \$(NOECHO) \$(TOUCH) pm_to_blib.ts
894 ]);
895
896     join('',@m);
897 }
898
899 =item tool_autosplit (override)
900
901 Use VMS-style quoting on command line.
902
903 =cut
904
905 sub tool_autosplit{
906     my($self, %attribs) = @_;
907     my($asl) = "";
908     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
909     q{
910 # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
911 AUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
912 };
913 }
914
915 =item tool_sxubpp (override)
916
917 Use VMS-style quoting on xsubpp command line.
918
919 =cut
920
921 sub tool_xsubpp {
922     my($self) = @_;
923     return '' unless $self->needs_linking;
924     my($xsdir) = $self->catdir($self->{PERL_LIB},'ExtUtils');
925     # drop back to old location if xsubpp is not in new location yet
926     $xsdir = $self->catdir($self->{PERL_SRC},'ext') unless (-f $self->catfile($xsdir,'xsubpp'));
927     my(@tmdeps) = '$(XSUBPPDIR)typemap';
928     if( $self->{TYPEMAPS} ){
929         my $typemap;
930         foreach $typemap (@{$self->{TYPEMAPS}}){
931                 if( ! -f  $typemap ){
932                         warn "Typemap $typemap not found.\n";
933                 }
934                 else{
935                         push(@tmdeps, $self->fixpath($typemap));
936                 }
937         }
938     }
939     push(@tmdeps, "typemap") if -f "typemap";
940     my(@tmargs) = map("-typemap $_", @tmdeps);
941     if( exists $self->{XSOPT} ){
942         unshift( @tmargs, $self->{XSOPT} );
943     }
944
945     my $xsubpp_version = $self->xsubpp_version($self->catfile($xsdir,'xsubpp'));
946
947     # What are the correct thresholds for version 1 && 2 Paul?
948     if ( $xsubpp_version > 1.923 ){
949         $self->{XSPROTOARG} = '' unless defined $self->{XSPROTOARG};
950     } else {
951         if (defined $self->{XSPROTOARG} && $self->{XSPROTOARG} =~ /\-prototypes/) {
952             print STDOUT qq{Warning: This extension wants to pass the switch "-prototypes" to xsubpp.
953         Your version of xsubpp is $xsubpp_version and cannot handle this.
954         Please upgrade to a more recent version of xsubpp.
955 };
956         } else {
957             $self->{XSPROTOARG} = "";
958         }
959     }
960
961     "
962 XSUBPPDIR = $xsdir
963 XSUBPP = \$(PERL) \"-I\$(PERL_ARCHLIB)\" \"-I\$(PERL_LIB)\" \$(XSUBPPDIR)xsubpp
964 XSPROTOARG = $self->{XSPROTOARG}
965 XSUBPPDEPS = @tmdeps
966 XSUBPPARGS = @tmargs
967 ";
968 }
969
970 =item xsubpp_version (override)
971
972 Test xsubpp exit status according to VMS rules ($sts & 1 ==E<gt> good)
973 rather than Unix rules ($sts == 0 ==E<gt> good).
974
975 =cut
976
977 sub xsubpp_version
978 {
979     my($self,$xsubpp) = @_;
980     my ($version) ;
981     return '' unless $self->needs_linking;
982
983     # try to figure out the version number of the xsubpp on the system
984
985     # first try the -v flag, introduced in 1.921 & 2.000a2
986
987     my $command = "$self->{PERL} \"-I$self->{PERL_LIB}\" $xsubpp -v";
988     print "Running: $command\n" if $Verbose;
989     $version = `$command` ;
990     warn "Running '$command' exits with status " . $? unless ($? & 1);
991     chop $version ;
992
993     return $1 if $version =~ /^xsubpp version (.*)/ ;
994
995     # nope, then try something else
996
997     my $counter = '000';
998     my ($file) = 'temp' ;
999     $counter++ while -e "$file$counter"; # don't overwrite anything
1000     $file .= $counter;
1001
1002     local(*F);
1003     open(F, ">$file") or die "Cannot open file '$file': $!\n" ;
1004     print F <<EOM ;
1005 MODULE = fred PACKAGE = fred
1006
1007 int
1008 fred(a)
1009         int     a;
1010 EOM
1011
1012     close F ;
1013
1014     $command = "$self->{PERL} $xsubpp $file";
1015     print "Running: $command\n" if $Verbose;
1016     my $text = `$command` ;
1017     warn "Running '$command' exits with status " . $? unless ($? & 1);
1018     unlink $file ;
1019
1020     # gets 1.2 -> 1.92 and 2.000a1
1021     return $1 if $text =~ /automatically by xsubpp version ([\S]+)\s*/  ;
1022
1023     # it is either 1.0 or 1.1
1024     return 1.1 if $text =~ /^Warning: ignored semicolon/ ;
1025
1026     # none of the above, so 1.0
1027     return "1.0" ;
1028 }
1029
1030 =item tools_other (override)
1031
1032 Adds a few MM[SK] macros, and shortens some the installatin commands,
1033 in order to stay under DCL's 255-character limit.  Also changes
1034 EQUALIZE_TIMESTAMP to set revision date of target file to one second
1035 later than source file, since MMK interprets precisely equal revision
1036 dates for a source and target file as a sign that the target needs
1037 to be updated.
1038
1039 =cut
1040
1041 sub tools_other {
1042     my($self) = @_;
1043     qq!
1044 # Assumes \$(MMS) invokes MMS or MMK
1045 # (It is assumed in some cases later that the default makefile name
1046 # (Descrip.MMS for MM[SK]) is used.)
1047 USEMAKEFILE = /Descrip=
1048 USEMACROS = /Macro=(
1049 MACROEND = )
1050 MAKEFILE = Descrip.MMS
1051 SHELL = Posix
1052 TOUCH = $self->{TOUCH}
1053 CHMOD = $self->{CHMOD}
1054 CP = $self->{CP}
1055 MV = $self->{MV}
1056 RM_F  = $self->{RM_F}
1057 RM_RF = $self->{RM_RF}
1058 UMASK_NULL = $self->{UMASK_NULL}
1059 NOOP = $self->{NOOP}
1060 NOECHO = $self->{NOECHO}
1061 MKPATH = Create/Directory
1062 EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])"
1063 !. ($self->{PARENT} ? '' : 
1064 qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}"
1065 MOD_INSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "install({split(' ',<STDIN>)},1);"
1066 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]"
1067 UNINSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1);"
1068 !);
1069 }
1070
1071 =item dist (override)
1072
1073 Provide VMSish defaults for some values, then hand off to
1074 default MM_Unix method.
1075
1076 =cut
1077
1078 sub dist {
1079     my($self, %attribs) = @_;
1080     $attribs{VERSION}      ||= $self->{VERSION_SYM};
1081     $attribs{ZIPFLAGS}     ||= '-Vu';
1082     $attribs{COMPRESS}     ||= 'gzip';
1083     $attribs{SUFFIX}       ||= '-gz';
1084     $attribs{SHAR}         ||= 'vms_share';
1085     $attribs{DIST_DEFAULT} ||= 'zipdist';
1086
1087     return ExtUtils::MM_Unix::dist($self,%attribs);
1088 }
1089
1090 =item c_o (override)
1091
1092 Use VMS syntax on command line.  In particular, $(DEFINE) and
1093 $(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
1094
1095 =cut
1096
1097 sub c_o {
1098     my($self) = @_;
1099     return '' unless $self->needs_linking();
1100     '
1101 .c$(OBJ_EXT) :
1102         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1103
1104 .cpp$(OBJ_EXT) :
1105         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
1106
1107 .cxx$(OBJ_EXT) :
1108         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
1109
1110 ';
1111 }
1112
1113 =item xs_c (override)
1114
1115 Use MM[SK] macros.
1116
1117 =cut
1118
1119 sub xs_c {
1120     my($self) = @_;
1121     return '' unless $self->needs_linking();
1122     '
1123 .xs.c :
1124         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
1125 ';
1126 }
1127
1128 =item xs_o (override)
1129
1130 Use MM[SK] macros, and VMS command line for C compiler.
1131
1132 =cut
1133
1134 sub xs_o {      # many makes are too dumb to use xs_c then c_o
1135     my($self) = @_;
1136     return '' unless $self->needs_linking();
1137     '
1138 .xs$(OBJ_EXT) :
1139         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
1140         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1141 ';
1142 }
1143
1144 =item top_targets (override)
1145
1146 Use VMS quoting on command line for Version_check.
1147
1148 =cut
1149
1150 sub top_targets {
1151     my($self) = shift;
1152     my(@m);
1153     push @m, '
1154 all :: pure_all manifypods
1155         $(NOECHO) $(NOOP)
1156
1157 pure_all :: config pm_to_blib subdirs linkext
1158         $(NOECHO) $(NOOP)
1159
1160 subdirs :: $(MYEXTLIB)
1161         $(NOECHO) $(NOOP)
1162
1163 config :: $(MAKEFILE) $(INST_LIBDIR).exists
1164         $(NOECHO) $(NOOP)
1165
1166 config :: $(INST_ARCHAUTODIR).exists
1167         $(NOECHO) $(NOOP)
1168
1169 config :: $(INST_AUTODIR).exists
1170         $(NOECHO) $(NOOP)
1171 ';
1172
1173     push @m, q{
1174 config :: Version_check
1175         $(NOECHO) $(NOOP)
1176
1177 } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC};
1178
1179
1180     push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
1181     if (%{$self->{MAN1PODS}}) {
1182         push @m, q[
1183 config :: $(INST_MAN1DIR).exists
1184         $(NOECHO) $(NOOP)
1185 ];
1186         push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
1187     }
1188     if (%{$self->{MAN3PODS}}) {
1189         push @m, q[
1190 config :: $(INST_MAN3DIR).exists
1191         $(NOECHO) $(NOOP)
1192 ];
1193         push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
1194     }
1195
1196     push @m, '
1197 $(O_FILES) : $(H_FILES)
1198 ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
1199
1200     push @m, q{
1201 help :
1202         perldoc ExtUtils::MakeMaker
1203 };
1204
1205     push @m, q{
1206 Version_check :
1207         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1208         "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')"
1209 };
1210
1211     join('',@m);
1212 }
1213
1214 =item dlsyms (override)
1215
1216 Create VMS linker options files specifying universal symbols for this
1217 extension's shareable image, and listing other shareable images or 
1218 libraries to which it should be linked.
1219
1220 =cut
1221
1222 sub dlsyms {
1223     my($self,%attribs) = @_;
1224
1225     return '' unless $self->needs_linking();
1226
1227     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1228     my($vars)  = $attribs{DL_VARS}  || $self->{DL_VARS}  || [];
1229     my($srcdir)= $attribs{PERL_SRC} || $self->{PERL_SRC} || '';
1230     my(@m);
1231
1232     unless ($self->{SKIPHASH}{'dynamic'}) {
1233         push(@m,'
1234 dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt
1235         $(NOECHO) $(NOOP)
1236 ');
1237         if ($srcdir) {
1238            my($popt) = $self->catfile($srcdir,'perlshr.opt');
1239            my($lopt) = $self->catfile($srcdir,'crtl.opt');
1240            push(@m,"# Depend on \$(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists
1241 rtls.opt : $popt $lopt \$(BASEEXT).opt
1242         Copy/Log $popt Sys\$Disk:[]rtls.opt
1243         Append/Log $lopt Sys\$Disk:[]rtls.opt
1244 ");
1245         }
1246         else {
1247             push(@m,'
1248 # rtls.opt is built in the same step as $(BASEEXT).opt
1249 rtls.opt : $(BASEEXT).opt
1250         $(TOUCH) $(MMS$TARGET)
1251 ');
1252         }
1253     }
1254
1255     push(@m,'
1256 static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1257         $(NOECHO) $(NOOP)
1258 ') unless $self->{SKIPHASH}{'static'};
1259
1260     push(@m,'
1261 $(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
1262         $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1263
1264 $(BASEEXT).opt : Makefile.PL
1265         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Mksymlists;" -
1266         ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
1267         neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),')"
1268         $(PERL) -e "print ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)
1269 ');
1270
1271     if (length $self->{LDLOADLIBS}) {
1272         my($lib); my($line) = '';
1273         foreach $lib (split ' ', $self->{LDLOADLIBS}) {
1274             $lib =~ s%\$%\\\$%g;  # Escape '$' in VMS filespecs
1275             if (length($line) + length($lib) > 160) {
1276                 push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n";
1277                 $line = $lib . '\n';
1278             }
1279             else { $line .= $lib . '\n'; }
1280         }
1281         push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n" if $line;
1282     }
1283
1284     join('',@m);
1285
1286 }
1287
1288 =item dynamic_lib (override)
1289
1290 Use VMS Link command.
1291
1292 =cut
1293
1294 sub dynamic_lib {
1295     my($self, %attribs) = @_;
1296     return '' unless $self->needs_linking(); #might be because of a subdir
1297
1298     return '' unless $self->has_link_code();
1299
1300     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
1301     my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1302     my(@m);
1303     push @m,"
1304
1305 OTHERLDFLAGS = $otherldflags
1306 INST_DYNAMIC_DEP = $inst_dynamic_dep
1307
1308 ";
1309     push @m, '
1310 $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1311         $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
1312         $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.Exe
1313         Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option
1314 ';
1315
1316     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1317     join('',@m);
1318 }
1319
1320 =item dynamic_bs (override)
1321
1322 Use VMS-style quoting on Mkbootstrap command line.
1323
1324 =cut
1325
1326 sub dynamic_bs {
1327     my($self, %attribs) = @_;
1328     return '
1329 BOOTSTRAP =
1330 ' unless $self->has_link_code();
1331     '
1332 BOOTSTRAP = '."$self->{BASEEXT}.bs".'
1333
1334 # As MakeMaker mkbootstrap might not write a file (if none is required)
1335 # we use touch to prevent make continually trying to remake it.
1336 # The DynaLoader only reads a non-empty file.
1337 $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists
1338         $(NOECHO) Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
1339         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1340         -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
1341         $(NOECHO) $(TOUCH) $(MMS$TARGET)
1342
1343 $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists
1344         $(NOECHO) $(RM_RF) $(INST_BOOT)
1345         - $(CP) $(BOOTSTRAP) $(INST_BOOT)
1346 ';
1347 }
1348
1349 =item static_lib (override)
1350
1351 Use VMS commands to manipulate object library.
1352
1353 =cut
1354
1355 sub static_lib {
1356     my($self) = @_;
1357     return '' unless $self->needs_linking();
1358
1359     return '
1360 $(INST_STATIC) :
1361         $(NOECHO) $(NOOP)
1362 ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
1363
1364     my(@m);
1365     push @m,'
1366 # Rely on suffix rule for update action
1367 $(OBJECT) : $(INST_ARCHAUTODIR).exists
1368
1369 $(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
1370 ';
1371     # If this extension has it's own library (eg SDBM_File)
1372     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1373     push(@m, '  $(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1374
1375     push(@m,'
1376         If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
1377         Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
1378         $(NOECHO) $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;"
1379 ');
1380     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1381     join('',@m);
1382 }
1383
1384
1385 # sub installpm_x { # called by installpm perl file
1386 #     my($self, $dist, $inst, $splitlib) = @_;
1387 #     if ($inst =~ m!#!) {
1388 #       warn "Warning: MM[SK] would have problems processing this file: $inst, SKIPPED\n";
1389 #       return '';
1390 #     }
1391 #     $inst = $self->fixpath($inst);
1392 #     $dist = $self->fixpath($dist);
1393 #     my($instdir) = $inst =~ /([^\)]+\))[^\)]*$/ ? $1 : dirname($inst);
1394 #     my(@m);
1395
1396 #     push(@m, "
1397 # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists
1398 # ",'   $(NOECHO) $(RM_F) $(MMS$TARGET)
1399 #       $(NOECHO) $(CP) ',"$dist $inst",'
1400 #       $(CHMOD) 644 $(MMS$TARGET)
1401 # ');
1402 #     push(@m, '        $(AUTOSPLITFILE) $(MMS$TARGET) ',
1403 #               $self->catdir($splitlib,'auto')."\n\n")
1404 #         if ($splitlib and $inst =~ /\.pm$/);
1405 #     push(@m,$self->dir_target($instdir));
1406
1407 #     join('',@m);
1408 # }
1409
1410 =item manifypods (override)
1411
1412 Use VMS-style quoting on command line, and VMS logical name
1413 to specify fallback location at build time if we can't find pod2man.
1414
1415 =cut
1416
1417
1418 sub manifypods {
1419     my($self, %attribs) = @_;
1420     return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}};
1421     my($dist);
1422     my($pod2man_exe);
1423     if (defined $self->{PERL_SRC}) {
1424         $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man');
1425     } else {
1426         $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man');
1427     }
1428     if (not ($pod2man_exe = $self->perl_script($pod2man_exe))) {
1429         # No pod2man but some MAN3PODS to be installed
1430         print <<END;
1431
1432 Warning: I could not locate your pod2man program.  As a last choice,
1433          I will look for the file to which the logical name POD2MAN
1434          points when MMK is invoked.
1435
1436 END
1437         $pod2man_exe = "pod2man";
1438     }
1439     my(@m);
1440     push @m,
1441 qq[POD2MAN_EXE = $pod2man_exe\n],
1442 q[POD2MAN = $(PERL) -we "%m=@ARGV;for (keys %m){" -
1443 -e "system(""MCR $^X $(POD2MAN_EXE) $_ >$m{$_}"");}"
1444 ];
1445     push @m, "\nmanifypods : \$(MAN1PODS) \$(MAN3PODS)\n";
1446     if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) {
1447         my($pod);
1448         foreach $pod (sort keys %{$self->{MAN1PODS}}) {
1449             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1450             push @m, "$pod $self->{MAN1PODS}{$pod}\n";
1451         }
1452         foreach $pod (sort keys %{$self->{MAN3PODS}}) {
1453             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1454             push @m, "$pod $self->{MAN3PODS}{$pod}\n";
1455         }
1456     }
1457     join('', @m);
1458 }
1459
1460 =item processPL (override)
1461
1462 Use VMS-style quoting on command line.
1463
1464 =cut
1465
1466 sub processPL {
1467     my($self) = @_;
1468     return "" unless $self->{PL_FILES};
1469     my(@m, $plfile);
1470     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
1471         my $vmsplfile = vmsify($plfile);
1472         my $vmsfile = vmsify($self->{PL_FILES}->{$plfile});
1473         push @m, "
1474 all :: $vmsfile
1475         \$(NOECHO) \$(NOOP)
1476
1477 $vmsfile :: $vmsplfile
1478 ",'     $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $vmsplfile
1479 ";
1480     }
1481     join "", @m;
1482 }
1483
1484 =item installbin (override)
1485
1486 Stay under DCL's 255 character command line limit once again by
1487 splitting potentially long list of files across multiple lines
1488 in C<realclean> target.
1489
1490 =cut
1491
1492 sub installbin {
1493     my($self) = @_;
1494     return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
1495     return '' unless @{$self->{EXE_FILES}};
1496     my(@m, $from, $to, %fromto, @to, $line);
1497     my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}};
1498     for $from (@exefiles) {
1499         my($path) = '$(INST_SCRIPT)' . basename($from);
1500         local($_) = $path;  # backward compatibility
1501         $to = $self->libscan($path);
1502         print "libscan($from) => '$to'\n" if ($Verbose >=2);
1503         $fromto{$from} = vmsify($to);
1504     }
1505     @to = values %fromto;
1506     push @m, "
1507 EXE_FILES = @exefiles
1508
1509 all :: @to
1510         \$(NOECHO) \$(NOOP)
1511
1512 realclean ::
1513 ";
1514     $line = '';  #avoid unitialized var warning
1515     foreach $to (@to) {
1516         if (length($line) + length($to) > 80) {
1517             push @m, "\t\$(RM_F) $line\n";
1518             $line = $to;
1519         }
1520         else { $line .= " $to"; }
1521     }
1522     push @m, "\t\$(RM_F) $line\n\n" if $line;
1523
1524     while (($from,$to) = each %fromto) {
1525         last unless defined $from;
1526         my $todir;
1527         if ($to =~ m#[/>:\]]#) { $todir = dirname($to); }
1528         else                   { ($todir = $to) =~ s/[^\)]+$//; }
1529         $todir = $self->fixpath($todir,1);
1530         push @m, "
1531 $to : $from \$(MAKEFILE) ${todir}.exists
1532         \$(CP) $from $to
1533
1534 ", $self->dir_target($todir);
1535     }
1536     join "", @m;
1537 }
1538
1539 =item subdir_x (override)
1540
1541 Use VMS commands to change default directory.
1542
1543 =cut
1544
1545 sub subdir_x {
1546     my($self, $subdir) = @_;
1547     my(@m,$key);
1548     $subdir = $self->fixpath($subdir,1);
1549     push @m, '
1550
1551 subdirs ::
1552         olddef = F$Environment("Default")
1553         Set Default ',$subdir,'
1554         - $(MMS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
1555         Set Default \'olddef\'
1556 ';
1557     join('',@m);
1558 }
1559
1560 =item clean (override)
1561
1562 Split potentially long list of files across multiple commands (in
1563 order to stay under the magic command line limit).  Also use MM[SK]
1564 commands for handling subdirectories.
1565
1566 =cut
1567
1568 sub clean {
1569     my($self, %attribs) = @_;
1570     my(@m,$dir);
1571     push @m, '
1572 # Delete temporary files but do not touch installed files. We don\'t delete
1573 # the Descrip.MMS here so that a later make realclean still has it to use.
1574 clean ::
1575 ';
1576     foreach $dir (@{$self->{DIR}}) { # clean subdirectories first
1577         my($vmsdir) = $self->fixpath($dir,1);
1578         push( @m, '     If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t",
1579               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n");
1580     }
1581     push @m, '  $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp
1582 ';
1583
1584     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
1585     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
1586     push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]);
1587     push(@otherfiles,$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
1588     my($file,$line);
1589     $line = '';  #avoid unitialized var warning
1590     foreach $file (@otherfiles) {
1591         $file = $self->fixpath($file);
1592         if (length($line) + length($file) > 80) {
1593             push @m, "\t\$(RM_RF) $line\n";
1594             $line = "$file";
1595         }
1596         else { $line .= " $file"; }
1597     }
1598     push @m, "\t\$(RM_RF) $line\n" if $line;
1599     push(@m, "  $attribs{POSTOP}\n") if $attribs{POSTOP};
1600     join('', @m);
1601 }
1602
1603 =item realclean (override)
1604
1605 Guess what we're working around?  Also, use MM[SK] for subdirectories.
1606
1607 =cut
1608
1609 sub realclean {
1610     my($self, %attribs) = @_;
1611     my(@m);
1612     push(@m,'
1613 # Delete temporary files (via clean) and also delete installed files
1614 realclean :: clean
1615 ');
1616     foreach(@{$self->{DIR}}){
1617         my($vmsdir) = $self->fixpath($_,1);
1618         push(@m, '      If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t",
1619               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) realclean`;"',"\n");
1620     }
1621     push @m,'   $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
1622 ';
1623     # We can't expand several of the MMS macros here, since they don't have
1624     # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
1625     # combination of macros).  In order to stay below DCL's 255 char limit,
1626     # we put only 2 on a line.
1627     my($file,$line,$fcnt);
1628     my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old };
1629     if ($self->has_link_code) {
1630         push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
1631     }
1632     push(@files, values %{$self->{PM}});
1633     $line = '';  #avoid unitialized var warning
1634     foreach $file (@files) {
1635         $file = $self->fixpath($file);
1636         if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
1637             push @m, "\t\$(RM_F) $line\n";
1638             $line = "$file";
1639             $fcnt = 0;
1640         }
1641         else { $line .= " $file"; }
1642     }
1643     push @m, "\t\$(RM_F) $line\n" if $line;
1644     if ($attribs{FILES} && ref $attribs{FILES} eq 'ARRAY') {
1645         $line = '';
1646         foreach $file (@{$attribs{'FILES'}}) {
1647             $file = $self->fixpath($file);
1648             if (length($line) + length($file) > 80) {
1649                 push @m, "\t\$(RM_RF) $line\n";
1650                 $line = "$file";
1651             }
1652             else { $line .= " $file"; }
1653         }
1654         push @m, "\t\$(RM_RF) $line\n" if $line;
1655     }
1656     push(@m, "  $attribs{POSTOP}\n")                     if $attribs{POSTOP};
1657     join('', @m);
1658 }
1659
1660 =item dist_basics (override)
1661
1662 Use VMS-style quoting on command line.
1663
1664 =cut
1665
1666 sub dist_basics {
1667     my($self) = @_;
1668 '
1669 distclean :: realclean distcheck
1670         $(NOECHO) $(NOOP)
1671
1672 distcheck :
1673         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()"
1674
1675 skipcheck :
1676         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; skipcheck()"
1677
1678 manifest :
1679         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&mkmanifest\'; mkmanifest()"
1680 ';
1681 }
1682
1683 =item dist_core (override)
1684
1685 Syntax for invoking F<VMS_Share> differs from that for Unix F<shar>,
1686 so C<shdist> target actions are VMS-specific.
1687
1688 =cut
1689
1690 sub dist_core {
1691     my($self) = @_;
1692 q[
1693 dist : $(DIST_DEFAULT)
1694         $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'"
1695
1696 zipdist : $(DISTVNAME).zip
1697         $(NOECHO) $(NOOP)
1698
1699 $(DISTVNAME).zip : distdir
1700         $(PREOP)
1701         $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) $(SRC)
1702         $(RM_RF) $(DISTVNAME)
1703         $(POSTOP)
1704
1705 $(DISTVNAME).tar$(SUFFIX) : distdir
1706         $(PREOP)
1707         $(TO_UNIX)
1708         $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar $(SRC)
1709         $(RM_RF) $(DISTVNAME)
1710         $(COMPRESS) $(DISTVNAME).tar
1711         $(POSTOP)
1712
1713 shdist : distdir
1714         $(PREOP)
1715         $(SHARE) $(SRC) $(DISTVNAME).share
1716         $(RM_RF) $(DISTVNAME)
1717         $(POSTOP)
1718 ];
1719 }
1720
1721 =item dist_dir (override)
1722
1723 Use VMS-style quoting on command line.
1724
1725 =cut
1726
1727 sub dist_dir {
1728     my($self) = @_;
1729 q{
1730 distdir :
1731         $(RM_RF) $(DISTVNAME)
1732         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest '/mani/';" \\
1733         -e "manicopy(maniread(),'$(DISTVNAME)','$(DIST_CP)');"
1734 };
1735 }
1736
1737 =item dist_test (override)
1738
1739 Use VMS commands to change default directory, and use VMS-style
1740 quoting on command line.
1741
1742 =cut
1743
1744 sub dist_test {
1745     my($self) = @_;
1746 q{
1747 disttest : distdir
1748         startdir = F$Environment("Default")
1749         Set Default [.$(DISTVNAME)]
1750         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL
1751         $(MMS)
1752         $(MMS) test
1753         Set Default 'startdir'
1754 };
1755 }
1756
1757 # --- Test and Installation Sections ---
1758
1759 =item install (override)
1760
1761 Work around DCL's 255 character limit several times,and use
1762 VMS-style command line quoting in a few cases.
1763
1764 =cut
1765
1766 sub install {
1767     my($self, %attribs) = @_;
1768     my(@m,@docfiles);
1769
1770     if ($self->{EXE_FILES}) {
1771         my($line,$file) = ('','');
1772         foreach $file (@{$self->{EXE_FILES}}) {
1773             $line .= "$file ";
1774             if (length($line) > 128) {
1775                 push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]);
1776                 $line = '';
1777             }
1778         }
1779         push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]) if $line;
1780     }
1781
1782     push @m, q[
1783 install :: all pure_install doc_install
1784         $(NOECHO) $(NOOP)
1785
1786 install_perl :: all pure_perl_install doc_perl_install
1787         $(NOECHO) $(NOOP)
1788
1789 install_site :: all pure_site_install doc_site_install
1790         $(NOECHO) $(NOOP)
1791
1792 install_ :: install_site
1793         $(NOECHO) Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1794
1795 pure_install :: pure_$(INSTALLDIRS)_install
1796         $(NOECHO) $(NOOP)
1797
1798 doc_install :: doc_$(INSTALLDIRS)_install
1799         $(NOECHO) Write Sys$Output "Appending installation info to $(INSTALLARCHLIB)perllocal.pod"
1800
1801 pure__install : pure_site_install
1802         $(NOECHO) Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1803
1804 doc__install : doc_site_install
1805         $(NOECHO} Write Sys$Output "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1806
1807 # This hack brought to you by DCL's 255-character command line limit
1808 pure_perl_install ::
1809         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1810         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1811         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp
1812         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp
1813         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1814         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1815         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1816         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1817         $(MOD_INSTALL) <.MM_tmp
1818         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1819         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[
1820
1821 # Likewise
1822 pure_site_install ::
1823         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1824         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1825         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp
1826         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp
1827         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1828         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1829         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1830         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1831         $(MOD_INSTALL) <.MM_tmp
1832         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1833         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1834
1835 # Ditto
1836 doc_perl_install ::
1837         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp
1838         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1839         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1840 ],@docfiles,
1841 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1842         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1843         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1844         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1845         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1846         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1847
1848 # And again
1849 doc_site_install ::
1850         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp
1851         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1852         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1853 ],@docfiles,
1854 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1855         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1856         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1857         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1858         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1859         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1860
1861 ];
1862
1863     push @m, q[
1864 uninstall :: uninstall_from_$(INSTALLDIRS)dirs
1865         $(NOECHO) $(NOOP)
1866
1867 uninstall_from_perldirs ::
1868         $(NOECHO) $(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1869
1870 uninstall_from_sitedirs ::
1871         $(NOECHO) $(UNINSTALL) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist')."\n";
1872
1873     join('',@m);
1874 }
1875
1876 =item perldepend (override)
1877
1878 Use VMS-style syntax for files; it's cheaper to just do it directly here
1879 than to have the MM_Unix method call C<catfile> repeatedly.  Also use
1880 config.vms as source of original config data if the Perl distribution
1881 is available; config.sh is an ancillary file under VMS.  Finally, if
1882 we have to rebuild Config.pm, use MM[SK] to do it.
1883
1884 =cut
1885
1886 sub perldepend {
1887     my($self) = @_;
1888     my(@m);
1889
1890     push @m, '
1891 $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
1892 $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
1893 $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
1894 $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
1895 $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
1896 $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
1897 $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
1898
1899 ' if $self->{OBJECT}; 
1900
1901     if ($self->{PERL_SRC}) {
1902         my(@macros);
1903         my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)';
1904         push(@macros,'__AXP__=1') if $Config{'arch'} eq 'VMS_AXP';
1905         push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
1906         push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
1907         push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
1908         push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
1909         $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1910         push(@m,q[
1911 # Check for unpropagated config.sh changes. Should never happen.
1912 # We do NOT just update config.h because that is not sufficient.
1913 # An out of date config.h is not fatal but complains loudly!
1914 #$(PERL_INC)config.h : $(PERL_SRC)config.sh
1915 $(PERL_INC)config.h : $(PERL_VMS)config.vms
1916         $(NOECHO) Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms"
1917
1918 #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1919 $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl
1920         $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl"
1921         olddef = F$Environment("Default")
1922         Set Default $(PERL_SRC)
1923         $(MMS)],$mmsquals,q[ $(MMS$TARGET)
1924         Set Default 'olddef'
1925 ]);
1926     }
1927
1928     push(@m, join(" ", map($self->fixpath($_),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1929       if %{$self->{XS}};
1930
1931     join('',@m);
1932 }
1933
1934 =item makefile (override)
1935
1936 Use VMS commands and quoting.
1937
1938 =cut
1939
1940 sub makefile {
1941     my($self) = @_;
1942     my(@m,@cmd);
1943     # We do not know what target was originally specified so we
1944     # must force a manual rerun to be sure. But as it should only
1945     # happen very rarely it is not a significant problem.
1946     push @m, q[
1947 $(OBJECT) : $(FIRST_MAKEFILE)
1948 ] if $self->{OBJECT};
1949
1950     push @m,q[
1951 # We take a very conservative approach here, but it\'s worth it.
1952 # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
1953 $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
1954         $(NOECHO) Write Sys$Output "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
1955         $(NOECHO) Write Sys$Output "Cleaning current config before rebuilding $(MAKEFILE) ..."
1956         - $(MV) $(MAKEFILE) $(MAKEFILE)_old
1957         - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean
1958         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
1959         $(NOECHO) Write Sys$Output "$(MAKEFILE) has been rebuilt."
1960         $(NOECHO) Write Sys$Output "Please run $(MMS) to build the extension."
1961 ];
1962
1963     join('',@m);
1964 }
1965
1966 =item test (override)
1967
1968 Use VMS commands for handling subdirectories.
1969
1970 =cut
1971
1972 sub test {
1973     my($self, %attribs) = @_;
1974     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
1975     my(@m);
1976     push @m,"
1977 TEST_VERBOSE = 0
1978 TEST_TYPE = test_\$(LINKTYPE)
1979 TEST_FILE = test.pl
1980 TESTDB_SW = -d
1981
1982 test :: \$(TEST_TYPE)
1983         \$(NOECHO) \$(NOOP)
1984
1985 testdb :: testdb_\$(LINKTYPE)
1986         \$(NOECHO) \$(NOOP)
1987
1988 ";
1989     foreach(@{$self->{DIR}}){
1990       my($vmsdir) = $self->fixpath($_,1);
1991       push(@m, '        If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
1992            '; print `$(MMS) $(PASTHRU2) test`'."\n");
1993     }
1994     push(@m, "\t\$(NOECHO) Write Sys\$Output \"No tests defined for \$(NAME) extension.\"\n")
1995         unless $tests or -f "test.pl" or @{$self->{DIR}};
1996     push(@m, "\n");
1997
1998     push(@m, "test_dynamic :: pure_all\n");
1999     push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests;
2000     push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl";
2001     push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl");
2002     push(@m, "\n");
2003
2004     push(@m, "testdb_dynamic :: pure_all\n");
2005     push(@m, $self->test_via_script('$(FULLPERL) "$(TESTDB_SW)"', '$(TEST_FILE)'));
2006     push(@m, "\n");
2007
2008     # Occasionally we may face this degenerate target:
2009     push @m, "test_ : test_dynamic\n\n";
2010  
2011     if ($self->needs_linking()) {
2012         push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
2013         push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
2014         push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
2015         push(@m, "\n");
2016         push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
2017         push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
2018         push(@m, "\n");
2019     }
2020     else {
2021         push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n";
2022         push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n";
2023     }
2024
2025     join('',@m);
2026 }
2027
2028 =item test_via_harness (override)
2029
2030 Use VMS-style quoting on command line.
2031
2032 =cut
2033
2034 sub test_via_harness {
2035     my($self,$perl,$tests) = @_;
2036     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\'."\n\t".
2037     '-e "use Test::Harness qw(&runtests $verbose); $verbose=$(TEST_VERBOSE); runtests @ARGV;" \\'."\n\t$tests\n";
2038 }
2039
2040 =item test_via_script (override)
2041
2042 Use VMS-style quoting on command line.
2043
2044 =cut
2045
2046 sub test_via_script {
2047     my($self,$perl,$script) = @_;
2048     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '.$script.'
2049 ';
2050 }
2051
2052 =item makeaperl (override)
2053
2054 Undertake to build a new set of Perl images using VMS commands.  Since
2055 VMS does dynamic loading, it's not necessary to statically link each
2056 extension into the Perl image, so this isn't the normal build path.
2057 Consequently, it hasn't really been tested, and may well be incomplete.
2058
2059 =cut
2060
2061 sub makeaperl {
2062     my($self, %attribs) = @_;
2063     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
2064       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
2065     my(@m);
2066     push @m, "
2067 # --- MakeMaker makeaperl section ---
2068 MAP_TARGET    = $target
2069 ";
2070     return join '', @m if $self->{PARENT};
2071
2072     my($dir) = join ":", @{$self->{DIR}};
2073
2074     unless ($self->{MAKEAPERL}) {
2075         push @m, q{
2076 $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
2077         $(NOECHO) Write Sys$Output "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
2078         $(NOECHO) $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
2079                 Makefile.PL DIR=}, $dir, q{ \
2080                 MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
2081                 MAKEAPERL=1 NORECURS=1
2082
2083 $(MAP_TARGET) :: $(MAKE_APERL_FILE)
2084         $(MMS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
2085 };
2086         push @m, map( " \\\n\t\t$_", @ARGV );
2087         push @m, "\n";
2088
2089         return join '', @m;
2090     }
2091
2092
2093     my($linkcmd,@staticopts,@staticpkgs,$extralist,$targdir,$libperldir);
2094
2095     # The front matter of the linkcommand...
2096     $linkcmd = join ' ', $Config{'ld'},
2097             grep($_, @Config{qw(large split ldflags ccdlflags)});
2098     $linkcmd =~ s/\s+/ /g;
2099
2100     # Which *.olb files could we make use of...
2101     local(%olbs);
2102     $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
2103     require File::Find;
2104     File::Find::find(sub {
2105         return unless m/\Q$self->{LIB_EXT}\E$/;
2106         return if m/^libperl/;
2107
2108         if( exists $self->{INCLUDE_EXT} ){
2109                 my $found = 0;
2110                 my $incl;
2111                 my $xx;
2112
2113                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2114                 $xx =~ s,/?$_,,;
2115                 $xx =~ s,/,::,g;
2116
2117                 # Throw away anything not explicitly marked for inclusion.
2118                 # DynaLoader is implied.
2119                 foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
2120                         if( $xx eq $incl ){
2121                                 $found++;
2122                                 last;
2123                         }
2124                 }
2125                 return unless $found;
2126         }
2127         elsif( exists $self->{EXCLUDE_EXT} ){
2128                 my $excl;
2129                 my $xx;
2130
2131                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2132                 $xx =~ s,/?$_,,;
2133                 $xx =~ s,/,::,g;
2134
2135                 # Throw away anything explicitly marked for exclusion
2136                 foreach $excl (@{$self->{EXCLUDE_EXT}}){
2137                         return if( $xx eq $excl );
2138                 }
2139         }
2140
2141         $olbs{$ENV{DEFAULT}} = $_;
2142     }, grep( -d $_, @{$searchdirs || []}));
2143
2144     # We trust that what has been handed in as argument will be buildable
2145     $static = [] unless $static;
2146     @olbs{@{$static}} = (1) x @{$static};
2147  
2148     $extra = [] unless $extra && ref $extra eq 'ARRAY';
2149     # Sort the object libraries in inverse order of
2150     # filespec length to try to insure that dependent extensions
2151     # will appear before their parents, so the linker will
2152     # search the parent library to resolve references.
2153     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
2154     # references from [.intuit.dwim]dwim.obj can be found
2155     # in [.intuit]intuit.olb).
2156     for (sort keys %olbs) {
2157         next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
2158         my($dir) = $self->fixpath($_,1);
2159         my($extralibs) = $dir . "extralibs.ld";
2160         my($extopt) = $dir . $olbs{$_};
2161         $extopt =~ s/$self->{LIB_EXT}$/.opt/;
2162         if (-f $extralibs ) {
2163             open LIST,$extralibs or warn $!,next;
2164             push @$extra, <LIST>;
2165             close LIST;
2166         }
2167         if (-f $extopt) {
2168             open OPT,$extopt or die $!;
2169             while (<OPT>) {
2170                 next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
2171                 # ExtUtils::Miniperl expects Unix paths
2172                 (my($pkg) = "$1_$1$self->{LIB_EXT}") =~ s#_*#/#g;
2173                 push @staticpkgs,$pkg;
2174             }
2175             push @staticopts, $extopt;
2176         }
2177     }
2178
2179     $target = "Perl.Exe" unless $target;
2180     ($shrtarget,$targdir) = fileparse($target);
2181     $shrtarget =~ s/^([^.]*)/$1Shr/;
2182     $shrtarget = $targdir . $shrtarget;
2183     $target = "Perlshr.$Config{'dlext'}" unless $target;
2184     $tmp = "[]" unless $tmp;
2185     $tmp = $self->fixpath($tmp,1);
2186     if (@$extra) {
2187         $extralist = join(' ',@$extra);
2188         $extralist =~ s/[,\s\n]+/, /g;
2189     }
2190     else { $extralist = ''; }
2191     if ($libperl) {
2192         unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
2193             print STDOUT "Warning: $libperl not found\n";
2194             undef $libperl;
2195         }
2196     }
2197     unless ($libperl) {
2198         if (defined $self->{PERL_SRC}) {
2199             $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
2200         } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
2201         } else {
2202             print STDOUT "Warning: $libperl not found
2203     If you're going to build a static perl binary, make sure perl is installed
2204     otherwise ignore this warning\n";
2205         }
2206     }
2207     $libperldir = $self->fixpath((fileparse($libperl))[1],1);
2208
2209     push @m, '
2210 # Fill in the target you want to produce if it\'s not perl
2211 MAP_TARGET    = ',$self->fixpath($target),'
2212 MAP_SHRTARGET = ',$self->fixpath($shrtarget),"
2213 MAP_LINKCMD   = $linkcmd
2214 MAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '','
2215 # We use the linker options files created with each extension, rather than
2216 #specifying the object files directly on the command line.
2217 MAP_STATIC    = ',@staticopts ? join(' ', @staticopts) : '','
2218 MAP_OPTS    = ',@staticopts ? ','.join(',', map($_.'/Option', @staticopts)) : '',"
2219 MAP_EXTRA     = $extralist
2220 MAP_LIBPERL = ",$self->fixpath($libperl),'
2221 ';
2222
2223
2224     push @m,'
2225 $(MAP_SHRTARGET) : $(MAP_LIBPERL) $(MAP_STATIC) ',"${libperldir}Perlshr_Attr.Opt",'
2226         $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",'
2227 $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",'
2228         $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
2229         $(NOECHO) Write Sys$Output "To install the new ""$(MAP_TARGET)"" binary, say"
2230         $(NOECHO) Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
2231         $(NOECHO) Write Sys$Output "To remove the intermediate files, say
2232         $(NOECHO) Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
2233 ';
2234     push @m,'
2235 ',"${tmp}perlmain.c",' : $(MAKEFILE)
2236         $(NOECHO) $(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET)
2237 ';
2238
2239     push @m, q[
2240 # More from the 255-char line length limit
2241 doc_inst_perl :
2242         $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp
2243         $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp
2244         $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
2245         $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp
2246         $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
2247         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
2248 ];
2249
2250     push @m, "
2251 inst_perl : pure_inst_perl doc_inst_perl
2252         \$(NOECHO) \$(NOOP)
2253
2254 pure_inst_perl : \$(MAP_TARGET)
2255         $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
2256         $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
2257
2258 clean :: map_clean
2259         \$(NOECHO) \$(NOOP)
2260
2261 map_clean :
2262         \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE)
2263         \$(RM_F) ${tmp}PerlShr.Opt \$(MAP_TARGET)
2264 ";
2265
2266     join '', @m;
2267 }
2268   
2269 # --- Output postprocessing section ---
2270
2271 =item nicetext (override)
2272
2273 Insure that colons marking targets are preceded by space, in order
2274 to distinguish the target delimiter from a colon appearing as
2275 part of a filespec.
2276
2277 =cut
2278
2279 sub nicetext {
2280
2281     my($self,$text) = @_;
2282     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
2283     $text;
2284 }
2285
2286 1;
2287
2288 __END__
2289