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