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