This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
1e39e118fcca3900d23264331c491bfef2410d9c
[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             $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 SAY = Write Sys\$Output
1059 UMASK_NULL = $self->{UMASK_NULL}
1060 NOOP = $self->{NOOP}
1061 NOECHO = $self->{NOECHO}
1062 MKPATH = Create/Directory
1063 EQUALIZE_TIMESTAMP = \$(PERL) -we "open F,qq{>\$ARGV[1]};close F;utime(0,(stat(\$ARGV[0]))[9]+1,\$ARGV[1])"
1064 !. ($self->{PARENT} ? '' : 
1065 qq!WARN_IF_OLD_PACKLIST = \$(PERL) -e "if (-f \$ARGV[0]){print qq[WARNING: Old package found (\$ARGV[0]); please check for collisions\\n]}"
1066 MOD_INSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "install({split(' ',<STDIN>)},1);"
1067 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]"
1068 UNINSTALL = \$(PERL) "-I\$(PERL_LIB)" "-MExtUtils::Install" -e "uninstall(\$ARGV[0],1,1);"
1069 !);
1070 }
1071
1072 =item dist (override)
1073
1074 Provide VMSish defaults for some values, then hand off to
1075 default MM_Unix method.
1076
1077 =cut
1078
1079 sub dist {
1080     my($self, %attribs) = @_;
1081     $attribs{VERSION}      ||= $self->{VERSION_SYM};
1082     $attribs{ZIPFLAGS}     ||= '-Vu';
1083     $attribs{COMPRESS}     ||= 'gzip';
1084     $attribs{SUFFIX}       ||= '-gz';
1085     $attribs{SHAR}         ||= 'vms_share';
1086     $attribs{DIST_DEFAULT} ||= 'zipdist';
1087
1088     return ExtUtils::MM_Unix::dist($self,%attribs);
1089 }
1090
1091 =item c_o (override)
1092
1093 Use VMS syntax on command line.  In particular, $(DEFINE) and
1094 $(PERL_INC) have been pulled into $(CCCMD).  Also use MM[SK] macros.
1095
1096 =cut
1097
1098 sub c_o {
1099     my($self) = @_;
1100     return '' unless $self->needs_linking();
1101     '
1102 .c$(OBJ_EXT) :
1103         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1104
1105 .cpp$(OBJ_EXT) :
1106         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp
1107
1108 .cxx$(OBJ_EXT) :
1109         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx
1110
1111 ';
1112 }
1113
1114 =item xs_c (override)
1115
1116 Use MM[SK] macros.
1117
1118 =cut
1119
1120 sub xs_c {
1121     my($self) = @_;
1122     return '' unless $self->needs_linking();
1123     '
1124 .xs.c :
1125         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
1126 ';
1127 }
1128
1129 =item xs_o (override)
1130
1131 Use MM[SK] macros, and VMS command line for C compiler.
1132
1133 =cut
1134
1135 sub xs_o {      # many makes are too dumb to use xs_c then c_o
1136     my($self) = @_;
1137     return '' unless $self->needs_linking();
1138     '
1139 .xs$(OBJ_EXT) :
1140         $(XSUBPP) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
1141         $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c
1142 ';
1143 }
1144
1145 =item top_targets (override)
1146
1147 Use VMS quoting on command line for Version_check.
1148
1149 =cut
1150
1151 sub top_targets {
1152     my($self) = shift;
1153     my(@m);
1154     push @m, '
1155 all :: pure_all manifypods
1156         $(NOECHO) $(NOOP)
1157
1158 pure_all :: config pm_to_blib subdirs linkext
1159         $(NOECHO) $(NOOP)
1160
1161 subdirs :: $(MYEXTLIB)
1162         $(NOECHO) $(NOOP)
1163
1164 config :: $(MAKEFILE) $(INST_LIBDIR).exists
1165         $(NOECHO) $(NOOP)
1166
1167 config :: $(INST_ARCHAUTODIR).exists
1168         $(NOECHO) $(NOOP)
1169
1170 config :: $(INST_AUTODIR).exists
1171         $(NOECHO) $(NOOP)
1172 ';
1173
1174     push @m, q{
1175 config :: Version_check
1176         $(NOECHO) $(NOOP)
1177
1178 } unless $self->{PARENT} or ($self->{PERL_SRC} && $self->{INSTALLDIRS} eq "perl") or $self->{NO_VC};
1179
1180
1181     push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
1182     if (%{$self->{MAN1PODS}}) {
1183         push @m, q[
1184 config :: $(INST_MAN1DIR).exists
1185         $(NOECHO) $(NOOP)
1186 ];
1187         push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
1188     }
1189     if (%{$self->{MAN3PODS}}) {
1190         push @m, q[
1191 config :: $(INST_MAN3DIR).exists
1192         $(NOECHO) $(NOOP)
1193 ];
1194         push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
1195     }
1196
1197     push @m, '
1198 $(O_FILES) : $(H_FILES)
1199 ' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
1200
1201     push @m, q{
1202 help :
1203         perldoc ExtUtils::MakeMaker
1204 };
1205
1206     push @m, q{
1207 Version_check :
1208         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1209         "-MExtUtils::MakeMaker=Version_check" -e "&Version_check('$(MM_VERSION)')"
1210 };
1211
1212     join('',@m);
1213 }
1214
1215 =item dlsyms (override)
1216
1217 Create VMS linker options files specifying universal symbols for this
1218 extension's shareable image, and listing other shareable images or 
1219 libraries to which it should be linked.
1220
1221 =cut
1222
1223 sub dlsyms {
1224     my($self,%attribs) = @_;
1225
1226     return '' unless $self->needs_linking();
1227
1228     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
1229     my($vars)  = $attribs{DL_VARS}  || $self->{DL_VARS}  || [];
1230     my($srcdir)= $attribs{PERL_SRC} || $self->{PERL_SRC} || '';
1231     my(@m);
1232
1233     unless ($self->{SKIPHASH}{'dynamic'}) {
1234         push(@m,'
1235 dynamic :: rtls.opt $(INST_ARCHAUTODIR)$(BASEEXT).opt
1236         $(NOECHO) $(NOOP)
1237 ');
1238         if ($srcdir) {
1239            my($popt) = $self->catfile($srcdir,'perlshr.opt');
1240            my($lopt) = $self->catfile($srcdir,'crtl.opt');
1241            push(@m,"# Depend on \$(BASEEXT).opt to insure we copy here *after* autogenerating (wrong) rtls.opt in Mksymlists
1242 rtls.opt : $popt $lopt \$(BASEEXT).opt
1243         Copy/Log $popt Sys\$Disk:[]rtls.opt
1244         Append/Log $lopt Sys\$Disk:[]rtls.opt
1245 ");
1246         }
1247         else {
1248             push(@m,'
1249 # rtls.opt is built in the same step as $(BASEEXT).opt
1250 rtls.opt : $(BASEEXT).opt
1251         $(TOUCH) $(MMS$TARGET)
1252 ');
1253         }
1254     }
1255
1256     push(@m,'
1257 static :: $(INST_ARCHAUTODIR)$(BASEEXT).opt
1258         $(NOECHO) $(NOOP)
1259 ') unless $self->{SKIPHASH}{'static'};
1260
1261     push(@m,'
1262 $(INST_ARCHAUTODIR)$(BASEEXT).opt : $(BASEEXT).opt
1263         $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1264
1265 $(BASEEXT).opt : Makefile.PL
1266         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Mksymlists;" -
1267         ',qq[-e "Mksymlists('NAME' => '$self->{NAME}', 'DL_FUNCS' => ],
1268         neatvalue($funcs),q[, 'DL_VARS' => ],neatvalue($vars),')"
1269         $(PERL) -e "print ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";" >>$(MMS$TARGET)
1270 ');
1271
1272     if (length $self->{LDLOADLIBS}) {
1273         my($lib); my($line) = '';
1274         foreach $lib (split ' ', $self->{LDLOADLIBS}) {
1275             $lib =~ s%\$%\\\$%g;  # Escape '$' in VMS filespecs
1276             if (length($line) + length($lib) > 160) {
1277                 push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n";
1278                 $line = $lib . '\n';
1279             }
1280             else { $line .= $lib . '\n'; }
1281         }
1282         push @m, "\t\$(PERL) -e \"print qq[$line]\" >>\$(MMS\$TARGET)\n" if $line;
1283     }
1284
1285     join('',@m);
1286
1287 }
1288
1289 =item dynamic_lib (override)
1290
1291 Use VMS Link command.
1292
1293 =cut
1294
1295 sub dynamic_lib {
1296     my($self, %attribs) = @_;
1297     return '' unless $self->needs_linking(); #might be because of a subdir
1298
1299     return '' unless $self->has_link_code();
1300
1301     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
1302     my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
1303     my(@m);
1304     push @m,"
1305
1306 OTHERLDFLAGS = $otherldflags
1307 INST_DYNAMIC_DEP = $inst_dynamic_dep
1308
1309 ";
1310     push @m, '
1311 $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1312         $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
1313         $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.Exe
1314         Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option
1315 ';
1316
1317     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1318     join('',@m);
1319 }
1320
1321 =item dynamic_bs (override)
1322
1323 Use VMS-style quoting on Mkbootstrap command line.
1324
1325 =cut
1326
1327 sub dynamic_bs {
1328     my($self, %attribs) = @_;
1329     return '
1330 BOOTSTRAP =
1331 ' unless $self->has_link_code();
1332     '
1333 BOOTSTRAP = '."$self->{BASEEXT}.bs".'
1334
1335 # As MakeMaker mkbootstrap might not write a file (if none is required)
1336 # we use touch to prevent make continually trying to remake it.
1337 # The DynaLoader only reads a non-empty file.
1338 $(BOOTSTRAP) : $(MAKEFILE) '."$self->{BOOTDEP}".' $(INST_ARCHAUTODIR).exists
1339         $(NOECHO) $(SAY) "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
1340         $(NOECHO) $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -
1341         -e "use ExtUtils::Mkbootstrap; Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
1342         $(NOECHO) $(TOUCH) $(MMS$TARGET)
1343
1344 $(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR).exists
1345         $(NOECHO) $(RM_RF) $(INST_BOOT)
1346         - $(CP) $(BOOTSTRAP) $(INST_BOOT)
1347 ';
1348 }
1349
1350 =item static_lib (override)
1351
1352 Use VMS commands to manipulate object library.
1353
1354 =cut
1355
1356 sub static_lib {
1357     my($self) = @_;
1358     return '' unless $self->needs_linking();
1359
1360     return '
1361 $(INST_STATIC) :
1362         $(NOECHO) $(NOOP)
1363 ' unless ($self->{OBJECT} or @{$self->{C} || []} or $self->{MYEXTLIB});
1364
1365     my(@m);
1366     push @m,'
1367 # Rely on suffix rule for update action
1368 $(OBJECT) : $(INST_ARCHAUTODIR).exists
1369
1370 $(INST_STATIC) : $(OBJECT) $(MYEXTLIB)
1371 ';
1372     # If this extension has it's own library (eg SDBM_File)
1373     # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1374     push(@m, '  $(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1375
1376     push(@m,'
1377         If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
1378         Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
1379         $(NOECHO) $(PERL) -e "open F,\'>>$(INST_ARCHAUTODIR)extralibs.ld\';print F qq[$(EXTRALIBS)\n];close F;"
1380 ');
1381     push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
1382     join('',@m);
1383 }
1384
1385
1386 # sub installpm_x { # called by installpm perl file
1387 #     my($self, $dist, $inst, $splitlib) = @_;
1388 #     if ($inst =~ m!#!) {
1389 #       warn "Warning: MM[SK] would have problems processing this file: $inst, SKIPPED\n";
1390 #       return '';
1391 #     }
1392 #     $inst = $self->fixpath($inst);
1393 #     $dist = $self->fixpath($dist);
1394 #     my($instdir) = $inst =~ /([^\)]+\))[^\)]*$/ ? $1 : dirname($inst);
1395 #     my(@m);
1396
1397 #     push(@m, "
1398 # $inst : $dist \$(MAKEFILE) ${instdir}.exists \$(INST_ARCHAUTODIR).exists
1399 # ",'   $(NOECHO) $(RM_F) $(MMS$TARGET)
1400 #       $(NOECHO) $(CP) ',"$dist $inst",'
1401 #       $(CHMOD) 644 $(MMS$TARGET)
1402 # ');
1403 #     push(@m, '        $(AUTOSPLITFILE) $(MMS$TARGET) ',
1404 #               $self->catdir($splitlib,'auto')."\n\n")
1405 #         if ($splitlib and $inst =~ /\.pm$/);
1406 #     push(@m,$self->dir_target($instdir));
1407
1408 #     join('',@m);
1409 # }
1410
1411 =item manifypods (override)
1412
1413 Use VMS-style quoting on command line, and VMS logical name
1414 to specify fallback location at build time if we can't find pod2man.
1415
1416 =cut
1417
1418
1419 sub manifypods {
1420     my($self, %attribs) = @_;
1421     return "\nmanifypods :\n\t\$(NOECHO) \$(NOOP)\n" unless %{$self->{MAN3PODS}} or %{$self->{MAN1PODS}};
1422     my($dist);
1423     my($pod2man_exe);
1424     if (defined $self->{PERL_SRC}) {
1425         $pod2man_exe = $self->catfile($self->{PERL_SRC},'pod','pod2man');
1426     } else {
1427         $pod2man_exe = $self->catfile($Config{scriptdirexp},'pod2man');
1428     }
1429     if (not ($pod2man_exe = $self->perl_script($pod2man_exe))) {
1430         # No pod2man but some MAN3PODS to be installed
1431         print <<END;
1432
1433 Warning: I could not locate your pod2man program.  As a last choice,
1434          I will look for the file to which the logical name POD2MAN
1435          points when MMK is invoked.
1436
1437 END
1438         $pod2man_exe = "pod2man";
1439     }
1440     my(@m);
1441     push @m,
1442 qq[POD2MAN_EXE = $pod2man_exe\n],
1443 q[POD2MAN = $(PERL) -we "%m=@ARGV;for (keys %m){" -
1444 -e "system(""MCR $^X $(POD2MAN_EXE) $_ >$m{$_}"");}"
1445 ];
1446     push @m, "\nmanifypods : \$(MAN1PODS) \$(MAN3PODS)\n";
1447     if (%{$self->{MAN1PODS}} || %{$self->{MAN3PODS}}) {
1448         my($pod);
1449         foreach $pod (sort keys %{$self->{MAN1PODS}}) {
1450             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1451             push @m, "$pod $self->{MAN1PODS}{$pod}\n";
1452         }
1453         foreach $pod (sort keys %{$self->{MAN3PODS}}) {
1454             push @m, qq[\t\@- If F\$Search("\$(POD2MAN_EXE)").nes."" Then \$(POD2MAN) ];
1455             push @m, "$pod $self->{MAN3PODS}{$pod}\n";
1456         }
1457     }
1458     join('', @m);
1459 }
1460
1461 =item processPL (override)
1462
1463 Use VMS-style quoting on command line.
1464
1465 =cut
1466
1467 sub processPL {
1468     my($self) = @_;
1469     return "" unless $self->{PL_FILES};
1470     my(@m, $plfile);
1471     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
1472         my $vmsplfile = vmsify($plfile);
1473         my $vmsfile = vmsify($self->{PL_FILES}->{$plfile});
1474         push @m, "
1475 all :: $vmsfile
1476         \$(NOECHO) \$(NOOP)
1477
1478 $vmsfile :: $vmsplfile
1479 ",'     $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '," $vmsplfile
1480 ";
1481     }
1482     join "", @m;
1483 }
1484
1485 =item installbin (override)
1486
1487 Stay under DCL's 255 character command line limit once again by
1488 splitting potentially long list of files across multiple lines
1489 in C<realclean> target.
1490
1491 =cut
1492
1493 sub installbin {
1494     my($self) = @_;
1495     return '' unless $self->{EXE_FILES} && ref $self->{EXE_FILES} eq "ARRAY";
1496     return '' unless @{$self->{EXE_FILES}};
1497     my(@m, $from, $to, %fromto, @to, $line);
1498     my(@exefiles) = map { vmsify($_) } @{$self->{EXE_FILES}};
1499     for $from (@exefiles) {
1500         my($path) = '$(INST_SCRIPT)' . basename($from);
1501         local($_) = $path;  # backward compatibility
1502         $to = $self->libscan($path);
1503         print "libscan($from) => '$to'\n" if ($Verbose >=2);
1504         $fromto{$from} = vmsify($to);
1505     }
1506     @to = values %fromto;
1507     push @m, "
1508 EXE_FILES = @exefiles
1509
1510 all :: @to
1511         \$(NOECHO) \$(NOOP)
1512
1513 realclean ::
1514 ";
1515     $line = '';  #avoid unitialized var warning
1516     foreach $to (@to) {
1517         if (length($line) + length($to) > 80) {
1518             push @m, "\t\$(RM_F) $line\n";
1519             $line = $to;
1520         }
1521         else { $line .= " $to"; }
1522     }
1523     push @m, "\t\$(RM_F) $line\n\n" if $line;
1524
1525     while (($from,$to) = each %fromto) {
1526         last unless defined $from;
1527         my $todir;
1528         if ($to =~ m#[/>:\]]#) { $todir = dirname($to); }
1529         else                   { ($todir = $to) =~ s/[^\)]+$//; }
1530         $todir = $self->fixpath($todir,1);
1531         push @m, "
1532 $to : $from \$(MAKEFILE) ${todir}.exists
1533         \$(CP) $from $to
1534
1535 ", $self->dir_target($todir);
1536     }
1537     join "", @m;
1538 }
1539
1540 =item subdir_x (override)
1541
1542 Use VMS commands to change default directory.
1543
1544 =cut
1545
1546 sub subdir_x {
1547     my($self, $subdir) = @_;
1548     my(@m,$key);
1549     $subdir = $self->fixpath($subdir,1);
1550     push @m, '
1551
1552 subdirs ::
1553         olddef = F$Environment("Default")
1554         Set Default ',$subdir,'
1555         - $(MMS) all $(USEMACROS)$(PASTHRU)$(MACROEND)
1556         Set Default \'olddef\'
1557 ';
1558     join('',@m);
1559 }
1560
1561 =item clean (override)
1562
1563 Split potentially long list of files across multiple commands (in
1564 order to stay under the magic command line limit).  Also use MM[SK]
1565 commands for handling subdirectories.
1566
1567 =cut
1568
1569 sub clean {
1570     my($self, %attribs) = @_;
1571     my(@m,$dir);
1572     push @m, '
1573 # Delete temporary files but do not touch installed files. We don\'t delete
1574 # the Descrip.MMS here so that a later make realclean still has it to use.
1575 clean ::
1576 ';
1577     foreach $dir (@{$self->{DIR}}) { # clean subdirectories first
1578         my($vmsdir) = $self->fixpath($dir,1);
1579         push( @m, '     If F$Search("'.$vmsdir.'$(MAKEFILE)") Then \\',"\n\t",
1580               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) clean`;"',"\n");
1581     }
1582     push @m, '  $(RM_F) *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *$(OBJ_EXT) *$(LIB_EXT) *.Opt $(BOOTSTRAP) $(BASEEXT).bso .MM_Tmp
1583 ';
1584
1585     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
1586     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
1587     push(@otherfiles, qw[ blib $(MAKE_APERL_FILE) extralibs.ld perlmain.c pm_to_blib.ts ]);
1588     push(@otherfiles,$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'));
1589     my($file,$line);
1590     $line = '';  #avoid unitialized var warning
1591     foreach $file (@otherfiles) {
1592         $file = $self->fixpath($file);
1593         if (length($line) + length($file) > 80) {
1594             push @m, "\t\$(RM_RF) $line\n";
1595             $line = "$file";
1596         }
1597         else { $line .= " $file"; }
1598     }
1599     push @m, "\t\$(RM_RF) $line\n" if $line;
1600     push(@m, "  $attribs{POSTOP}\n") if $attribs{POSTOP};
1601     join('', @m);
1602 }
1603
1604 =item realclean (override)
1605
1606 Guess what we're working around?  Also, use MM[SK] for subdirectories.
1607
1608 =cut
1609
1610 sub realclean {
1611     my($self, %attribs) = @_;
1612     my(@m);
1613     push(@m,'
1614 # Delete temporary files (via clean) and also delete installed files
1615 realclean :: clean
1616 ');
1617     foreach(@{$self->{DIR}}){
1618         my($vmsdir) = $self->fixpath($_,1);
1619         push(@m, '      If F$Search("'."$vmsdir".'$(MAKEFILE)").nes."" Then \\',"\n\t",
1620               '$(PERL) -e "chdir ',"'$vmsdir'",'; print `$(MMS) realclean`;"',"\n");
1621     }
1622     push @m,'   $(RM_RF) $(INST_AUTODIR) $(INST_ARCHAUTODIR)
1623 ';
1624     # We can't expand several of the MMS macros here, since they don't have
1625     # corresponding %$self keys (i.e. they're defined in Descrip.MMS as a
1626     # combination of macros).  In order to stay below DCL's 255 char limit,
1627     # we put only 2 on a line.
1628     my($file,$line,$fcnt);
1629     my(@files) = qw{ $(MAKEFILE) $(MAKEFILE)_old };
1630     if ($self->has_link_code) {
1631         push(@files,qw{ $(INST_DYNAMIC) $(INST_STATIC) $(INST_BOOT) $(OBJECT) });
1632     }
1633     push(@files, values %{$self->{PM}});
1634     $line = '';  #avoid unitialized var warning
1635     foreach $file (@files) {
1636         $file = $self->fixpath($file);
1637         if (length($line) + length($file) > 80 || ++$fcnt >= 2) {
1638             push @m, "\t\$(RM_F) $line\n";
1639             $line = "$file";
1640             $fcnt = 0;
1641         }
1642         else { $line .= " $file"; }
1643     }
1644     push @m, "\t\$(RM_F) $line\n" if $line;
1645     if ($attribs{FILES} && ref $attribs{FILES} eq 'ARRAY') {
1646         $line = '';
1647         foreach $file (@{$attribs{'FILES'}}) {
1648             $file = $self->fixpath($file);
1649             if (length($line) + length($file) > 80) {
1650                 push @m, "\t\$(RM_RF) $line\n";
1651                 $line = "$file";
1652             }
1653             else { $line .= " $file"; }
1654         }
1655         push @m, "\t\$(RM_RF) $line\n" if $line;
1656     }
1657     push(@m, "  $attribs{POSTOP}\n")                     if $attribs{POSTOP};
1658     join('', @m);
1659 }
1660
1661 =item dist_basics (override)
1662
1663 Use VMS-style quoting on command line.
1664
1665 =cut
1666
1667 sub dist_basics {
1668     my($self) = @_;
1669 '
1670 distclean :: realclean distcheck
1671         $(NOECHO) $(NOOP)
1672
1673 distcheck :
1674         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; fullcheck()"
1675
1676 skipcheck :
1677         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&fullcheck\'; skipcheck()"
1678
1679 manifest :
1680         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest \'&mkmanifest\'; mkmanifest()"
1681 ';
1682 }
1683
1684 =item dist_core (override)
1685
1686 Syntax for invoking F<VMS_Share> differs from that for Unix F<shar>,
1687 so C<shdist> target actions are VMS-specific.
1688
1689 =cut
1690
1691 sub dist_core {
1692     my($self) = @_;
1693 q[
1694 dist : $(DIST_DEFAULT)
1695         $(NOECHO) $(PERL) -le "print 'Warning: $m older than $vf' if -e ($vf = '$(VERSION_FROM)') && -M $vf < -M ($m = '$(MAKEFILE)'"
1696
1697 zipdist : $(DISTVNAME).zip
1698         $(NOECHO) $(NOOP)
1699
1700 $(DISTVNAME).zip : distdir
1701         $(PREOP)
1702         $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) $(SRC)
1703         $(RM_RF) $(DISTVNAME)
1704         $(POSTOP)
1705
1706 $(DISTVNAME).tar$(SUFFIX) : distdir
1707         $(PREOP)
1708         $(TO_UNIX)
1709         $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar $(SRC)
1710         $(RM_RF) $(DISTVNAME)
1711         $(COMPRESS) $(DISTVNAME).tar
1712         $(POSTOP)
1713
1714 shdist : distdir
1715         $(PREOP)
1716         $(SHARE) $(SRC) $(DISTVNAME).share
1717         $(RM_RF) $(DISTVNAME)
1718         $(POSTOP)
1719 ];
1720 }
1721
1722 =item dist_dir (override)
1723
1724 Use VMS-style quoting on command line.
1725
1726 =cut
1727
1728 sub dist_dir {
1729     my($self) = @_;
1730 q{
1731 distdir :
1732         $(RM_RF) $(DISTVNAME)
1733         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::Manifest '/mani/';" \\
1734         -e "manicopy(maniread(),'$(DISTVNAME)','$(DIST_CP)');"
1735 };
1736 }
1737
1738 =item dist_test (override)
1739
1740 Use VMS commands to change default directory, and use VMS-style
1741 quoting on command line.
1742
1743 =cut
1744
1745 sub dist_test {
1746     my($self) = @_;
1747 q{
1748 disttest : distdir
1749         startdir = F$Environment("Default")
1750         Set Default [.$(DISTVNAME)]
1751         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL
1752         $(MMS)
1753         $(MMS) test
1754         Set Default 'startdir'
1755 };
1756 }
1757
1758 # --- Test and Installation Sections ---
1759
1760 =item install (override)
1761
1762 Work around DCL's 255 character limit several times,and use
1763 VMS-style command line quoting in a few cases.
1764
1765 =cut
1766
1767 sub install {
1768     my($self, %attribs) = @_;
1769     my(@m,@docfiles);
1770
1771     if ($self->{EXE_FILES}) {
1772         my($line,$file) = ('','');
1773         foreach $file (@{$self->{EXE_FILES}}) {
1774             $line .= "$file ";
1775             if (length($line) > 128) {
1776                 push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]);
1777                 $line = '';
1778             }
1779         }
1780         push(@docfiles,qq[\t\$(PERL) -e "print '$line'" >>.MM_tmp\n]) if $line;
1781     }
1782
1783     push @m, q[
1784 install :: all pure_install doc_install
1785         $(NOECHO) $(NOOP)
1786
1787 install_perl :: all pure_perl_install doc_perl_install
1788         $(NOECHO) $(NOOP)
1789
1790 install_site :: all pure_site_install doc_site_install
1791         $(NOECHO) $(NOOP)
1792
1793 install_ :: install_site
1794         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1795
1796 pure_install :: pure_$(INSTALLDIRS)_install
1797         $(NOECHO) $(NOOP)
1798
1799 doc_install :: doc_$(INSTALLDIRS)_install
1800         $(NOECHO) $(SAY) "Appending installation info to $(INSTALLARCHLIB)perllocal.pod"
1801
1802 pure__install : pure_site_install
1803         $(NOECHO) $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1804
1805 doc__install : doc_site_install
1806         $(NOECHO} $(SAY) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1807
1808 # This hack brought to you by DCL's 255-character command line limit
1809 pure_perl_install ::
1810         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1811         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1812         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLPRIVLIB) '" >>.MM_tmp
1813         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLARCHLIB) '" >>.MM_tmp
1814         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1815         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1816         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1817         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1818         $(MOD_INSTALL) <.MM_tmp
1819         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1820         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[
1821
1822 # Likewise
1823 pure_site_install ::
1824         $(NOECHO) $(PERL) -e "print 'read ].$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').q[ '" >.MM_tmp
1825         $(NOECHO) $(PERL) -e "print 'write ].$self->catfile('$(INSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').q[ '" >>.MM_tmp
1826         $(NOECHO) $(PERL) -e "print '$(INST_LIB) $(INSTALLSITELIB) '" >>.MM_tmp
1827         $(NOECHO) $(PERL) -e "print '$(INST_ARCHLIB) $(INSTALLSITEARCH) '" >>.MM_tmp
1828         $(NOECHO) $(PERL) -e "print '$(INST_BIN) $(INSTALLBIN) '" >>.MM_tmp
1829         $(NOECHO) $(PERL) -e "print '$(INST_SCRIPT) $(INSTALLSCRIPT) '" >>.MM_tmp
1830         $(NOECHO) $(PERL) -e "print '$(INST_MAN1DIR) $(INSTALLMAN1DIR) '" >>.MM_tmp
1831         $(NOECHO) $(PERL) -e "print '$(INST_MAN3DIR) $(INSTALLMAN3DIR) '" >>.MM_tmp
1832         $(MOD_INSTALL) <.MM_tmp
1833         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
1834         $(NOECHO) $(WARN_IF_OLD_PACKLIST) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1835
1836 # Ditto
1837 doc_perl_install ::
1838         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLPRIVLIB)|'" >.MM_tmp
1839         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1840         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1841 ],@docfiles,
1842 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1843         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1844         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1845         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1846         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1847         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1848
1849 # And again
1850 doc_site_install ::
1851         $(NOECHO) $(PERL) -e "print 'Module $(NAME)|installed into|$(INSTALLSITELIB)|'" >.MM_tmp
1852         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|'" >>.MM_tmp
1853         $(NOECHO) $(PERL) -e "print 'LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|'" >>.MM_tmp
1854 ],@docfiles,
1855 q%      $(NOECHO) $(PERL) -e "print q[@ARGV=split(/\\|/,<STDIN>);]" >.MM2_tmp
1856         $(NOECHO) $(PERL) -e "print q[print '=head3 ',scalar(localtime),': C<',shift,qq[>\\n\\n=over 4\\n\\n];]" >>.MM2_tmp
1857         $(NOECHO) $(PERL) -e "print q[while(($key=shift) && ($val=shift)) ]" >>.MM2_tmp
1858         $(NOECHO) $(PERL) -e "print q[{print qq[=item *\\n\\nC<$key: $val>\\n\\n];}print qq[=back\\n\\n];]" >>.MM2_tmp
1859         $(NOECHO) $(PERL) .MM2_tmp <.MM_tmp >>%.$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
1860         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;,.MM2_tmp;
1861
1862 ];
1863
1864     push @m, q[
1865 uninstall :: uninstall_from_$(INSTALLDIRS)dirs
1866         $(NOECHO) $(NOOP)
1867
1868 uninstall_from_perldirs ::
1869         $(NOECHO) $(UNINSTALL) ].$self->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').q[
1870         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1871         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1872         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1873
1874 uninstall_from_sitedirs ::
1875         $(NOECHO) $(UNINSTALL) ],$self->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist'),"\n",q[
1876         $(NOECHO) $(SAY) "Uninstall is now deprecated and makes no actual changes."
1877         $(NOECHO) $(SAY) "Please check the list above carefully for errors, and manually remove"
1878         $(NOECHO) $(SAY) "the appropriate files.  Sorry for the inconvenience."
1879 ];
1880
1881     join('',@m);
1882 }
1883
1884 =item perldepend (override)
1885
1886 Use VMS-style syntax for files; it's cheaper to just do it directly here
1887 than to have the MM_Unix method call C<catfile> repeatedly.  Also use
1888 config.vms as source of original config data if the Perl distribution
1889 is available; config.sh is an ancillary file under VMS.  Finally, if
1890 we have to rebuild Config.pm, use MM[SK] to do it.
1891
1892 =cut
1893
1894 sub perldepend {
1895     my($self) = @_;
1896     my(@m);
1897
1898     push @m, '
1899 $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
1900 $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
1901 $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
1902 $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
1903 $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
1904 $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
1905 $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
1906
1907 ' if $self->{OBJECT}; 
1908
1909     if ($self->{PERL_SRC}) {
1910         my(@macros);
1911         my($mmsquals) = '$(USEMAKEFILE)[.vms]$(MAKEFILE)';
1912         push(@macros,'__AXP__=1') if $Config{'arch'} eq 'VMS_AXP';
1913         push(@macros,'DECC=1')    if $Config{'vms_cc_type'} eq 'decc';
1914         push(@macros,'GNUC=1')    if $Config{'vms_cc_type'} eq 'gcc';
1915         push(@macros,'SOCKET=1')  if $Config{'d_has_sockets'};
1916         push(@macros,qq["CC=$Config{'cc'}"])  if $Config{'cc'} =~ m!/!;
1917         $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1918         push(@m,q[
1919 # Check for unpropagated config.sh changes. Should never happen.
1920 # We do NOT just update config.h because that is not sufficient.
1921 # An out of date config.h is not fatal but complains loudly!
1922 #$(PERL_INC)config.h : $(PERL_SRC)config.sh
1923 $(PERL_INC)config.h : $(PERL_VMS)config.vms
1924         $(NOECHO) Write Sys$Error "Warning: $(PERL_INC)config.h out of date with $(PERL_VMS)config.vms"
1925
1926 #$(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1927 $(PERL_ARCHLIB)Config.pm : $(PERL_VMS)config.vms $(PERL_VMS)genconfig.pl
1928         $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.vms or genconfig.pl"
1929         olddef = F$Environment("Default")
1930         Set Default $(PERL_SRC)
1931         $(MMS)],$mmsquals,q[ $(MMS$TARGET)
1932         Set Default 'olddef'
1933 ]);
1934     }
1935
1936     push(@m, join(" ", map($self->fixpath($_),values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1937       if %{$self->{XS}};
1938
1939     join('',@m);
1940 }
1941
1942 =item makefile (override)
1943
1944 Use VMS commands and quoting.
1945
1946 =cut
1947
1948 sub makefile {
1949     my($self) = @_;
1950     my(@m,@cmd);
1951     # We do not know what target was originally specified so we
1952     # must force a manual rerun to be sure. But as it should only
1953     # happen very rarely it is not a significant problem.
1954     push @m, q[
1955 $(OBJECT) : $(FIRST_MAKEFILE)
1956 ] if $self->{OBJECT};
1957
1958     push @m,q[
1959 # We take a very conservative approach here, but it\'s worth it.
1960 # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
1961 $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
1962         $(NOECHO) $(SAY) "$(MAKEFILE) out-of-date with respect to $(MMS$SOURCE_LIST)"
1963         $(NOECHO) $(SAY) "Cleaning current config before rebuilding $(MAKEFILE) ..."
1964         - $(MV) $(MAKEFILE) $(MAKEFILE)_old
1965         - $(MMS) $(USEMAKEFILE)$(MAKEFILE)_old clean
1966         $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" Makefile.PL ],join(' ',map(qq["$_"],@ARGV)),q[
1967         $(NOECHO) $(SAY) "$(MAKEFILE) has been rebuilt."
1968         $(NOECHO) $(SAY) "Please run $(MMS) to build the extension."
1969 ];
1970
1971     join('',@m);
1972 }
1973
1974 =item test (override)
1975
1976 Use VMS commands for handling subdirectories.
1977
1978 =cut
1979
1980 sub test {
1981     my($self, %attribs) = @_;
1982     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
1983     my(@m);
1984     push @m,"
1985 TEST_VERBOSE = 0
1986 TEST_TYPE = test_\$(LINKTYPE)
1987 TEST_FILE = test.pl
1988 TESTDB_SW = -d
1989
1990 test :: \$(TEST_TYPE)
1991         \$(NOECHO) \$(NOOP)
1992
1993 testdb :: testdb_\$(LINKTYPE)
1994         \$(NOECHO) \$(NOOP)
1995
1996 ";
1997     foreach(@{$self->{DIR}}){
1998       my($vmsdir) = $self->fixpath($_,1);
1999       push(@m, '        If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir ',"'$vmsdir'",
2000            '; print `$(MMS) $(PASTHRU2) test`'."\n");
2001     }
2002     push(@m, "\t\$(NOECHO) \$(SAY) \"No tests defined for \$(NAME) extension.\"\n")
2003         unless $tests or -f "test.pl" or @{$self->{DIR}};
2004     push(@m, "\n");
2005
2006     push(@m, "test_dynamic :: pure_all\n");
2007     push(@m, $self->test_via_harness('$(FULLPERL)', $tests)) if $tests;
2008     push(@m, $self->test_via_script('$(FULLPERL)', 'test.pl')) if -f "test.pl";
2009     push(@m, "\t\$(NOECHO) \$(NOOP)\n") if (!$tests && ! -f "test.pl");
2010     push(@m, "\n");
2011
2012     push(@m, "testdb_dynamic :: pure_all\n");
2013     push(@m, $self->test_via_script('$(FULLPERL) "$(TESTDB_SW)"', '$(TEST_FILE)'));
2014     push(@m, "\n");
2015
2016     # Occasionally we may face this degenerate target:
2017     push @m, "test_ : test_dynamic\n\n";
2018  
2019     if ($self->needs_linking()) {
2020         push(@m, "test_static :: pure_all \$(MAP_TARGET)\n");
2021         push(@m, $self->test_via_harness('$(MAP_TARGET)', $tests)) if $tests;
2022         push(@m, $self->test_via_script('$(MAP_TARGET)', 'test.pl')) if -f 'test.pl';
2023         push(@m, "\n");
2024         push(@m, "testdb_static :: pure_all \$(MAP_TARGET)\n");
2025         push(@m, $self->test_via_script('$(MAP_TARGET) $(TESTDB_SW)', '$(TEST_FILE)'));
2026         push(@m, "\n");
2027     }
2028     else {
2029         push @m, "test_static :: test_dynamic\n\t\$(NOECHO) \$(NOOP)\n\n";
2030         push @m, "testdb_static :: testdb_dynamic\n\t\$(NOECHO) \$(NOOP)\n";
2031     }
2032
2033     join('',@m);
2034 }
2035
2036 =item test_via_harness (override)
2037
2038 Use VMS-style quoting on command line.
2039
2040 =cut
2041
2042 sub test_via_harness {
2043     my($self,$perl,$tests) = @_;
2044     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_LIB)" "-I$(PERL_ARCHLIB)" \\'."\n\t".
2045     '-e "use Test::Harness qw(&runtests $verbose); $verbose=$(TEST_VERBOSE); runtests @ARGV;" \\'."\n\t$tests\n";
2046 }
2047
2048 =item test_via_script (override)
2049
2050 Use VMS-style quoting on command line.
2051
2052 =cut
2053
2054 sub test_via_script {
2055     my($self,$perl,$script) = @_;
2056     "   $perl".' "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" '.$script.'
2057 ';
2058 }
2059
2060 =item makeaperl (override)
2061
2062 Undertake to build a new set of Perl images using VMS commands.  Since
2063 VMS does dynamic loading, it's not necessary to statically link each
2064 extension into the Perl image, so this isn't the normal build path.
2065 Consequently, it hasn't really been tested, and may well be incomplete.
2066
2067 =cut
2068
2069 sub makeaperl {
2070     my($self, %attribs) = @_;
2071     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
2072       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
2073     my(@m);
2074     push @m, "
2075 # --- MakeMaker makeaperl section ---
2076 MAP_TARGET    = $target
2077 ";
2078     return join '', @m if $self->{PARENT};
2079
2080     my($dir) = join ":", @{$self->{DIR}};
2081
2082     unless ($self->{MAKEAPERL}) {
2083         push @m, q{
2084 $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
2085         $(NOECHO) $(SAY) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
2086         $(NOECHO) $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
2087                 Makefile.PL DIR=}, $dir, q{ \
2088                 MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
2089                 MAKEAPERL=1 NORECURS=1
2090
2091 $(MAP_TARGET) :: $(MAKE_APERL_FILE)
2092         $(MMS)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
2093 };
2094         push @m, map( " \\\n\t\t$_", @ARGV );
2095         push @m, "\n";
2096
2097         return join '', @m;
2098     }
2099
2100
2101     my($linkcmd,@staticopts,@staticpkgs,$extralist,$targdir,$libperldir);
2102
2103     # The front matter of the linkcommand...
2104     $linkcmd = join ' ', $Config{'ld'},
2105             grep($_, @Config{qw(large split ldflags ccdlflags)});
2106     $linkcmd =~ s/\s+/ /g;
2107
2108     # Which *.olb files could we make use of...
2109     local(%olbs);
2110     $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
2111     require File::Find;
2112     File::Find::find(sub {
2113         return unless m/\Q$self->{LIB_EXT}\E$/;
2114         return if m/^libperl/;
2115
2116         if( exists $self->{INCLUDE_EXT} ){
2117                 my $found = 0;
2118                 my $incl;
2119                 my $xx;
2120
2121                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2122                 $xx =~ s,/?$_,,;
2123                 $xx =~ s,/,::,g;
2124
2125                 # Throw away anything not explicitly marked for inclusion.
2126                 # DynaLoader is implied.
2127                 foreach $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
2128                         if( $xx eq $incl ){
2129                                 $found++;
2130                                 last;
2131                         }
2132                 }
2133                 return unless $found;
2134         }
2135         elsif( exists $self->{EXCLUDE_EXT} ){
2136                 my $excl;
2137                 my $xx;
2138
2139                 ($xx = $File::Find::name) =~ s,.*?/auto/,,;
2140                 $xx =~ s,/?$_,,;
2141                 $xx =~ s,/,::,g;
2142
2143                 # Throw away anything explicitly marked for exclusion
2144                 foreach $excl (@{$self->{EXCLUDE_EXT}}){
2145                         return if( $xx eq $excl );
2146                 }
2147         }
2148
2149         $olbs{$ENV{DEFAULT}} = $_;
2150     }, grep( -d $_, @{$searchdirs || []}));
2151
2152     # We trust that what has been handed in as argument will be buildable
2153     $static = [] unless $static;
2154     @olbs{@{$static}} = (1) x @{$static};
2155  
2156     $extra = [] unless $extra && ref $extra eq 'ARRAY';
2157     # Sort the object libraries in inverse order of
2158     # filespec length to try to insure that dependent extensions
2159     # will appear before their parents, so the linker will
2160     # search the parent library to resolve references.
2161     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
2162     # references from [.intuit.dwim]dwim.obj can be found
2163     # in [.intuit]intuit.olb).
2164     for (sort keys %olbs) {
2165         next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
2166         my($dir) = $self->fixpath($_,1);
2167         my($extralibs) = $dir . "extralibs.ld";
2168         my($extopt) = $dir . $olbs{$_};
2169         $extopt =~ s/$self->{LIB_EXT}$/.opt/;
2170         if (-f $extralibs ) {
2171             open LIST,$extralibs or warn $!,next;
2172             push @$extra, <LIST>;
2173             close LIST;
2174         }
2175         if (-f $extopt) {
2176             open OPT,$extopt or die $!;
2177             while (<OPT>) {
2178                 next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
2179                 # ExtUtils::Miniperl expects Unix paths
2180                 (my($pkg) = "$1_$1$self->{LIB_EXT}") =~ s#_*#/#g;
2181                 push @staticpkgs,$pkg;
2182             }
2183             push @staticopts, $extopt;
2184         }
2185     }
2186
2187     $target = "Perl.Exe" unless $target;
2188     ($shrtarget,$targdir) = fileparse($target);
2189     $shrtarget =~ s/^([^.]*)/$1Shr/;
2190     $shrtarget = $targdir . $shrtarget;
2191     $target = "Perlshr.$Config{'dlext'}" unless $target;
2192     $tmp = "[]" unless $tmp;
2193     $tmp = $self->fixpath($tmp,1);
2194     if (@$extra) {
2195         $extralist = join(' ',@$extra);
2196         $extralist =~ s/[,\s\n]+/, /g;
2197     }
2198     else { $extralist = ''; }
2199     if ($libperl) {
2200         unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
2201             print STDOUT "Warning: $libperl not found\n";
2202             undef $libperl;
2203         }
2204     }
2205     unless ($libperl) {
2206         if (defined $self->{PERL_SRC}) {
2207             $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
2208         } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
2209         } else {
2210             print STDOUT "Warning: $libperl not found
2211     If you're going to build a static perl binary, make sure perl is installed
2212     otherwise ignore this warning\n";
2213         }
2214     }
2215     $libperldir = $self->fixpath((fileparse($libperl))[1],1);
2216
2217     push @m, '
2218 # Fill in the target you want to produce if it\'s not perl
2219 MAP_TARGET    = ',$self->fixpath($target),'
2220 MAP_SHRTARGET = ',$self->fixpath($shrtarget),"
2221 MAP_LINKCMD   = $linkcmd
2222 MAP_PERLINC   = ", $perlinc ? map('"$_" ',@{$perlinc}) : '','
2223 # We use the linker options files created with each extension, rather than
2224 #specifying the object files directly on the command line.
2225 MAP_STATIC    = ',@staticopts ? join(' ', @staticopts) : '','
2226 MAP_OPTS    = ',@staticopts ? ','.join(',', map($_.'/Option', @staticopts)) : '',"
2227 MAP_EXTRA     = $extralist
2228 MAP_LIBPERL = ",$self->fixpath($libperl),'
2229 ';
2230
2231
2232     push @m,'
2233 $(MAP_SHRTARGET) : $(MAP_LIBPERL) $(MAP_STATIC) ',"${libperldir}Perlshr_Attr.Opt",'
2234         $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",'
2235 $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmp}perlmain\$(OBJ_EXT) ${tmp}PerlShr.Opt",'
2236         $(MAP_LINKCMD) ',"${tmp}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
2237         $(NOECHO) $(SAY) "To install the new ""$(MAP_TARGET)"" binary, say"
2238         $(NOECHO) $(SAY) "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
2239         $(NOECHO) $(SAY) "To remove the intermediate files, say
2240         $(NOECHO) $(SAY) "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
2241 ';
2242     push @m,'
2243 ',"${tmp}perlmain.c",' : $(MAKEFILE)
2244         $(NOECHO) $(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET)
2245 ';
2246
2247     push @m, q[
2248 # More from the 255-char line length limit
2249 doc_inst_perl :
2250         $(NOECHO) $(PERL) -e "print 'Perl binary $(MAP_TARGET)|'" >.MM_tmp
2251         $(NOECHO) $(PERL) -e "print 'MAP_STATIC|$(MAP_STATIC)|'" >>.MM_tmp
2252         $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
2253         $(NOECHO) $(PERL) -e "print 'MAP_LIBPERL|$(MAP_LIBPERL)|'" >>.MM_tmp
2254         $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(INSTALLARCHLIB)','perllocal.pod').q[
2255         $(NOECHO) Delete/NoLog/NoConfirm .MM_tmp;
2256 ];
2257
2258     push @m, "
2259 inst_perl : pure_inst_perl doc_inst_perl
2260         \$(NOECHO) \$(NOOP)
2261
2262 pure_inst_perl : \$(MAP_TARGET)
2263         $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
2264         $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
2265
2266 clean :: map_clean
2267         \$(NOECHO) \$(NOOP)
2268
2269 map_clean :
2270         \$(RM_F) ${tmp}perlmain\$(OBJ_EXT) ${tmp}perlmain.c \$(MAKEFILE)
2271         \$(RM_F) ${tmp}PerlShr.Opt \$(MAP_TARGET)
2272 ";
2273
2274     join '', @m;
2275 }
2276   
2277 # --- Output postprocessing section ---
2278
2279 =item nicetext (override)
2280
2281 Insure that colons marking targets are preceded by space, in order
2282 to distinguish the target delimiter from a colon appearing as
2283 part of a filespec.
2284
2285 =cut
2286
2287 sub nicetext {
2288
2289     my($self,$text) = @_;
2290     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
2291     $text;
2292 }
2293
2294 1;
2295
2296 __END__
2297