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