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