File Coverage

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


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