File Coverage

lib/ExtUtils/MM_VMS.pm
Criterion Covered Total %
statement 19 813 2.3
branch 1 438 0.2
condition 0 142 0.0
subroutine 7 72 9.7
pod 58 59 98.3
total 85 1524 5.5


line stmt bran cond sub pod time code
1              
2             use strict;
3 4     4   10299 use warnings;
  4         8  
  4         102  
4 4     4   17  
  4         8  
  4         95  
5             use ExtUtils::MakeMaker::Config;
6 4     4   20 require Exporter;
  4         7  
  4         27  
7              
8             BEGIN {
9             # so we can compile the thing on non-VMS platforms.
10             if( $^O eq 'VMS' ) {
11 4 50   4   94 require VMS::Filespec;
12 0         0 VMS::Filespec->import;
13 0         0 }
14             }
15              
16             use File::Basename;
17 4     4   21  
  4         7  
  4         436  
18             our $VERSION = '7.64';
19             $VERSION =~ tr/_//d;
20              
21             require ExtUtils::MM_Any;
22             require ExtUtils::MM_Unix;
23             our @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
24              
25             use ExtUtils::MakeMaker qw($Verbose neatvalue _sprintf562);
26 4     4   27 our $Revision = $ExtUtils::MakeMaker::Revision;
  4         8  
  4         43272  
27              
28              
29             =head1 NAME
30              
31             ExtUtils::MM_VMS - methods to override UN*X behaviour in ExtUtils::MakeMaker
32              
33             =head1 SYNOPSIS
34              
35             Do not use this directly.
36             Instead, use ExtUtils::MM and it will figure out which MM_*
37             class to use for you.
38              
39             =head1 DESCRIPTION
40              
41             See L<ExtUtils::MM_Unix> for a documentation of the methods provided
42             there. This package overrides the implementation of these methods, not
43             the semantics.
44              
45             =head2 Methods always loaded
46              
47             =over 4
48              
49             =item wraplist
50              
51             Converts a list into a string wrapped at approximately 80 columns.
52              
53             =cut
54              
55             my($self) = shift;
56             my($line,$hlen) = ('',0);
57 0     0 1 0  
58 0         0 foreach my $word (@_) {
59             # Perl bug -- seems to occasionally insert extra elements when
60 0         0 # traversing array (scalar(@array) doesn't show them, but
61             # foreach(@array) does) (5.00307)
62             next unless $word =~ /\w/;
63             $line .= ' ' if length($line);
64 0 0       0 if ($hlen > 80) { $line .= "\\\n\t"; $hlen = 0; }
65 0 0       0 $line .= $word;
66 0 0       0 $hlen += length($word) + 2;
  0         0  
  0         0  
67 0         0 }
68 0         0 $line;
69             }
70 0         0  
71              
72             # This isn't really an override. It's just here because ExtUtils::MM_VMS
73             # appears in @MM::ISA before ExtUtils::Liblist::Kid, so if there isn't an ext()
74             # in MM_VMS, then AUTOLOAD is called, and bad things happen. So, we just
75             # mimic inheritance here and hand off to ExtUtils::Liblist::Kid.
76             # XXX This hackery will die soon. --Schwern
77             require ExtUtils::Liblist::Kid;
78             goto &ExtUtils::Liblist::Kid::ext;
79             }
80 0     0 0 0  
81 0         0 =back
82              
83             =head2 Methods
84              
85             Those methods which override default MM_Unix methods are marked
86             "(override)", while methods unique to MM_VMS are marked "(specific)".
87             For overridden methods, documentation is limited to an explanation
88             of why this method overrides the MM_Unix method; see the L<ExtUtils::MM_Unix>
89             documentation for more details.
90              
91             =over 4
92              
93             =item guess_name (override)
94              
95             Try to determine name of extension being built. We begin with the name
96             of the current directory. Since VMS filenames are case-insensitive,
97             however, we look for a F<.pm> file whose name matches that of the current
98             directory (presumably the 'main' F<.pm> file for this extension), and try
99             to find a C<package> statement from which to obtain the Mixed::Case
100             package name.
101              
102             =cut
103              
104             my($self) = @_;
105             my($defname,$defpm,@pm,%xs);
106             local *PM;
107              
108 0     0 1 0 $defname = basename(fileify($ENV{'DEFAULT'}));
109 0         0 $defname =~ s![\d\-_]*\.dir.*$!!; # Clip off .dir;1 suffix, and package version
110 0         0 $defpm = $defname;
111             # Fallback in case for some reason a user has copied the files for an
112 0         0 # extension into a working directory whose name doesn't reflect the
113 0         0 # extension's name. We'll use the name of a unique .pm file, or the
114 0         0 # first .pm file with a matching .xs file.
115             if (not -e "${defpm}.pm") {
116             @pm = glob('*.pm');
117             s/.pm$// for @pm;
118             if (@pm == 1) { ($defpm = $pm[0]) =~ s/.pm$//; }
119 0 0       0 elsif (@pm) {
120 0         0 %xs = map { s/.xs$//; ($_,1) } glob('*.xs'); ## no critic
121 0         0 if (keys %xs) {
122 0 0       0 foreach my $pm (@pm) {
  0 0       0  
123             $defpm = $pm, last if exists $xs{$pm};
124 0         0 }
  0         0  
  0         0  
125 0 0       0 }
126 0         0 }
127 0 0       0 }
128             if (open(my $pm, '<', "${defpm}.pm")){
129             while (<$pm>) {
130             if (/^\s*package\s+([^;]+)/i) {
131             $defname = $1;
132 0 0       0 last;
133 0         0 }
134 0 0       0 }
135 0         0 print "Warning (non-fatal): Couldn't find package name in ${defpm}.pm;\n\t",
136 0         0 "defaulting package name to $defname\n"
137             if eof($pm);
138             close $pm;
139 0 0       0 }
140             else {
141             print "Warning (non-fatal): Couldn't find ${defpm}.pm;\n\t",
142 0         0 "defaulting package name to $defname\n";
143             }
144             $defname =~ s#[\d.\-_]+$##;
145 0         0 $defname;
146             }
147              
148 0         0 =item find_perl (override)
149 0         0  
150             Use VMS file specification syntax and CLI commands to find and
151             invoke Perl images.
152              
153             =cut
154              
155             my($self, $ver, $names, $dirs, $trace) = @_;
156             my($vmsfile,@sdirs,@snames,@cand);
157             my($rslt);
158             my($inabs) = 0;
159             local *TCF;
160 0     0 1 0  
161 0         0 if( $self->{PERL_CORE} ) {
162 0         0 # Check in relative directories first, so we pick up the current
163 0         0 # version of Perl if we're running MakeMaker as part of the main build.
164 0         0 @sdirs = sort { my($absa) = $self->file_name_is_absolute($a);
165             my($absb) = $self->file_name_is_absolute($b);
166 0 0       0 if ($absa && $absb) { return $a cmp $b }
167             else { return $absa ? 1 : ($absb ? -1 : ($a cmp $b)); }
168             } @$dirs;
169 0         0 # Check miniperl before perl, and check names likely to contain
  0         0  
170 0         0 # version numbers before "generic" names, so we pick up an
171 0 0 0     0 # executable that's less likely to be from an old installation.
  0         0  
172 0 0       0 @snames = sort { my($ba) = $a =~ m!([^:>\]/]+)$!; # basename
    0          
173             my($bb) = $b =~ m!([^:>\]/]+)$!;
174             my($ahasdir) = (length($a) - length($ba) > 0);
175             my($bhasdir) = (length($b) - length($bb) > 0);
176             if ($ahasdir and not $bhasdir) { return 1; }
177 0         0 elsif ($bhasdir and not $ahasdir) { return -1; }
  0         0  
178 0         0 else { $bb =~ /\d/ <=> $ba =~ /\d/
179 0         0 or substr($ba,0,1) cmp substr($bb,0,1)
180 0         0 or length($bb) <=> length($ba) } } @$names;
181 0 0 0     0 }
  0 0 0     0  
182 0         0 else {
183 0 0 0     0 @sdirs = @$dirs;
184             @snames = @$names;
185             }
186              
187             # Image names containing Perl version use '_' instead of '.' under VMS
188 0         0 s/\.(\d+)$/_$1/ for @snames;
189 0         0 if ($trace >= 2){
190             print "Looking for perl $ver by these names:\n";
191             print "\t@snames,\n";
192             print "in these dirs:\n";
193 0         0 print "\t@sdirs\n";
194 0 0       0 }
195 0         0 foreach my $dir (@sdirs){
196 0         0 next unless defined $dir; # $self->{PERL_SRC} may be undefined
197 0         0 $inabs++ if $self->file_name_is_absolute($dir);
198 0         0 if ($inabs == 1) {
199             # We've covered relative dirs; everything else is an absolute
200 0         0 # dir (probably an installed location). First, we'll try
201 0 0       0 # potential command names, to see whether we can avoid a long
202 0 0       0 # MCR expression.
203 0 0       0 foreach my $name (@snames) {
204             push(@cand,$name) if $name =~ /^[\w\-\$]+$/;
205             }
206             $inabs++; # Should happen above in next $dir, but just in case...
207             }
208 0         0 foreach my $name (@snames){
209 0 0       0 push @cand, ($name !~ m![/:>\]]!) ? $self->catfile($dir,$name)
210             : $self->fixpath($name,0);
211 0         0 }
212             }
213 0         0 foreach my $name (@cand) {
214 0 0       0 print "Checking $name\n" if $trace >= 2;
215             # If it looks like a potential command, try it without the MCR
216             if ($name =~ /^[\w\-\$]+$/) {
217             open(my $tcf, ">", "temp_mmvms.com")
218 0         0 or die('unable to open temp file');
219 0 0       0 print $tcf "\$ set message/nofacil/nosever/noident/notext\n";
220             print $tcf "\$ $name -e \"require $ver; print \"\"VER_OK\\n\"\"\"\n";
221 0 0       0 close $tcf;
222 0 0       0 $rslt = `\@temp_mmvms.com` ;
223             unlink('temp_mmvms.com');
224 0         0 if ($rslt =~ /VER_OK/) {
225 0         0 print "Using PERL=$name\n" if $trace;
226 0         0 return $name;
227 0         0 }
228 0         0 }
229 0 0       0 next unless $vmsfile = $self->maybe_command($name);
230 0 0       0 $vmsfile =~ s/;[\d\-]*$//; # Clip off version number; we can use a newer version as well
231 0         0 print "Executing $vmsfile\n" if ($trace >= 2);
232             open(my $tcf, '>', "temp_mmvms.com")
233             or die('unable to open temp file');
234 0 0       0 print $tcf "\$ set message/nofacil/nosever/noident/notext\n";
235 0         0 print $tcf "\$ mcr $vmsfile -e \"require $ver; print \"\"VER_OK\\n\"\"\" \n";
236 0 0       0 close $tcf;
237 0 0       0 $rslt = `\@temp_mmvms.com`;
238             unlink('temp_mmvms.com');
239 0         0 if ($rslt =~ /VER_OK/) {
240 0         0 print "Using PERL=MCR $vmsfile\n" if $trace;
241 0         0 return "MCR $vmsfile";
242 0         0 }
243 0         0 }
244 0 0       0 print "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
245 0 0       0 0; # false and not empty
246 0         0 }
247              
248             =item _fixin_replace_shebang (override)
249 0         0  
250 0         0 Helper routine for L<< MM->fixin()|ExtUtils::MM_Unix/fixin >>, overridden
251             because there's no such thing as an
252             actual shebang line that will be interpreted by the shell, so we just prepend
253             $Config{startperl} and preserve the shebang line argument for any switches it
254             may contain.
255              
256             =cut
257              
258             my ( $self, $file, $line ) = @_;
259              
260             my ( undef, $arg ) = split ' ', $line, 2;
261              
262             return $Config{startperl} . "\n" . $Config{sharpbang} . "perl $arg\n";
263             }
264 0     0   0  
265             =item maybe_command (override)
266 0         0  
267             Follows VMS naming conventions for executable files.
268 0         0 If the name passed in doesn't exactly match an executable file,
269             appends F<.Exe> (or equivalent) to check for executable image, and F<.Com>
270             to check for DCL procedure. If this fails, checks directories in DCL$PATH
271             and finally F<Sys$System:> for an executable file having the name specified,
272             with or without the F<.Exe>-equivalent suffix.
273              
274             =cut
275              
276             my($self,$file) = @_;
277             return $file if -x $file && ! -d _;
278             my(@dirs) = ('');
279             my(@exts) = ('',$Config{'exe_ext'},'.exe','.com');
280              
281             if ($file !~ m![/:>\]]!) {
282             for (my $i = 0; defined $ENV{"DCL\$PATH;$i"}; $i++) {
283 0     0 1 0 my $dir = $ENV{"DCL\$PATH;$i"};
284 0 0 0     0 $dir .= ':' unless $dir =~ m%[\]:]$%;
285 0         0 push(@dirs,$dir);
286 0         0 }
287             push(@dirs,'Sys$System:');
288 0 0       0 foreach my $dir (@dirs) {
289 0         0 my $sysfile = "$dir$file";
290 0         0 foreach my $ext (@exts) {
291 0 0       0 return $file if -x "$sysfile$ext" && ! -d _;
292 0         0 }
293             }
294 0         0 }
295 0         0 return 0;
296 0         0 }
297 0         0  
298 0 0 0     0  
299             =item pasthru (override)
300              
301             The list of macro definitions to be passed through must be specified using
302 0         0 the /MACRO qualifier and must not add another /DEFINE qualifier. We prepend
303             our own comma here to the contents of $(PASTHRU_DEFINE) because it is often
304             empty and a comma always present in CCFLAGS would generate a missing
305             qualifier value error.
306              
307             =cut
308              
309             my($self) = shift;
310             my $pasthru = $self->SUPER::pasthru;
311             $pasthru =~ s|(PASTHRU\s*=\s*)|$1/MACRO=(|;
312             $pasthru =~ s|\n\z|)\n|m;
313             $pasthru =~ s|/defi?n?e?=\(?([^\),]+)\)?|,$1|ig;
314              
315             return $pasthru;
316             }
317 0     0 1 0  
318 0         0  
319 0         0 =item pm_to_blib (override)
320 0         0  
321 0         0 VMS wants a dot in every file so we can't have one called 'pm_to_blib',
322             it becomes 'pm_to_blib.' and MMS/K isn't smart enough to know that when
323 0         0 you have a target called 'pm_to_blib' it should look for 'pm_to_blib.'.
324              
325             So in VMS its pm_to_blib.ts.
326              
327             =cut
328              
329             my $self = shift;
330              
331             my $make = $self->SUPER::pm_to_blib;
332              
333             $make =~ s{^pm_to_blib :}{pm_to_blib.ts :}m;
334             $make =~ s{\$\(TOUCH\) pm_to_blib}{\$(TOUCH) pm_to_blib.ts};
335              
336             $make = <<'MAKE' . $make;
337             # Dummy target to match Unix target name; we use pm_to_blib.ts as
338 0     0 1 0 # timestamp file to avoid repeated invocations under VMS
339             pm_to_blib : pm_to_blib.ts
340 0         0 $(NOECHO) $(NOOP)
341              
342 0         0 MAKE
343 0         0  
344             return $make;
345 0         0 }
346              
347              
348             =item perl_script (override)
349              
350             If name passed in doesn't specify a readable file, appends F<.com> or
351             F<.pl> and tries again, since it's customary to have file types on all files
352             under VMS.
353 0         0  
354             =cut
355              
356             my($self,$file) = @_;
357             return $file if -r $file && ! -d _;
358             return "$file.com" if -r "$file.com";
359             return "$file.pl" if -r "$file.pl";
360             return '';
361             }
362              
363              
364             =item replace_manpage_separator
365              
366 0     0 1 0 Use as separator a character which is legal in a VMS-syntax file name.
367 0 0 0     0  
368 0 0       0 =cut
369 0 0       0  
370 0         0 my($self,$man) = @_;
371             $man = unixify($man);
372             $man =~ s#/+#__#g;
373             $man;
374             }
375              
376             =item init_DEST
377              
378             (override) Because of the difficulty concatenating VMS filepaths we
379             must pre-expand the DEST* variables.
380              
381 0     0 1 0 =cut
382 0         0  
383 0         0 my $self = shift;
384 0         0  
385             $self->SUPER::init_DEST;
386              
387             # Expand DEST variables.
388             foreach my $var ($self->installvars) {
389             my $destvar = 'DESTINSTALL'.$var;
390             $self->{$destvar} = $self->eliminate_macros($self->{$destvar});
391             }
392             }
393              
394              
395 0     0 1 0 =item init_DIRFILESEP
396              
397 0         0 No separator between a directory path and a filename on VMS.
398              
399             =cut
400 0         0  
401 0         0 my($self) = shift;
402 0         0  
403             $self->{DIRFILESEP} = '';
404             return 1;
405             }
406              
407              
408             =item init_main (override)
409              
410              
411             =cut
412              
413             my($self) = shift;
414 0     0 1 0  
415             $self->SUPER::init_main;
416 0         0  
417 0         0 $self->{DEFINE} ||= '';
418             if ($self->{DEFINE} ne '') {
419             my(@terms) = split(/\s+/,$self->{DEFINE});
420             my(@defs,@udefs);
421             foreach my $def (@terms) {
422             next unless $def;
423             my $targ = \@defs;
424             if ($def =~ s/^-([DU])//) { # If it was a Unix-style definition
425             $targ = \@udefs if $1 eq 'U';
426             $def =~ s/='(.*)'$/=$1/; # then remove shell-protection ''
427 0     0 1 0 $def =~ s/^'(.*)'$/$1/; # from entire term or argument
428             }
429 0         0 if ($def =~ /=/) {
430             $def =~ s/"/""/g; # Protect existing " from DCL
431 0   0     0 $def = qq["$def"]; # and quote to prevent parsing of =
432 0 0       0 }
433 0         0 push @$targ, $def;
434 0         0 }
435 0         0  
436 0 0       0 $self->{DEFINE} = '';
437 0         0 if (@defs) {
438 0 0       0 $self->{DEFINE} = '/Define=(' . join(',',@defs) . ')';
439 0 0       0 }
440 0         0 if (@udefs) {
441 0         0 $self->{DEFINE} .= '/Undef=(' . join(',',@udefs) . ')';
442             }
443 0 0       0 }
444 0         0 }
445 0         0  
446             =item init_tools (override)
447 0         0  
448             Provide VMS-specific forms of various utility commands.
449              
450 0         0 Sets DEV_NULL to nothing because I don't know how to do it on VMS.
451 0 0       0  
452 0         0 Changes EQUALIZE_TIMESTAMP to set revision date of target file to
453             one second later than source file, since MMK interprets precisely
454 0 0       0 equal revision dates for a source and target file as a sign that the
455 0         0 target needs to be updated.
456              
457             =cut
458              
459             my($self) = @_;
460              
461             $self->{NOOP} = 'Continue';
462             $self->{NOECHO} ||= '@ ';
463              
464             $self->{MAKEFILE} ||= $self->{FIRST_MAKEFILE} || 'Descrip.MMS';
465             $self->{FIRST_MAKEFILE} ||= $self->{MAKEFILE};
466             $self->{MAKE_APERL_FILE} ||= 'Makeaperl.MMS';
467             $self->{MAKEFILE_OLD} ||= $self->eliminate_macros('$(FIRST_MAKEFILE)_old');
468             #
469             # If an extension is not specified, then MMS/MMK assumes an
470             # an extension of .MMS. If there really is no extension,
471             # then a trailing "." needs to be appended to specify a
472             # a null extension.
473             #
474 0     0 1 0 $self->{MAKEFILE} .= '.' unless $self->{MAKEFILE} =~ m/\./;
475             $self->{FIRST_MAKEFILE} .= '.' unless $self->{FIRST_MAKEFILE} =~ m/\./;
476 0         0 $self->{MAKE_APERL_FILE} .= '.' unless $self->{MAKE_APERL_FILE} =~ m/\./;
477 0   0     0 $self->{MAKEFILE_OLD} .= '.' unless $self->{MAKEFILE_OLD} =~ m/\./;
478              
479 0   0     0 $self->{MACROSTART} ||= '/Macro=(';
      0        
480 0   0     0 $self->{MACROEND} ||= ')';
481 0   0     0 $self->{USEMAKEFILE} ||= '/Descrip=';
482 0   0     0  
483             $self->{EQUALIZE_TIMESTAMP} ||= '$(ABSPERLRUN) -we "open F,qq{>>$ARGV[1]};close F;utime(0,(stat($ARGV[0]))[9]+1,$ARGV[1])"';
484              
485             $self->{MOD_INSTALL} ||=
486             $self->oneliner(<<'CODE', ['-MExtUtils::Install']);
487             install([ from_to => {split('\|', <STDIN>)}, verbose => '$(VERBINST)', uninstall_shadows => '$(UNINST)', dir_mode => '$(PERM_DIR)' ]);
488             CODE
489 0 0       0  
490 0 0       0 $self->{UMASK_NULL} = '! ';
491 0 0       0  
492 0 0       0 $self->SUPER::init_tools;
493              
494 0   0     0 # Use the default shell
495 0   0     0 $self->{SHELL} ||= 'Posix';
496 0   0     0  
497             # Redirection on VMS goes before the command, not after as on Unix.
498 0   0     0 # $(DEV_NULL) is used once and its not worth going nuts over making
499             # it work. However, Unix's DEV_NULL is quite wrong for VMS.
500             $self->{DEV_NULL} = '';
501 0   0     0  
502             return;
503             }
504              
505 0         0 =item init_platform (override)
506              
507 0         0 Add PERL_VMS, MM_VMS_REVISION and MM_VMS_VERSION.
508              
509             MM_VMS_REVISION is for backwards compatibility before MM_VMS had a
510 0   0     0 $VERSION.
511              
512             =cut
513              
514             my($self) = shift;
515 0         0  
516             $self->{MM_VMS_REVISION} = $Revision;
517 0         0 $self->{MM_VMS_VERSION} = $VERSION;
518             $self->{PERL_VMS} = $self->catdir($self->{PERL_SRC}, 'VMS')
519             if $self->{PERL_SRC};
520             }
521              
522              
523             =item platform_constants
524              
525             =cut
526              
527             my($self) = shift;
528             my $make_frag = '';
529              
530 0     0 1 0 foreach my $macro (qw(PERL_VMS MM_VMS_REVISION MM_VMS_VERSION))
531             {
532 0         0 next unless defined $self->{$macro};
533 0         0 $make_frag .= "$macro = $self->{$macro}\n";
534             }
535 0 0       0  
536             return $make_frag;
537             }
538              
539              
540             =item init_VERSION (override)
541              
542             Override the *DEFINE_VERSION macros with VMS semantics. Translate the
543             MAKEMAKER filepath to VMS style.
544 0     0 1 0  
545 0         0 =cut
546              
547 0         0 my $self = shift;
548              
549 0 0       0 $self->SUPER::init_VERSION;
550 0         0  
551             $self->{DEFINE_VERSION} = '"$(VERSION_MACRO)=""$(VERSION)"""';
552             $self->{XS_DEFINE_VERSION} = '"$(XS_VERSION_MACRO)=""$(XS_VERSION)"""';
553 0         0 $self->{MAKEMAKER} = vmsify($INC{'ExtUtils/MakeMaker.pm'});
554             }
555              
556              
557             =item constants (override)
558              
559             Fixes up numerous file and directory macros to insure VMS syntax
560             regardless of input syntax. Also makes lists of files
561             comma-separated.
562              
563             =cut
564              
565 0     0 1 0 my($self) = @_;
566              
567 0         0 # Be kind about case for pollution
568             for (@ARGV) { $_ = uc($_) if /POLLUTE/i; }
569 0         0  
570 0         0 # Cleanup paths for directories in MMS macros.
571 0         0 foreach my $macro ( qw [
572             INST_BIN INST_SCRIPT INST_LIB INST_ARCHLIB
573             PERL_LIB PERL_ARCHLIB PERL_ARCHLIBDEP
574             PERL_INC PERL_SRC ],
575             (map { 'INSTALL'.$_ } $self->installvars),
576             (map { 'DESTINSTALL'.$_ } $self->installvars)
577             )
578             {
579             next unless defined $self->{$macro};
580             next if $macro =~ /MAN/ && $self->{$macro} eq 'none';
581             $self->{$macro} = $self->fixpath($self->{$macro},1);
582             }
583              
584 0     0 1 0 # Cleanup paths for files in MMS macros.
585             foreach my $macro ( qw[LIBPERL_A FIRST_MAKEFILE MAKEFILE_OLD
586             MAKE_APERL_FILE MYEXTLIB] )
587 0 0       0 {
  0         0  
588             next unless defined $self->{$macro};
589             $self->{$macro} = $self->fixpath($self->{$macro},0);
590 0         0 }
591              
592             # Fixup files for MMS macros
593             # XXX is this list complete?
594 0         0 for my $macro (qw/
595 0         0 FULLEXT VERSION_FROM
596             / ) {
597             next unless defined $self->{$macro};
598 0 0       0 $self->{$macro} = $self->fixpath($self->{$macro},0);
599 0 0 0     0 }
600 0         0  
601              
602             for my $macro (qw/
603             OBJECT LDFROM
604 0         0 / ) {
605             next unless defined $self->{$macro};
606              
607 0 0       0 # Must expand macros before splitting on unescaped whitespace.
608 0         0 $self->{$macro} = $self->eliminate_macros($self->{$macro});
609             if ($self->{$macro} =~ /(?<!\^)\s/) {
610             $self->{$macro} =~ s/(\\)?\n+\s+/ /g;
611             $self->{$macro} = $self->wraplist(
612             map $self->fixpath($_,0), split /,?(?<!\^)\s+/, $self->{$macro}
613 0         0 );
614             }
615             else {
616 0 0       0 $self->{$macro} = $self->fixpath($self->{$macro},0);
617 0         0 }
618             }
619              
620             for my $macro (qw/ XS MAN1PODS MAN3PODS PM /) {
621 0         0 # Where is the space coming from? --jhi
622             next unless $self ne " " && defined $self->{$macro};
623             my %tmp = ();
624 0 0       0 for my $key (keys %{$self->{$macro}}) {
625             $tmp{$self->fixpath($key,0)} =
626             $self->fixpath($self->{$macro}{$key},0);
627 0         0 }
628 0 0       0 $self->{$macro} = \%tmp;
629 0         0 }
630              
631 0         0 for my $macro (qw/ C O_FILES H /) {
632             next unless defined $self->{$macro};
633             my @tmp = ();
634             for my $val (@{$self->{$macro}}) {
635 0         0 push(@tmp,$self->fixpath($val,0));
636             }
637             $self->{$macro} = \@tmp;
638             }
639 0         0  
640             # mms/k does not define a $(MAKE) macro.
641 0 0 0     0 $self->{MAKE} = '$(MMS)$(MMSQUALIFIERS)';
642 0         0  
643 0         0 return $self->SUPER::constants;
  0         0  
644             }
645 0         0  
646              
647 0         0 =item special_targets
648              
649             Clear the default .SUFFIXES and put in our own list.
650 0         0  
651 0 0       0 =cut
652 0         0  
653 0         0 my $self = shift;
  0         0  
654 0         0  
655             my $make_frag .= <<'MAKE_FRAG';
656 0         0 .SUFFIXES :
657             .SUFFIXES : $(OBJ_EXT) .c .cpp .cxx .xs
658              
659             MAKE_FRAG
660 0         0  
661             return $make_frag;
662 0         0 }
663              
664             =item cflags (override)
665              
666             Bypass shell script and produce qualifiers for CC directly (but warn
667             user if a shell script for this extension exists). Fold multiple
668             /Defines into one, since some C compilers pay attention to only one
669             instance of this qualifier on the command line.
670              
671             =cut
672              
673 0     0 1 0 my($self,$libperl) = @_;
674             my($quals) = $self->{CCFLAGS} || $Config{'ccflags'};
675 0         0 my($definestr,$undefstr,$flagoptstr) = ('','','');
676             my($incstr) = '/Include=($(PERL_INC)';
677             my($name,$sys,@m);
678              
679             ( $name = $self->{NAME} . "_cflags" ) =~ s/:/_/g ;
680             print "Unix shell script ".$Config{"$self->{'BASEEXT'}_cflags"}.
681 0         0 " required to modify CC command for $self->{'BASEEXT'}\n"
682             if ($Config{$name});
683              
684             if ($quals =~ / -[DIUOg]/) {
685             while ($quals =~ / -([Og])(\d*)\b/) {
686             my($type,$lvl) = ($1,$2);
687             $quals =~ s/ -$type$lvl\b\s*//;
688             if ($type eq 'g') { $flagoptstr = '/NoOptimize'; }
689             else { $flagoptstr = '/Optimize' . (defined($lvl) ? "=$lvl" : ''); }
690             }
691             while ($quals =~ / -([DIU])(\S+)/) {
692             my($type,$def) = ($1,$2);
693             $quals =~ s/ -$type$def\s*//;
694 0     0 1 0 $def =~ s/"/""/g;
695 0   0     0 if ($type eq 'D') { $definestr .= qq["$def",]; }
696 0         0 elsif ($type eq 'I') { $incstr .= ',' . $self->fixpath($def,1); }
697 0         0 else { $undefstr .= qq["$def",]; }
698 0         0 }
699             }
700 0         0 if (length $quals and $quals !~ m!/!) {
701             warn "MM_VMS: Ignoring unrecognized CCFLAGS elements \"$quals\"\n";
702             $quals = '';
703 0 0       0 }
704             $definestr .= q["PERL_POLLUTE",] if $self->{POLLUTE};
705 0 0       0 if (length $definestr) { chop($definestr); $quals .= "/Define=($definestr)"; }
706 0         0 if (length $undefstr) { chop($undefstr); $quals .= "/Undef=($undefstr)"; }
707 0         0 # Deal with $self->{DEFINE} here since some C compilers pay attention
708 0         0 # to only one /Define clause on command line, so we have to
709 0 0       0 # conflate the ones from $Config{'ccflags'} and $self->{DEFINE}
  0         0  
710 0 0       0 # ($self->{DEFINE} has already been VMSified in constants() above)
711             if ($self->{DEFINE}) { $quals .= $self->{DEFINE}; }
712 0         0 for my $type (qw(Def Undef)) {
713 0         0 my(@terms);
714 0         0 while ($quals =~ m:/${type}i?n?e?=([^/]+):ig) {
715 0         0 my $term = $1;
716 0 0       0 $term =~ s:^\((.+)\)$:$1:;
  0 0       0  
717 0         0 push @terms, $term;
718 0         0 }
719             if ($type eq 'Def') {
720             push @terms, qw[ $(DEFINE_VERSION) $(XS_DEFINE_VERSION) ];
721 0 0 0     0 }
722 0         0 if (@terms) {
723 0         0 $quals =~ s:/${type}i?n?e?=[^/]+::ig;
724             # PASTHRU_DEFINE will have its own comma
725 0 0       0 $quals .= "/${type}ine=(" . join(',',@terms) . ($type eq 'Def' ? '$(PASTHRU_DEFINE)' : '') . ')';
726 0 0       0 }
  0         0  
  0         0  
727 0 0       0 }
  0         0  
  0         0  
728              
729             $libperl or $libperl = $self->{LIBPERL_A} || "libperl.olb";
730              
731             # Likewise with $self->{INC} and /Include
732 0 0       0 if ($self->{'INC'}) {
  0         0  
733 0         0 my(@includes) = split(/\s+/,$self->{INC});
734 0         0 foreach (@includes) {
735 0         0 s/^-I//;
736 0         0 $incstr .= ','.$self->fixpath($_,1);
737 0         0 }
738 0         0 }
739             $quals .= "$incstr)";
740 0 0       0 # $quals =~ s/,,/,/g; $quals =~ s/\(,/(/g;
741 0         0 $self->{CCFLAGS} = $quals;
742              
743 0 0       0 $self->{PERLTYPE} ||= '';
744 0         0  
745             $self->{OPTIMIZE} ||= $flagoptstr || $Config{'optimize'};
746 0 0       0 if ($self->{OPTIMIZE} !~ m!/!) {
747             if ($self->{OPTIMIZE} =~ m!-g!) { $self->{OPTIMIZE} = '/Debug/NoOptimize' }
748             elsif ($self->{OPTIMIZE} =~ /-O(\d*)/) {
749             $self->{OPTIMIZE} = '/Optimize' . (defined($1) ? "=$1" : '');
750 0 0 0     0 }
751             else {
752             warn "MM_VMS: Can't parse OPTIMIZE \"$self->{OPTIMIZE}\"; using default\n" if length $self->{OPTIMIZE};
753 0 0       0 $self->{OPTIMIZE} = '/Optimize';
754 0         0 }
755 0         0 }
756 0         0  
757 0         0 return $self->{CFLAGS} = qq{
758             CCFLAGS = $self->{CCFLAGS}
759             OPTIMIZE = $self->{OPTIMIZE}
760 0         0 PERLTYPE = $self->{PERLTYPE}
761             };
762 0         0 }
763              
764 0   0     0 =item const_cccmd (override)
765              
766 0   0     0 Adds directives to point C preprocessor to the right place when
      0        
767 0 0       0 handling #include E<lt>sys/foo.hE<gt> directives. Also constructs CC
768 0 0       0 command line a bit differently than MM_Unix method.
  0 0       0  
769              
770 0 0       0 =cut
771              
772             my($self,$libperl) = @_;
773 0 0       0 my(@m);
774 0         0  
775             return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
776             return '' unless $self->needs_linking();
777             if ($Config{'vms_cc_type'} eq 'gcc') {
778 0         0 push @m,'
779             .FIRST
780             ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS GNU_CC_Include:[VMS]';
781             }
782             elsif ($Config{'vms_cc_type'} eq 'vaxc') {
783             push @m,'
784             .FIRST
785             ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").eqs."" Then Define/NoLog SYS Sys$Library
786             ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("VAXC$Include").nes."" Then Define/NoLog SYS VAXC$Include';
787             }
788             else {
789             push @m,'
790             .FIRST
791             ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").eqs."" Then Define/NoLog SYS ',
792             ($Config{'archname'} eq 'VMS_AXP' ? 'Sys$Library' : 'DECC$Library_Include'),'
793             ',$self->{NOECHO},'If F$TrnLnm("Sys").eqs."" .and. F$TrnLnm("DECC$System_Include").nes."" Then Define/NoLog SYS DECC$System_Include';
794 0     0 1 0 }
795 0         0  
796             push(@m, "\n\nCCCMD = $Config{'cc'} \$(CCFLAGS)\$(OPTIMIZE)\n");
797 0 0       0  
798 0 0       0 $self->{CONST_CCCMD} = join('',@m);
799 0 0       0 }
    0          
800              
801              
802 0         0 =item tools_other (override)
803              
804             Throw in some dubious extra macros for Makefile args.
805              
806             Also keep around the old $(SAY) macro in case somebody's using it.
807              
808 0         0 =cut
809              
810             my($self) = @_;
811              
812             # XXX Are these necessary? Does anyone override them? They're longer
813             # than just typing the literal string.
814             my $extra_tools = <<'EXTRA_TOOLS';
815 0 0       0  
816             # Just in case anyone is using the old macro.
817             USEMACROS = $(MACROSTART)
818 0         0 SAY = $(ECHO)
819              
820 0         0 EXTRA_TOOLS
821              
822             return $self->SUPER::tools_other . $extra_tools;
823             }
824              
825             =item init_dist (override)
826              
827             VMSish defaults for some values.
828              
829             macro description default
830              
831             ZIPFLAGS flags to pass to ZIP -Vu
832              
833 0     0 1 0 COMPRESS compression command to gzip
834             use for tarfiles
835             SUFFIX suffix to put on -gz
836             compressed files
837 0         0  
838             SHAR shar command to use vms_share
839              
840             DIST_DEFAULT default target to use to tardist
841             create a distribution
842              
843             DISTVNAME Use VERSION_SYM instead of $(DISTNAME)-$(VERSION_SYM)
844             VERSION for the name
845 0         0  
846             =cut
847              
848             my($self) = @_;
849             $self->{ZIPFLAGS} ||= '-Vu';
850             $self->{COMPRESS} ||= 'gzip';
851             $self->{SUFFIX} ||= '-gz';
852             $self->{SHAR} ||= 'vms_share';
853             $self->{DIST_DEFAULT} ||= 'zipdist';
854              
855             $self->SUPER::init_dist;
856              
857             $self->{DISTVNAME} = "$self->{DISTNAME}-$self->{VERSION_SYM}"
858             unless $self->{ARGS}{DISTVNAME};
859              
860             return;
861             }
862              
863             =item c_o (override)
864              
865             Use VMS syntax on command line. In particular, $(DEFINE) and
866             $(PERL_INC) have been pulled into $(CCCMD). Also use MM[SK] macros.
867              
868             =cut
869              
870             my($self) = @_;
871             return '' unless $self->needs_linking();
872 0     0 1 0 '
873 0   0     0 .c$(OBJ_EXT) :
874 0   0     0 $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
875 0   0     0  
876 0   0     0 .cpp$(OBJ_EXT) :
877 0   0     0 $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cpp /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
878              
879 0         0 .cxx$(OBJ_EXT) :
880             $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).cxx /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
881              
882 0 0       0 ';
883             }
884 0         0  
885             =item xs_c (override)
886              
887             Use MM[SK] macros.
888              
889             =cut
890              
891             my($self) = @_;
892             return '' unless $self->needs_linking();
893             '
894             .xs.c :
895 0     0 1 0 $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).xsc
896 0 0       0 $(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
897 0         0 ';
898             }
899              
900             =item xs_o (override)
901              
902             Use MM[SK] macros, and VMS command line for C compiler.
903              
904             =cut
905              
906             my ($self) = @_;
907             return '' unless $self->needs_linking();
908             my $frag = '
909             .xs$(OBJ_EXT) :
910             $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).xsc
911             $(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
912             $(CCCMD) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
913             ';
914             if ($self->{XSMULTI}) {
915             for my $ext ($self->_xs_list_basenames) {
916             my $version = $self->parse_version("$ext.pm");
917 0     0 1 0 my $ccflags = $self->{CCFLAGS};
918 0 0       0 $ccflags =~ s/\$\(DEFINE_VERSION\)/\"VERSION_MACRO=\\"\"$version\\"\"/;
919 0         0 $ccflags =~ s/\$\(XS_DEFINE_VERSION\)/\"XS_VERSION_MACRO=\\"\"$version\\"\"/;
920             $self->_xsbuild_replace_macro($ccflags, 'xs', $ext, 'INC');
921             $self->_xsbuild_replace_macro($ccflags, 'xs', $ext, 'DEFINE');
922              
923             $frag .= _sprintf562 <<'EOF', $ext, $ccflags;
924              
925             %1$s$(OBJ_EXT) : %1$s.xs
926             $(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs > $(MMS$TARGET_NAME).xsc
927             $(MV) $(MMS$TARGET_NAME).xsc $(MMS$TARGET_NAME).c
928             $(CC)%2$s$(OPTIMIZE) $(CCCDLFLAGS) $(MMS$TARGET_NAME).c /OBJECT=$(MMS$TARGET_NAME)$(OBJ_EXT)
929             EOF
930             }
931             }
932             $frag;
933 0     0 1 0 }
934 0 0       0  
935 0         0 =item _xsbuild_replace_macro (override)
936              
937             There is no simple replacement possible since a qualifier and all its
938             subqualifiers must be considered together, so we use our own utility
939             routine for the replacement.
940              
941 0 0       0 =cut
942 0         0  
943 0         0 my ($self, undef, $xstype, $ext, $varname) = @_;
944 0         0 my $value = $self->_xsbuild_value($xstype, $ext, $varname);
945 0         0 return unless defined $value;
946 0         0 $_[1] = _vms_replace_qualifier($self, $_[1], $value, $varname);
947 0         0 }
948 0         0  
949             =item _xsbuild_value (override)
950 0         0  
951             Convert the extension spec to Unix format, as that's what will
952             match what's in the XSBUILD data structure.
953              
954             =cut
955              
956             my ($self, $xstype, $ext, $varname) = @_;
957             $ext = unixify($ext);
958             return $self->SUPER::_xsbuild_value($xstype, $ext, $varname);
959 0         0 }
960              
961             my ($self, $flags, $newflag, $macro) = @_;
962             my $qual_type;
963             my $type_suffix;
964             my $quote_subquals = 0;
965             my @subquals_new = split /\s+/, $newflag;
966              
967             if ($macro eq 'DEFINE') {
968             $qual_type = 'Def';
969             $type_suffix = 'ine';
970             map { $_ =~ s/^-D// } @subquals_new;
971 0     0   0 $quote_subquals = 1;
972 0         0 }
973 0 0       0 elsif ($macro eq 'INC') {
974 0         0 $qual_type = 'Inc';
975             $type_suffix = 'lude';
976             map { $_ =~ s/^-I//; $_ = $self->fixpath($_) } @subquals_new;
977             }
978              
979             my @subquals = ();
980             while ($flags =~ m:/${qual_type}\S{0,4}=([^/]+):ig) {
981             my $term = $1;
982             $term =~ s/\"//g;
983             $term =~ s:^\((.+)\)$:$1:;
984             push @subquals, split /,/, $term;
985 0     0   0 }
986 0         0 for my $new (@subquals_new) {
987 0         0 my ($sq_new, $sqval_new) = split /=/, $new;
988             my $replaced_old = 0;
989             for my $old (@subquals) {
990             my ($sq, $sqval) = split /=/, $old;
991 0     0   0 if ($sq_new eq $sq) {
992 0         0 $old = $sq_new;
993             $old .= '=' . $sqval_new if defined($sqval_new) and length($sqval_new);
994 0         0 $replaced_old = 1;
995 0         0 last;
996             }
997 0 0       0 }
    0          
998 0         0 push @subquals, $new unless $replaced_old;
999 0         0 }
1000 0         0  
  0         0  
1001 0         0 if (@subquals) {
1002             $flags =~ s:/${qual_type}\S{0,4}=[^/]+::ig;
1003             # add quotes if requested but not for unexpanded macros
1004 0         0 map { $_ = qq/"$_"/ if $_ !~ m/^\$\(/ } @subquals if $quote_subquals;
1005 0         0 $flags .= "/${qual_type}$type_suffix=(" . join(',',@subquals) . ')';
1006 0         0 }
  0         0  
  0         0  
1007              
1008             return $flags;
1009 0         0 }
1010 0         0  
1011 0         0  
1012 0         0 '.opt';
1013 0         0 }
1014 0         0  
1015             =item dlsyms (override)
1016 0         0  
1017 0         0 Create VMS linker options files specifying universal symbols for this
1018 0         0 extension's shareable image(s), and listing other shareable images or
1019 0         0 libraries to which it should be linked.
1020 0         0  
1021 0 0       0 =cut
1022 0         0  
1023 0 0 0     0 my ($self, %attribs) = @_;
1024 0         0 return '' unless $self->needs_linking;
1025 0         0 $self->xs_dlsyms_iterator;
1026             }
1027              
1028 0 0       0 my ($self, $attribs, $target, $dep, $name, $dlbase, $funcs, $funclist, $imports, $vars, $extra) = @_;
1029             my @m;
1030             my $instloc;
1031 0 0       0 if ($self->{XSMULTI}) {
1032 0         0 my ($v, $d, $f) = File::Spec->splitpath($target);
1033             my @d = File::Spec->splitdir($d);
1034 0 0       0 shift @d if $d[0] eq 'lib';
  0 0       0  
1035 0         0 $instloc = $self->catfile('$(INST_ARCHLIB)', 'auto', @d, $f);
1036             push @m,"\ndynamic :: $instloc\n\t\$(NOECHO) \$(NOOP)\n"
1037             unless $self->{SKIPHASH}{'dynamic'};
1038 0         0 push @m,"\nstatic :: $instloc\n\t\$(NOECHO) \$(NOOP)\n"
1039             unless $self->{SKIPHASH}{'static'};
1040             push @m, "\n", sprintf <<'EOF', $instloc, $target;
1041             %s : %s
1042             $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1043 0     0 1 0 EOF
1044             }
1045             else {
1046             push @m,"\ndynamic :: \$(INST_ARCHAUTODIR)$self->{BASEEXT}.opt\n\t\$(NOECHO) \$(NOOP)\n"
1047             unless $self->{SKIPHASH}{'dynamic'};
1048             push @m,"\nstatic :: \$(INST_ARCHAUTODIR)$self->{BASEEXT}.opt\n\t\$(NOECHO) \$(NOOP)\n"
1049             unless $self->{SKIPHASH}{'static'};
1050             push @m, "\n", sprintf <<'EOF', $target;
1051             $(INST_ARCHAUTODIR)$(BASEEXT).opt : %s
1052             $(CP) $(MMS$SOURCE) $(MMS$TARGET)
1053             EOF
1054             }
1055 0     0 1 0 push @m,
1056 0 0       0 "\n$target : $dep\n\t",
1057 0         0 q!$(PERLRUN) -MExtUtils::Mksymlists -e "Mksymlists('NAME'=>'!, $name,
1058             q!', 'DLBASE' => '!,$dlbase,
1059             q!', 'DL_FUNCS' => !,neatvalue($funcs),
1060             q!, 'FUNCLIST' => !,neatvalue($funclist),
1061 0     0 1 0 q!, 'IMPORTS' => !,neatvalue($imports),
1062 0         0 q!, 'DL_VARS' => !, neatvalue($vars);
1063             push @m, $extra if defined $extra;
1064 0 0       0 push @m, qq!);"\n\t!;
1065 0         0 # Can't use dlbase as it's been through mod2fname.
1066 0         0 my $olb_base = basename($target, '.opt');
1067 0 0       0 if ($self->{XSMULTI}) {
1068 0         0 # We've been passed everything but the kitchen sink -- and the location of the
1069             # static library we're using to build the dynamic library -- so concoct that
1070 0 0       0 # location from what we do have.
1071             my $olb_dir = $self->catdir(dirname($instloc), $olb_base);
1072 0 0       0 push @m, qq!\$(PERL) -e "print ""${olb_dir}${olb_base}\$(LIB_EXT)/Include=!;
1073 0         0 push @m, ($Config{d_vms_case_sensitive_symbols} ? uc($olb_base) : $olb_base);
1074             push @m, '\n' . $olb_dir . $olb_base . '$(LIB_EXT)/Library\n"";" >>$(MMS$TARGET)',"\n";
1075             }
1076             else {
1077             push @m, qq!\$(PERL) -e "print ""\$(INST_ARCHAUTODIR)${olb_base}\$(LIB_EXT)/Include=!;
1078             if ($self->{OBJECT} =~ /\bBASEEXT\b/ or
1079             $self->{OBJECT} =~ /\b$self->{BASEEXT}\b/i) {
1080 0 0       0 push @m, ($Config{d_vms_case_sensitive_symbols}
1081             ? uc($self->{BASEEXT}) :'$(BASEEXT)');
1082 0 0       0 }
1083 0         0 else { # We don't have a "main" object file, so pull 'em all in
1084             # Upcase module names if linker is being case-sensitive
1085             my($upcase) = $Config{d_vms_case_sensitive_symbols};
1086             my(@omods) = split ' ', $self->eliminate_macros($self->{OBJECT});
1087             for (@omods) {
1088 0         0 s/\.[^.]*$//; # Trim off file type
1089             s[\$\(\w+_EXT\)][]; # even as a macro
1090             s/.*[:>\/\]]//; # Trim off dir spec
1091             $_ = uc if $upcase;
1092             };
1093             my(@lines);
1094             my $tmp = shift @omods;
1095             foreach my $elt (@omods) {
1096 0 0       0 $tmp .= ",$elt";
1097 0         0 if (length($tmp) > 80) { push @lines, $tmp; $tmp = ''; }
1098             }
1099 0         0 push @lines, $tmp;
1100 0 0       0 push @m, '(', join( qq[, -\\n\\t"";" >>\$(MMS\$TARGET)\n\t\$(PERL) -e "print ""], @lines),')';
1101             }
1102             push @m, '\n$(INST_ARCHAUTODIR)' . $olb_base . '$(LIB_EXT)/Library\n"";" >>$(MMS$TARGET)',"\n";
1103             }
1104 0         0 if (length $self->{LDLOADLIBS}) {
1105 0         0 my($line) = '';
1106 0 0       0 foreach my $lib (split ' ', $self->{LDLOADLIBS}) {
1107 0         0 $lib =~ s%\$%\\\$%g; # Escape '$' in VMS filespecs
1108             if (length($line) + length($lib) > 160) {
1109             push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n";
1110 0         0 $line = $lib . '\n';
1111 0 0 0     0 }
1112             else { $line .= $lib . '\n'; }
1113             }
1114 0 0       0 push @m, "\t\$(PERL) -e \"print qq{$line}\" >>\$(MMS\$TARGET)\n" if $line;
1115             }
1116             join '', @m;
1117             }
1118 0         0  
1119 0         0  
1120 0         0 =item xs_obj_opt
1121 0         0  
1122 0         0 Override to fixup -o flags.
1123 0         0  
1124 0 0       0 =cut
1125              
1126 0         0 my ($self, $output_file) = @_;
1127 0         0 "/OBJECT=$output_file";
1128 0         0 }
1129 0         0  
1130 0 0       0 =item dynamic_lib (override)
  0         0  
  0         0  
1131              
1132 0         0 Use VMS Link command.
1133 0         0  
1134             =cut
1135 0         0  
1136             my ($self, $attribs) = @_;
1137 0 0       0 my $otherldflags = $attribs->{OTHERLDFLAGS} || "";
1138 0         0 my $inst_dynamic_dep = $attribs->{INST_DYNAMIC_DEP} || "";
1139 0         0 sprintf <<'EOF', $otherldflags, $inst_dynamic_dep;
1140 0         0 # This section creates the dynamically loadable objects from relevant
1141 0 0       0 # objects and possibly $(MYEXTLIB).
1142 0         0 OTHERLDFLAGS = %s
1143 0         0 INST_DYNAMIC_DEP = %s
1144             EOF
1145 0         0 }
1146              
1147 0 0       0 my ($self, $attribs, $from, $to, $todir, $ldfrom, $exportlist) = @_;
1148             my $shr = $Config{'dbgprefix'} . 'PerlShr';
1149 0         0 $exportlist =~ s/.def$/.opt/; # it's a linker options file
1150             # 1 2 3 4 5
1151             _sprintf562 <<'EOF', $to, $todir, $exportlist, $shr, "$shr Sys\$Share:$shr.$Config{'dlext'}";
1152             %1$s : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt %2$s$(DFSEP).exists %3$s $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP)
1153             If F$TrnLNm("%4$s").eqs."" Then Define/NoLog/User %5$s
1154             Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) %3$s/Option,$(PERL_INC)perlshr_attr.opt/Option
1155             EOF
1156             }
1157              
1158             =item xs_make_static_lib (override)
1159              
1160 0     0 1 0 Use VMS commands to manipulate object library.
1161 0         0  
1162             =cut
1163              
1164             my ($self, $object, $to, $todir) = @_;
1165              
1166             my @objects;
1167             if ($self->{XSMULTI}) {
1168             # The extension name should be the main object file name minus file type.
1169             my $lib = $object;
1170             $lib =~ s/\$\(OBJ_EXT\)\z//;
1171 0     0 1 0 my $override = $self->_xsbuild_value('xs', $lib, 'OBJECT');
1172 0   0     0 $object = $override if defined $override;
1173 0   0     0 @objects = map { $self->fixpath($_,0) } split /(?<!\^)\s+/, $object;
1174 0         0 }
1175             else {
1176             push @objects, $object;
1177             }
1178              
1179             my @m;
1180             for my $obj (@objects) {
1181             push(@m, sprintf "\n%s : %s\$(DFSEP).exists", $obj, $todir);
1182             }
1183 0     0 1 0 push(@m, sprintf "\n\n%s : %s \$(MYEXTLIB)\n", $to, (join ' ', @objects));
1184 0         0  
1185 0         0 # If this extension has its own library (eg SDBM_File)
1186             # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
1187 0         0 push(@m, "\t",'$(CP) $(MYEXTLIB) $(MMS$TARGET)',"\n") if $self->{MYEXTLIB};
1188              
1189             push(@m,"\t",'If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)',"\n");
1190              
1191             # if there was a library to copy, then we can't use MMS$SOURCE_LIST,
1192             # 'cause it's a library and you can't stick them in other libraries.
1193             # In that case, we use $OBJECT instead and hope for the best
1194             if ($self->{MYEXTLIB}) {
1195             for my $obj (@objects) {
1196             push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) ' . $obj,"\n");
1197             }
1198             }
1199             else {
1200             push(@m,"\t",'Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)',"\n");
1201 0     0 1 0 }
1202              
1203 0         0 push @m, "\t\$(NOECHO) \$(PERL) -e 1 >\$(INST_ARCHAUTODIR)extralibs.ld\n";
1204 0 0       0 foreach my $lib (split ' ', $self->{EXTRALIBS}) {
1205             push(@m,"\t",'$(NOECHO) $(PERL) -e "print qq{',$lib,'\n}" >>$(INST_ARCHAUTODIR)extralibs.ld',"\n");
1206 0         0 }
1207 0         0 join('',@m);
1208 0         0 }
1209 0 0       0  
1210 0         0  
  0         0  
1211             =item static_lib_pure_cmd (override)
1212              
1213 0         0 Use VMS commands to manipulate object library.
1214              
1215             =cut
1216 0         0  
1217 0         0 my ($self, $from) = @_;
1218 0         0  
1219             sprintf <<'MAKE_FRAG', $from;
1220 0         0 If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
1221             Library/Object/Replace $(MMS$TARGET) %s
1222             MAKE_FRAG
1223             }
1224 0 0       0  
1225             =item xs_static_lib_is_xs
1226 0         0  
1227             =cut
1228              
1229             return 1;
1230             }
1231 0 0       0  
1232 0         0 =item extra_clean_files
1233 0         0  
1234             Clean up some OS specific files. Plus the temp file used to shorten
1235             a lot of commands. And the name mangler database.
1236              
1237 0         0 =cut
1238              
1239             return qw(
1240 0         0 *.Map *.Dmp *.Lis *.cpp *.$(DLEXT) *.Opt $(BASEEXT).bso
1241 0         0 .MM_Tmp cxx_repository
1242 0         0 );
1243             }
1244 0         0  
1245              
1246             =item zipfile_target
1247              
1248             =item tarfile_target
1249              
1250             =item shdist_target
1251              
1252             Syntax for invoking shar, tar and zip differs from that for Unix.
1253              
1254             =cut
1255 0     0 1 0  
1256             my($self) = shift;
1257 0         0  
1258             return <<'MAKE_FRAG';
1259             $(DISTVNAME).zip : distdir
1260             $(PREOP)
1261             $(ZIP) "$(ZIPFLAGS)" $(MMS$TARGET) [.$(DISTVNAME)...]*.*;
1262             $(RM_RF) $(DISTVNAME)
1263             $(POSTOP)
1264             MAKE_FRAG
1265             }
1266              
1267             my($self) = shift;
1268 0     0 1 0  
1269             return <<'MAKE_FRAG';
1270             $(DISTVNAME).tar$(SUFFIX) : distdir
1271             $(PREOP)
1272             $(TO_UNIX)
1273             $(TAR) "$(TARFLAGS)" $(DISTVNAME).tar [.$(DISTVNAME)...]
1274             $(RM_RF) $(DISTVNAME)
1275             $(COMPRESS) $(DISTVNAME).tar
1276             $(POSTOP)
1277             MAKE_FRAG
1278             }
1279 0     0 1 0  
1280             my($self) = shift;
1281              
1282             return <<'MAKE_FRAG';
1283             shdist : distdir
1284             $(PREOP)
1285             $(SHAR) [.$(DISTVNAME)...]*.*; $(DISTVNAME).share
1286             $(RM_RF) $(DISTVNAME)
1287             $(POSTOP)
1288             MAKE_FRAG
1289             }
1290              
1291              
1292             # --- Test and Installation Sections ---
1293              
1294             =item install (override)
1295              
1296             Work around DCL's 255 character limit several times,and use
1297 0     0 1 0 VMS-style command line quoting in a few cases.
1298              
1299 0         0 =cut
1300              
1301             my($self, %attribs) = @_;
1302             my(@m);
1303              
1304             push @m, q[
1305             install :: all pure_install doc_install
1306             $(NOECHO) $(NOOP)
1307              
1308             install_perl :: all pure_perl_install doc_perl_install
1309 0     0 1 0 $(NOECHO) $(NOOP)
1310              
1311 0         0 install_site :: all pure_site_install doc_site_install
1312             $(NOECHO) $(NOOP)
1313              
1314             install_vendor :: all pure_vendor_install doc_vendor_install
1315             $(NOECHO) $(NOOP)
1316              
1317             pure_install :: pure_$(INSTALLDIRS)_install
1318             $(NOECHO) $(NOOP)
1319              
1320             doc_install :: doc_$(INSTALLDIRS)_install
1321             $(NOECHO) $(NOOP)
1322              
1323 0     0 1 0 pure__install : pure_site_install
1324             $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1325 0         0  
1326             doc__install : doc_site_install
1327             $(NOECHO) $(ECHO) "INSTALLDIRS not defined, defaulting to INSTALLDIRS=site"
1328              
1329             # This hack brought to you by DCL's 255-character command line limit
1330             pure_perl_install ::
1331             ];
1332             push @m,
1333             q[ $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(PERL_ARCHLIB)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1334             $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLARCHLIB)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
1335             ] unless $self->{NO_PACKLIST};
1336              
1337             push @m,
1338             q[ $(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLPRIVLIB)|" >>.MM_tmp
1339             $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLARCHLIB)|" >>.MM_tmp
1340             $(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLBIN)|" >>.MM_tmp
1341             $(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1342             $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) " >>.MM_tmp
1343             $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLMAN3DIR)" >>.MM_tmp
1344             $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1345 0     0 1 0 $(NOECHO) $(RM_F) .MM_tmp
1346 0         0 $(NOECHO) $(WARN_IF_OLD_PACKLIST) "].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q["
1347              
1348 0         0 # Likewise
1349             pure_site_install ::
1350             ];
1351             push @m,
1352             q[ $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(SITEARCHEXP)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1353             $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLSITEARCH)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
1354             ] unless $self->{NO_PACKLIST};
1355              
1356             push @m,
1357             q[ $(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLSITELIB)|" >>.MM_tmp
1358             $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLSITEARCH)|" >>.MM_tmp
1359             $(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLSITEBIN)|" >>.MM_tmp
1360             $(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1361             $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR)|$(DESTINSTALLSITEMAN1DIR)|" >>.MM_tmp
1362             $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLSITEMAN3DIR)" >>.MM_tmp
1363             $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1364             $(NOECHO) $(RM_F) .MM_tmp
1365             $(NOECHO) $(WARN_IF_OLD_PACKLIST) "].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q["
1366              
1367             pure_vendor_install ::
1368             ];
1369             push @m,
1370             q[ $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'read|'.File::Spec->catfile('$(VENDORARCHEXP)','auto','$(FULLEXT)','.packlist').'|'" >.MM_tmp
1371             $(NOECHO) $(PERLRUN) "-MFile::Spec" -e "print 'write|'.File::Spec->catfile('$(DESTINSTALLVENDORARCH)','auto','$(FULLEXT)','.packlist').'|'" >>.MM_tmp
1372             ] unless $self->{NO_PACKLIST};
1373              
1374             push @m,
1375             q[ $(NOECHO) $(ECHO_N) "$(INST_LIB)|$(DESTINSTALLVENDORLIB)|" >>.MM_tmp
1376             $(NOECHO) $(ECHO_N) "$(INST_ARCHLIB)|$(DESTINSTALLVENDORARCH)|" >>.MM_tmp
1377             $(NOECHO) $(ECHO_N) "$(INST_BIN)|$(DESTINSTALLVENDORBIN)|" >>.MM_tmp
1378             $(NOECHO) $(ECHO_N) "$(INST_SCRIPT)|$(DESTINSTALLSCRIPT)|" >>.MM_tmp
1379 0 0       0 $(NOECHO) $(ECHO_N) "$(INST_MAN1DIR)|$(DESTINSTALLVENDORMAN1DIR)|" >>.MM_tmp
1380             $(NOECHO) $(ECHO_N) "$(INST_MAN3DIR)|$(DESTINSTALLVENDORMAN3DIR)" >>.MM_tmp
1381             $(NOECHO) $(MOD_INSTALL) <.MM_tmp
1382             $(NOECHO) $(RM_F) .MM_tmp
1383              
1384             ];
1385              
1386             push @m, q[
1387             # Ditto
1388             doc_perl_install ::
1389             $(NOECHO) $(NOOP)
1390 0         0  
1391             # And again
1392             doc_site_install ::
1393             $(NOECHO) $(NOOP)
1394              
1395             doc_vendor_install ::
1396             $(NOECHO) $(NOOP)
1397              
1398 0 0       0 ] if $self->{NO_PERLLOCAL};
1399              
1400             push @m, q[
1401             # Ditto
1402             doc_perl_install ::
1403             $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1404             $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1405             $(NOECHO) $(ECHO_N) "installed into|$(INSTALLPRIVLIB)|" >.MM_tmp
1406             $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1407             $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1408             $(NOECHO) $(RM_F) .MM_tmp
1409 0         0  
1410             # And again
1411             doc_site_install ::
1412             $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1413             $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1414             $(NOECHO) $(ECHO_N) "installed into|$(INSTALLSITELIB)|" >.MM_tmp
1415             $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1416 0 0       0 $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1417             $(NOECHO) $(RM_F) .MM_tmp
1418 0         0  
1419             doc_vendor_install ::
1420             $(NOECHO) $(ECHO) "Appending installation info to ].$self->catfile($self->{DESTINSTALLARCHLIB}, 'perllocal.pod').q["
1421             $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1422             $(NOECHO) $(ECHO_N) "installed into|$(INSTALLVENDORLIB)|" >.MM_tmp
1423             $(NOECHO) $(ECHO_N) "LINKTYPE|$(LINKTYPE)|VERSION|$(VERSION)|EXE_FILES|$(EXE_FILES) " >>.MM_tmp
1424             $(NOECHO) $(DOC_INSTALL) "Module" "$(NAME)" <.MM_tmp >>].$self->catfile($self->{DESTINSTALLARCHLIB},'perllocal.pod').q[
1425             $(NOECHO) $(RM_F) .MM_tmp
1426              
1427             ] unless $self->{NO_PERLLOCAL};
1428              
1429             push @m, q[
1430             uninstall :: uninstall_from_$(INSTALLDIRS)dirs
1431             $(NOECHO) $(NOOP)
1432              
1433             uninstall_from_perldirs ::
1434             $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{PERL_ARCHLIB},'auto',$self->{FULLEXT},'.packlist').q[
1435              
1436             uninstall_from_sitedirs ::
1437             $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{SITEARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1438              
1439             uninstall_from_vendordirs ::
1440             $(NOECHO) $(UNINSTALL) ].$self->catfile($self->{VENDORARCHEXP},'auto',$self->{FULLEXT},'.packlist').q[
1441             ];
1442 0 0       0  
1443             join('',@m);
1444             }
1445              
1446             =item perldepend (override)
1447              
1448             Use VMS-style syntax for files; it's cheaper to just do it directly here
1449             than to have the L<MM_Unix|ExtUtils::MM_Unix> method call C<catfile>
1450             repeatedly. Also, if we have to rebuild Config.pm, use MM[SK] to do it.
1451              
1452             =cut
1453              
1454             my($self) = @_;
1455             my(@m);
1456              
1457             if ($self->{OBJECT}) {
1458             # Need to add an object file dependency on the perl headers.
1459             # this is very important for XS modules in perl.git development.
1460              
1461             push @m, $self->_perl_header_files_fragment(""); # empty separator on VMS as its in the $(PERL_INC)
1462             }
1463              
1464             if ($self->{PERL_SRC}) {
1465             my(@macros);
1466             my($mmsquals) = '$(USEMAKEFILE)[.vms]$(FIRST_MAKEFILE)';
1467             push(@macros,'__AXP__=1') if $Config{'archname'} eq 'VMS_AXP';
1468             push(@macros,'DECC=1') if $Config{'vms_cc_type'} eq 'decc';
1469             push(@macros,'GNUC=1') if $Config{'vms_cc_type'} eq 'gcc';
1470             push(@macros,'SOCKET=1') if $Config{'d_has_sockets'};
1471 0 0       0 push(@macros,qq["CC=$Config{'cc'}"]) if $Config{'cc'} =~ m!/!;
1472             $mmsquals .= '$(USEMACROS)' . join(',',@macros) . '$(MACROEND)' if @macros;
1473             push(@m,q[
1474             # Check for unpropagated config.sh changes. Should never happen.
1475             # We do NOT just update config.h because that is not sufficient.
1476             # An out of date config.h is not fatal but complains loudly!
1477             $(PERL_INC)config.h : $(PERL_SRC)config.sh
1478             $(NOOP)
1479              
1480             $(PERL_ARCHLIB)Config.pm : $(PERL_SRC)config.sh
1481             $(NOECHO) Write Sys$Error "$(PERL_ARCHLIB)Config.pm may be out of date with config.h or genconfig.pl"
1482             olddef = F$Environment("Default")
1483             Set Default $(PERL_SRC)
1484 0         0 $(MMS)],$mmsquals,);
1485             if ($self->{PERL_ARCHLIB} =~ m|\[-| && $self->{PERL_SRC} =~ m|(\[-+)|) {
1486             my($prefix,$target) = ($1,$self->fixpath('$(PERL_ARCHLIB)Config.pm',0));
1487 0         0 $target =~ s/\Q$prefix/[/;
1488             push(@m," $target");
1489             }
1490             else { push(@m,' $(MMS$TARGET)'); }
1491             push(@m,q[
1492             Set Default 'olddef'
1493             ]);
1494             }
1495              
1496             push(@m, join(" ", map($self->fixpath($_,0),sort values %{$self->{XS}}))." : \$(XSUBPPDEPS)\n")
1497             if %{$self->{XS}};
1498              
1499 0     0 1 0 join('',@m);
1500 0         0 }
1501              
1502 0 0       0  
1503             =item makeaperl (override)
1504              
1505             Undertake to build a new set of Perl images using VMS commands. Since
1506 0         0 VMS does dynamic loading, it's not necessary to statically link each
1507             extension into the Perl image, so this isn't the normal build path.
1508             Consequently, it hasn't really been tested, and may well be incomplete.
1509 0 0       0  
1510 0         0 =cut
1511 0         0  
1512 0 0       0 our %olbs; # needs to be localized
1513 0 0       0  
1514 0 0       0 my($self, %attribs) = @_;
1515 0 0       0 my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmpdir, $libperl) =
1516 0 0       0 @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
1517 0 0       0 my(@m);
1518 0         0 push @m, "
1519             # --- MakeMaker makeaperl section ---
1520             MAP_TARGET = $target
1521             ";
1522             return join '', @m if $self->{PARENT};
1523              
1524             my($dir) = join ":", @{$self->{DIR}};
1525              
1526             unless ($self->{MAKEAPERL}) {
1527             push @m, q{
1528             $(MAKE_APERL_FILE) : $(FIRST_MAKEFILE)
1529             $(NOECHO) $(ECHO) "Writing ""$(MMS$TARGET)"" for this $(MAP_TARGET)"
1530 0 0 0     0 $(NOECHO) $(PERLRUNINST) \
1531 0         0 Makefile.PL DIR=}, $dir, q{ \
1532 0         0 FIRST_MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
1533 0         0 MAKEAPERL=1 NORECURS=1 };
1534              
1535 0         0 push @m, map(q[ \\\n\t\t"$_"], @ARGV),q{
1536 0         0  
1537             $(MAP_TARGET) :: $(MAKE_APERL_FILE)
1538             $(MAKE)$(USEMAKEFILE)$(MAKE_APERL_FILE) static $(MMS$TARGET)
1539             };
1540             push @m, "\n";
1541 0         0  
1542 0 0       0 return join '', @m;
  0         0  
1543             }
1544 0         0  
1545              
1546             my($linkcmd,@optlibs,@staticpkgs,$extralist,$targdir,$libperldir,%libseen);
1547             local($_);
1548              
1549             # The front matter of the linkcommand...
1550             $linkcmd = join ' ', $Config{'ld'},
1551             grep($_, @Config{qw(large split ldflags ccdlflags)});
1552             $linkcmd =~ s/\s+/ /g;
1553              
1554             # Which *.olb files could we make use of...
1555             local(%olbs); # XXX can this be lexical?
1556             $olbs{$self->{INST_ARCHAUTODIR}} = "$self->{BASEEXT}\$(LIB_EXT)";
1557             require File::Find;
1558             File::Find::find(sub {
1559             return unless m/\Q$self->{LIB_EXT}\E$/;
1560 0     0 1 0 return if m/^libperl/;
1561              
1562 0         0 if( exists $self->{INCLUDE_EXT} ){
1563 0         0 my $found = 0;
1564 0         0  
1565             (my $xx = $File::Find::name) =~ s,.*?/auto/,,;
1566             $xx =~ s,/?$_,,;
1567             $xx =~ s,/,::,g;
1568 0 0       0  
1569             # Throw away anything not explicitly marked for inclusion.
1570 0         0 # DynaLoader is implied.
  0         0  
1571             foreach my $incl ((@{$self->{INCLUDE_EXT}},'DynaLoader')){
1572 0 0       0 if( $xx eq $incl ){
1573 0         0 $found++;
1574             last;
1575             }
1576             }
1577             return unless $found;
1578             }
1579             elsif( exists $self->{EXCLUDE_EXT} ){
1580             (my $xx = $File::Find::name) =~ s,.*?/auto/,,;
1581 0         0 $xx =~ s,/?$_,,;
1582             $xx =~ s,/,::,g;
1583              
1584             # Throw away anything explicitly marked for exclusion
1585             foreach my $excl (@{$self->{EXCLUDE_EXT}}){
1586 0         0 return if( $xx eq $excl );
1587             }
1588 0         0 }
1589              
1590             $olbs{$ENV{DEFAULT}} = $_;
1591             }, grep( -d $_, @{$searchdirs || []}));
1592 0         0  
1593 0         0 # We trust that what has been handed in as argument will be buildable
1594             $static = [] unless $static;
1595             @olbs{@{$static}} = (1) x @{$static};
1596              
1597 0         0 $extra = [] unless $extra && ref $extra eq 'ARRAY';
1598 0         0 # Sort the object libraries in inverse order of
1599             # filespec length to try to insure that dependent extensions
1600             # will appear before their parents, so the linker will
1601 0         0 # search the parent library to resolve references.
1602 0         0 # (e.g. Intuit::DWIM will precede Intuit, so unresolved
1603 0         0 # references from [.intuit.dwim]dwim.obj can be found
1604             # in [.intuit]intuit.olb).
1605 0 0   0   0 for (sort { length($a) <=> length($b) || $a cmp $b } keys %olbs) {
1606 0 0       0 next unless $olbs{$_} =~ /\Q$self->{LIB_EXT}\E$/;
1607             my($dir) = $self->fixpath($_,1);
1608 0 0       0 my($extralibs) = $dir . "extralibs.ld";
    0          
1609 0         0 my($extopt) = $dir . $olbs{$_};
1610             $extopt =~ s/$self->{LIB_EXT}$/.opt/;
1611 0         0 push @optlibs, "$dir$olbs{$_}";
1612 0         0 # Get external libraries this extension will need
1613 0         0 if (-f $extralibs ) {
1614             my %seenthis;
1615             open my $list, "<", $extralibs or warn $!,next;
1616             while (<$list>) {
1617 0         0 chomp;
  0         0  
1618 0 0       0 # Include a library in the link only once, unless it's mentioned
1619 0         0 # multiple times within a single extension's options file, in which
1620 0         0 # case we assume the builder needed to search it again later in the
1621             # link.
1622             my $skip = exists($libseen{$_}) && !exists($seenthis{$_});
1623 0 0       0 $libseen{$_}++; $seenthis{$_}++;
1624             next if $skip;
1625             push @$extra,$_;
1626 0         0 }
1627 0         0 }
1628 0         0 # Get full name of extension for ExtUtils::Miniperl
1629             if (-f $extopt) {
1630             open my $opt, '<', $extopt or die $!;
1631 0         0 while (<$opt>) {
  0         0  
1632 0 0       0 next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
1633             my $pkg = $1;
1634             $pkg =~ s#__*#::#g;
1635             push @staticpkgs,$pkg;
1636 0         0 }
1637 0 0       0 }
  0         0  
1638             }
1639             # Place all of the external libraries after all of the Perl extension
1640 0 0       0 # libraries in the final link, in order to maximize the opportunity
1641 0         0 # for XS code from multiple extensions to resolve symbols against the
  0         0  
  0         0  
1642             # same external library while only including that library once.
1643 0 0 0     0 push @optlibs, @$extra;
1644              
1645             $target = "Perl$Config{'exe_ext'}" unless $target;
1646             my $shrtarget;
1647             ($shrtarget,$targdir) = fileparse($target);
1648             $shrtarget =~ s/^([^.]*)/$1Shr/;
1649             $shrtarget = $targdir . $shrtarget;
1650             $target = "Perlshr.$Config{'dlext'}" unless $target;
1651 0 0       0 $tmpdir = "[]" unless $tmpdir;
  0         0  
1652 0 0       0 $tmpdir = $self->fixpath($tmpdir,1);
1653 0         0 if (@optlibs) { $extralist = join(' ',@optlibs); }
1654 0         0 else { $extralist = ''; }
1655 0         0 # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr)
1656 0         0 # that's what we're building here).
1657 0         0 push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2];
1658             if ($libperl) {
1659 0 0       0 unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) {
1660 0         0 print "Warning: $libperl not found\n";
1661 0 0       0 undef $libperl;
1662 0         0 }
1663 0         0 }
1664             unless ($libperl) {
1665             if (defined $self->{PERL_SRC}) {
1666             $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}");
1667             } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) {
1668 0   0     0 } else {
1669 0         0 print "Warning: $libperl not found
  0         0  
1670 0 0       0 If you're going to build a static perl binary, make sure perl is installed
1671 0         0 otherwise ignore this warning\n";
1672             }
1673             }
1674             $libperldir = $self->fixpath((fileparse($libperl))[1],1);
1675 0 0       0  
1676 0 0       0 push @m, '
1677 0         0 # Fill in the target you want to produce if it\'s not perl
1678 0 0       0 MAP_TARGET = ',$self->fixpath($target,0),'
1679 0         0 MAP_SHRTARGET = ',$self->fixpath($shrtarget,0),"
1680 0         0 MAP_LINKCMD = $linkcmd
1681 0         0 MAP_PERLINC = ", $perlinc ? map('"$_" ',@{$perlinc}) : '',"
1682             MAP_EXTRA = $extralist
1683             MAP_LIBPERL = ",$self->fixpath($libperl,0),'
1684             ';
1685              
1686              
1687             push @m,"\n${tmpdir}Makeaperl.Opt : \$(MAP_EXTRA)\n";
1688             foreach (@optlibs) {
1689 0         0 push @m,' $(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n";
1690             }
1691 0 0       0 push @m,"\n${tmpdir}PerlShr.Opt :\n\t";
1692 0         0 push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n";
1693 0         0  
1694 0         0 push @m,'
1695 0         0 $(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",'
1696 0 0       0 $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",'
1697 0 0       0 $(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}PerlShr.Opt",'
1698 0         0 $(MAP_LINKCMD) ',"${tmpdir}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option
1699 0 0       0 $(NOECHO) $(ECHO) "To install the new ""$(MAP_TARGET)"" binary, say"
  0         0  
1700 0         0 $(NOECHO) $(ECHO) " $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
1701             $(NOECHO) $(ECHO) "To remove the intermediate files, say
1702             $(NOECHO) $(ECHO) " $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) map_clean"
1703 0         0 ';
  0         0  
1704 0 0       0 push @m,"\n${tmpdir}perlmain.c : \$(FIRST_MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmpdir}Writemain.tmp\n";
1705 0 0 0     0 push @m, "# More from the 255-char line length limit\n";
1706 0         0 foreach (@staticpkgs) {
1707 0         0 push @m,' $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmpdir}Writemain.tmp\n];
1708             }
1709              
1710 0 0       0 push @m, sprintf <<'MAKE_FRAG', $tmpdir, $tmpdir;
1711 0 0       0 $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" %sWritemain.tmp >$(MMS$TARGET)
    0          
1712 0         0 $(NOECHO) $(RM_F) %sWritemain.tmp
1713             MAKE_FRAG
1714              
1715 0         0 push @m, q[
1716             # Still more from the 255-char line length limit
1717             doc_inst_perl :
1718             $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB)
1719             $(NOECHO) $(ECHO) "Perl binary $(MAP_TARGET)|" >.MM_tmp
1720 0         0 $(NOECHO) $(ECHO) "MAP_STATIC|$(MAP_STATIC)|" >>.MM_tmp
1721             $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp
1722             $(NOECHO) $(ECHO) -e "MAP_LIBPERL|$(MAP_LIBPERL)|" >>.MM_tmp
1723             $(NOECHO) $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(DESTINSTALLARCHLIB)','perllocal.pod').q[
1724             $(NOECHO) $(RM_F) .MM_tmp
1725             ];
1726              
1727 0 0       0 push @m, "
  0         0  
1728             inst_perl : pure_inst_perl doc_inst_perl
1729             \$(NOECHO) \$(NOOP)
1730              
1731             pure_inst_perl : \$(MAP_TARGET)
1732             $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1),"
1733 0         0 $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"
1734 0         0  
1735 0         0 clean :: map_clean
1736             \$(NOECHO) \$(NOOP)
1737 0         0  
1738 0         0 map_clean :
1739             \$(RM_F) ${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}perlmain.c \$(FIRST_MAKEFILE)
1740 0         0 \$(RM_F) ${tmpdir}Makeaperl.Opt ${tmpdir}PerlShr.Opt \$(MAP_TARGET)
1741             ";
1742              
1743             join '', @m;
1744             }
1745              
1746              
1747             # --- Output postprocessing section ---
1748              
1749             =item maketext_filter (override)
1750 0         0  
1751 0         0 Ensure that colons marking targets are preceded by space, in order
1752 0         0 to distinguish the target delimiter from a colon appearing as
1753 0         0 part of a filespec.
1754              
1755             =cut
1756 0         0  
1757             my($self, $text) = @_;
1758              
1759             $text =~ s/^([^\s:=]+)(:+\s)/$1 $2/mg;
1760             return $text;
1761 0         0 }
1762              
1763             =item prefixify (override)
1764              
1765             prefixifying on VMS is simple. Each should simply be:
1766              
1767             perl_root:[some.dir]
1768              
1769             which can just be converted to:
1770              
1771             volume:[your.prefix.some.dir]
1772              
1773             otherwise you get the default layout.
1774              
1775             In effect, your search prefix is ignored and $Config{vms_prefix} is
1776             used instead.
1777              
1778             =cut
1779 0         0  
1780             my($self, $var, $sprefix, $rprefix, $default) = @_;
1781              
1782             # Translate $(PERLPREFIX) to a real path.
1783             $rprefix = $self->eliminate_macros($rprefix);
1784             $rprefix = vmspath($rprefix) if $rprefix;
1785             $sprefix = vmspath($sprefix) if $sprefix;
1786              
1787             $default = vmsify($default)
1788             unless $default =~ /\[.*\]/;
1789 0         0  
1790             (my $var_no_install = $var) =~ s/^install//;
1791             my $path = $self->{uc $var} ||
1792             $ExtUtils::MM_Unix::Config_Override{lc $var} ||
1793             $Config{lc $var} || $Config{lc $var_no_install};
1794              
1795             if( !$path ) {
1796             warn " no Config found for $var.\n" if $Verbose >= 2;
1797             $path = $self->_prefixify_default($rprefix, $default);
1798             }
1799             elsif( !$self->{ARGS}{PREFIX} || !$self->file_name_is_absolute($path) ) {
1800             # do nothing if there's no prefix or if its relative
1801             }
1802             elsif( $sprefix eq $rprefix ) {
1803             warn " no new prefix.\n" if $Verbose >= 2;
1804 3     3 1 8 }
1805             else {
1806 3         33  
1807 3         13 warn " prefixify $var => $path\n" if $Verbose >= 2;
1808             warn " from $sprefix to $rprefix\n" if $Verbose >= 2;
1809              
1810             my($path_vol, $path_dirs) = $self->splitpath( $path );
1811             if( $path_vol eq $Config{vms_prefix}.':' ) {
1812             warn " $Config{vms_prefix}: seen\n" if $Verbose >= 2;
1813              
1814             $path_dirs =~ s{^\[}{\[.} unless $path_dirs =~ m{^\[\.};
1815             $path = $self->_catprefix($rprefix, $path_dirs);
1816             }
1817             else {
1818             $path = $self->_prefixify_default($rprefix, $default);
1819             }
1820             }
1821              
1822             print " now $path\n" if $Verbose >= 2;
1823             return $self->{uc $var} = $path;
1824             }
1825              
1826              
1827             my($self, $rprefix, $default) = @_;
1828 0     0 1    
1829             warn " cannot prefix, using default.\n" if $Verbose >= 2;
1830              
1831 0           if( !$default ) {
1832 0 0         warn "No default!\n" if $Verbose >= 1;
1833 0 0         return;
1834             }
1835 0 0         if( !$rprefix ) {
1836             warn "No replacement prefix!\n" if $Verbose >= 1;
1837             return '';
1838 0           }
1839              
1840             return $self->_catprefix($rprefix, $default);
1841 0   0       }
1842              
1843 0 0 0       my($self, $rprefix, $default) = @_;
    0          
    0          
1844 0 0          
1845 0           my($rvol, $rdirs) = $self->splitpath($rprefix);
1846             if( $rvol ) {
1847             return $self->catpath($rvol,
1848             $self->catdir($rdirs, $default),
1849             ''
1850             )
1851 0 0         }
1852             else {
1853             return $self->catdir($rdirs, $default);
1854             }
1855 0 0         }
1856 0 0          
1857              
1858 0           =item cd
1859 0 0          
1860 0 0         =cut
1861              
1862 0 0         my($self, $dir, @cmds) = @_;
1863 0            
1864             $dir = vmspath($dir);
1865              
1866 0           my $cmd = join "\n\t", map "$_", @cmds;
1867              
1868             # No leading tab makes it look right when embedded
1869             my $make_frag = sprintf <<'MAKE_FRAG', $dir, $cmd;
1870 0 0         startdir = F$Environment("Default")
1871 0           Set Default %s
1872             %s
1873             Set Default 'startdir'
1874             MAKE_FRAG
1875              
1876 0     0     # No trailing newline makes this easier to embed
1877             chomp $make_frag;
1878 0 0          
1879             return $make_frag;
1880 0 0         }
1881 0 0          
1882 0            
1883             =item oneliner
1884 0 0          
1885 0 0         =cut
1886 0            
1887             my($self, $cmd, $switches) = @_;
1888             $switches = [] unless defined $switches;
1889 0            
1890             # Strip leading and trailing newlines
1891             $cmd =~ s{^\n+}{};
1892             $cmd =~ s{\n+$}{};
1893 0     0      
1894             my @cmds = split /\n/, $cmd;
1895 0           $cmd = join " \n\t -e ", map $self->quote_literal($_), @cmds;
1896 0 0         $cmd = $self->escape_newlines($cmd);
1897 0            
1898             # Switches must be quoted else they will be lowercased.
1899             $switches = join ' ', map { qq{"$_"} } @$switches;
1900              
1901             return qq{\$(ABSPERLRUN) $switches -e $cmd "--"};
1902             }
1903 0            
1904              
1905             =item B<echo>
1906              
1907             perl trips up on "<foo>" thinking it's an input redirect. So we use the
1908             native Write command instead. Besides, it's faster.
1909              
1910             =cut
1911              
1912             my($self, $text, $file, $opts) = @_;
1913 0     0 1    
1914             # Compatibility with old options
1915 0           if( !ref $opts ) {
1916             my $append = $opts;
1917 0           $opts = { append => $append || 0 };
1918             }
1919             my $opencmd = $opts->{append} ? 'Open/Append' : 'Open/Write';
1920 0            
1921             $opts->{allow_variables} = 0 unless defined $opts->{allow_variables};
1922              
1923             my $ql_opts = { allow_variables => $opts->{allow_variables} };
1924              
1925             my @cmds = ("\$(NOECHO) $opencmd MMECHOFILE $file ");
1926             push @cmds, map { '$(NOECHO) Write MMECHOFILE '.$self->quote_literal($_, $ql_opts) }
1927             split /\n/, $text;
1928 0           push @cmds, '$(NOECHO) Close MMECHOFILE';
1929             return @cmds;
1930 0           }
1931              
1932              
1933             =item quote_literal
1934              
1935             =cut
1936              
1937             my($self, $text, $opts) = @_;
1938             $opts->{allow_variables} = 1 unless defined $opts->{allow_variables};
1939 0     0 1    
1940 0 0         # I believe this is all we should need.
1941             $text =~ s{"}{""}g;
1942              
1943 0           $text = $opts->{allow_variables}
1944 0           ? $self->escape_dollarsigns($text) : $self->escape_all_dollarsigns($text);
1945              
1946 0           return qq{"$text"};
1947 0           }
1948 0            
1949             =item escape_dollarsigns
1950              
1951 0           Quote, don't escape.
  0            
1952              
1953 0           =cut
1954              
1955             my($self, $text) = @_;
1956              
1957             # Quote dollar signs which are not starting a variable
1958             $text =~ s{\$ (?!\() }{"\$"}gx;
1959              
1960             return $text;
1961             }
1962              
1963              
1964             =item escape_all_dollarsigns
1965 0     0 1    
1966             Quote, don't escape.
1967              
1968 0 0         =cut
1969 0            
1970 0   0       my($self, $text) = @_;
1971              
1972 0 0         # Quote dollar signs
1973             $text =~ s{\$}{"\$\"}gx;
1974 0 0          
1975             return $text;
1976 0           }
1977              
1978 0           =item escape_newlines
1979 0            
  0            
1980             =cut
1981 0            
1982 0           my($self, $text) = @_;
1983              
1984             $text =~ s{\n}{-\n}g;
1985              
1986             return $text;
1987             }
1988              
1989             =item max_exec_len
1990              
1991 0     0 1   256 characters.
1992 0 0          
1993             =cut
1994              
1995 0           my $self = shift;
1996              
1997             return $self->{_MAX_EXEC_LEN} ||= 256;
1998 0 0         }
1999              
2000 0           =item init_linker
2001              
2002             =cut
2003              
2004             my $self = shift;
2005             $self->{EXPORT_LIST} ||= '$(BASEEXT).opt';
2006              
2007             my $shr = $Config{dbgprefix} . 'PERLSHR';
2008             if ($self->{PERL_SRC}) {
2009             $self->{PERL_ARCHIVE} ||=
2010 0     0 1   $self->catfile($self->{PERL_SRC}, "$shr.$Config{'dlext'}");
2011             }
2012             else {
2013 0           $self->{PERL_ARCHIVE} ||=
2014             $ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}";
2015 0           }
2016              
2017             $self->{PERL_ARCHIVEDEP} ||= '';
2018             $self->{PERL_ARCHIVE_AFTER} ||= '';
2019             }
2020              
2021              
2022             =item catdir (override)
2023              
2024             =item catfile (override)
2025              
2026 0     0 1   Eliminate the macros in the output to the MMS/MMK file.
2027              
2028             (L<File::Spec::VMS> used to do this for us, but it's being removed)
2029 0            
2030             =cut
2031 0            
2032             my $self = shift;
2033              
2034             # Process the macros on VMS MMS/MMK
2035             my @args = map { m{\$\(} ? $self->eliminate_macros($_) : $_ } @_;
2036              
2037             my $dir = $self->SUPER::catdir(@args);
2038              
2039 0     0 1   # Fix up the directory and force it to VMS format.
2040             $dir = $self->fixpath($dir, 1);
2041 0            
2042             return $dir;
2043 0           }
2044              
2045             my $self = shift;
2046              
2047             # Process the macros on VMS MMS/MMK
2048             my @args = map { m{\$\(} ? $self->eliminate_macros($_) : $_ } @_;
2049              
2050             my $file = $self->SUPER::catfile(@args);
2051              
2052             $file = vmsify($file);
2053 0     0 1    
2054             return $file
2055 0   0       }
2056              
2057              
2058             =item eliminate_macros
2059              
2060             Expands MM[KS]/Make macros in a text string, using the contents of
2061             identically named elements of C<%$self>, and returns the result
2062             as a file specification in Unix syntax.
2063 0     0 1    
2064 0   0       NOTE: This is the canonical version of the method. The version in
2065             L<File::Spec::VMS> is deprecated.
2066 0            
2067 0 0         =cut
2068              
2069 0   0       my($self,$path) = @_;
2070             return '' unless $path;
2071             $self = {} unless ref $self;
2072              
2073 0 0 0       my($npath) = unixify($path);
2074             # sometimes unixify will return a string with an off-by-one trailing null
2075             $npath =~ s{\0$}{};
2076 0   0        
2077 0   0       my($complex) = 0;
2078             my($head,$macro,$tail);
2079              
2080             # perform m##g in scalar context so it acts as an iterator
2081             while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#gs) {
2082             if (defined $self->{$2}) {
2083             ($head,$macro,$tail) = ($1,$2,$3);
2084             if (ref $self->{$macro}) {
2085             if (ref $self->{$macro} eq 'ARRAY') {
2086             $macro = join ' ', @{$self->{$macro}};
2087             }
2088             else {
2089             print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}),
2090             "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n";
2091             $macro = "\cB$macro\cB";
2092 0     0 1   $complex = 1;
2093             }
2094             }
2095 0 0         else {
  0            
2096             $macro = $self->{$macro};
2097 0           # Don't unixify if there is unescaped whitespace
2098             $macro = unixify($macro) unless ($macro =~ /(?<!\^)\s/);
2099             $macro =~ s#/\Z(?!\n)##;
2100 0           }
2101             $npath = "$head$macro$tail";
2102 0           }
2103             }
2104             if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#gs; }
2105             $npath;
2106 0     0 1   }
2107              
2108             =item fixpath
2109 0 0          
  0            
2110             my $path = $mm->fixpath($path);
2111 0           my $path = $mm->fixpath($path, $is_dir);
2112              
2113 0           Catchall routine to clean up problem MM[SK]/Make macros. Expands macros
2114             in any directory specification, in order to avoid juxtaposing two
2115 0           VMS-syntax directories when MM[SK] is run. Also expands expressions which
2116             are all macro, so that we can tell how long the expansion is, and avoid
2117             overrunning DCL's command buffer when MM[KS] is running.
2118              
2119             fixpath() checks to see whether the result matches the name of a
2120             directory in the current default directory and returns a directory or
2121             file specification accordingly. C<$is_dir> can be set to true to
2122             force fixpath() to consider the path to be a directory or false to force
2123             it to be a file.
2124              
2125             NOTE: This is the canonical version of the method. The version in
2126             L<File::Spec::VMS> is deprecated.
2127              
2128             =cut
2129              
2130             my($self,$path,$force_path) = @_;
2131 0     0 1   return '' unless $path;
2132 0 0         $self = bless {}, $self unless ref $self;
2133 0 0         my($fixedpath,$prefix,$name);
2134              
2135 0           if ($path =~ m#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) {
2136             if ($force_path or $path =~ /(?:DIR\)|\])\Z(?!\n)/) {
2137 0           $fixedpath = vmspath($self->eliminate_macros($path));
2138             }
2139 0           else {
2140 0           $fixedpath = vmsify($self->eliminate_macros($path));
2141             }
2142             }
2143 0           elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#s)) && $self->{$prefix}) {
2144 0 0         my($vmspre) = $self->eliminate_macros("\$($prefix)");
2145 0           # is it a dir or just a name?
2146 0 0         $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR\Z(?!\n)/) ? vmspath($vmspre) : '';
2147 0 0         $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name;
2148 0           $fixedpath = vmspath($fixedpath) if $force_path;
  0            
2149             }
2150             else {
2151 0           $fixedpath = $path;
2152             $fixedpath = vmspath($fixedpath) if $force_path;
2153 0           }
2154 0           # No hints, so we try to guess
2155             if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) {
2156             $fixedpath = vmspath($fixedpath) if -d $fixedpath;
2157             }
2158 0            
2159             # Trim off root dirname if it's had other dirs inserted in front of it.
2160 0 0         $fixedpath =~ s/\.000000([\]>])/$1/;
2161 0           # Special case for VMS absolute directory specs: these will have had device
2162             # prepended during trip through Unix syntax in eliminate_macros(), since
2163 0           # Unix syntax has no way to express "absolute from the top of this device's
2164             # directory tree".
2165             if ($path =~ /^[\[>][^.\-]/) { $fixedpath =~ s/^[^\[<]+//; }
2166 0 0          
  0            
2167 0           return $fixedpath;
2168             }
2169              
2170              
2171             =item os_flavor
2172              
2173             VMS is VMS.
2174              
2175             =cut
2176              
2177             return('VMS');
2178             }
2179              
2180              
2181             =item is_make_type (override)
2182              
2183             None of the make types being checked for is viable on VMS,
2184             plus our $self->{MAKE} is an unexpanded (and unexpandable)
2185             macro whose value is known only to the make utility itself.
2186              
2187             =cut
2188              
2189             my($self, $type) = @_;
2190             return 0;
2191             }
2192              
2193 0     0 1    
2194 0 0         =item make_type (override)
2195 0 0          
2196 0           Returns a suitable string describing the type of makefile being written.
2197              
2198 0 0 0       =cut
    0 0        
2199 0 0 0        
2200 0            
2201              
2202             =back
2203 0            
2204              
2205             =head1 AUTHOR
2206              
2207 0           Original author Charles Bailey F<bailey@newman.upenn.edu>
2208              
2209 0 0 0       Maintained by Michael G Schwern F<schwern@pobox.com>
2210 0 0          
2211 0 0         See L<ExtUtils::MakeMaker> for patching and contact information.
2212              
2213              
2214 0           =cut
2215 0 0          
2216             1;
2217