📄 mm_vms.pm
字号:
$target = "Perl$Config{'exe_ext'}" unless $target; my $shrtarget; ($shrtarget,$targdir) = fileparse($target); $shrtarget =~ s/^([^.]*)/$1Shr/; $shrtarget = $targdir . $shrtarget; $target = "Perlshr.$Config{'dlext'}" unless $target; $tmpdir = "[]" unless $tmpdir; $tmpdir = $self->fixpath($tmpdir,1); if (@optlibs) { $extralist = join(' ',@optlibs); } else { $extralist = ''; } # Let ExtUtils::Liblist find the necessary libs for us (but skip PerlShr) # that's what we're building here). push @optlibs, grep { !/PerlShr/i } split ' ', +($self->ext())[2]; if ($libperl) { unless (-f $libperl || -f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',$libperl))) { print STDOUT "Warning: $libperl not found\n"; undef $libperl; } } unless ($libperl) { if (defined $self->{PERL_SRC}) { $libperl = $self->catfile($self->{PERL_SRC},"libperl$self->{LIB_EXT}"); } elsif (-f ($libperl = $self->catfile($Config{'installarchlib'},'CORE',"libperl$self->{LIB_EXT}")) ) { } else { print STDOUT "Warning: $libperl not found If you're going to build a static perl binary, make sure perl is installed otherwise ignore this warning\n"; } } $libperldir = $self->fixpath((fileparse($libperl))[1],1); push @m, '# Fill in the target you want to produce if it\'s not perlMAP_TARGET = ',$self->fixpath($target,0),'MAP_SHRTARGET = ',$self->fixpath($shrtarget,0),"MAP_LINKCMD = $linkcmdMAP_PERLINC = ", $perlinc ? map('"$_" ',@{$perlinc}) : '',"MAP_EXTRA = $extralistMAP_LIBPERL = ",$self->fixpath($libperl,0),''; push @m,"\n${tmpdir}Makeaperl.Opt : \$(MAP_EXTRA)\n"; foreach (@optlibs) { push @m,' $(NOECHO) $(PERL) -e "print q{',$_,'}" >>$(MMS$TARGET)',"\n"; } push @m,"\n${tmpdir}PerlShr.Opt :\n\t"; push @m,'$(NOECHO) $(PERL) -e "print q{$(MAP_SHRTARGET)}" >$(MMS$TARGET)',"\n"; push @m,'$(MAP_SHRTARGET) : $(MAP_LIBPERL) Makeaperl.Opt ',"${libperldir}Perlshr_Attr.Opt",' $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_LIBPERL), Makeaperl.Opt/Option ',"${libperldir}Perlshr_Attr.Opt/Option",'$(MAP_TARGET) : $(MAP_SHRTARGET) ',"${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}PerlShr.Opt",' $(MAP_LINKCMD) ',"${tmpdir}perlmain\$(OBJ_EXT)",', PerlShr.Opt/Option $(NOECHO) $(ECHO) "To install the new ""$(MAP_TARGET)"" binary, say" $(NOECHO) $(ECHO) " $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)" $(NOECHO) $(ECHO) "To remove the intermediate files, say $(NOECHO) $(ECHO) " $(MAKE)$(USEMAKEFILE)$(FIRST_MAKEFILE) map_clean"'; push @m,"\n${tmpdir}perlmain.c : \$(FIRST_MAKEFILE)\n\t\$(NOECHO) \$(PERL) -e 1 >${tmpdir}Writemain.tmp\n"; push @m, "# More from the 255-char line length limit\n"; foreach (@staticpkgs) { push @m,' $(NOECHO) $(PERL) -e "print q{',$_,qq[}" >>${tmpdir}Writemain.tmp\n]; } push @m, sprintf <<'MAKE_FRAG', $tmpdir, $tmpdir; $(NOECHO) $(PERL) $(MAP_PERLINC) -ane "use ExtUtils::Miniperl; writemain(@F)" %sWritemain.tmp >$(MMS$TARGET) $(NOECHO) $(RM_F) %sWritemain.tmpMAKE_FRAG push @m, q[# Still more from the 255-char line length limitdoc_inst_perl : $(NOECHO) $(MKPATH) $(DESTINSTALLARCHLIB) $(NOECHO) $(ECHO) "Perl binary $(MAP_TARGET)|" >.MM_tmp $(NOECHO) $(ECHO) "MAP_STATIC|$(MAP_STATIC)|" >>.MM_tmp $(NOECHO) $(PERL) -pl040 -e " " ].$self->catfile('$(INST_ARCHAUTODIR)','extralibs.all'),q[ >>.MM_tmp $(NOECHO) $(ECHO) -e "MAP_LIBPERL|$(MAP_LIBPERL)|" >>.MM_tmp $(NOECHO) $(DOC_INSTALL) <.MM_tmp >>].$self->catfile('$(DESTINSTALLARCHLIB)','perllocal.pod').q[ $(NOECHO) $(RM_F) .MM_tmp]; push @m, "inst_perl : pure_inst_perl doc_inst_perl \$(NOECHO) \$(NOOP)pure_inst_perl : \$(MAP_TARGET) $self->{CP} \$(MAP_SHRTARGET) ",$self->fixpath($Config{'installbin'},1)," $self->{CP} \$(MAP_TARGET) ",$self->fixpath($Config{'installbin'},1),"clean :: map_clean \$(NOECHO) \$(NOOP)map_clean : \$(RM_F) ${tmpdir}perlmain\$(OBJ_EXT) ${tmpdir}perlmain.c \$(FIRST_MAKEFILE) \$(RM_F) ${tmpdir}Makeaperl.Opt ${tmpdir}PerlShr.Opt \$(MAP_TARGET)"; join '', @m;}# --- Output postprocessing section ---=item maketext_filter (override)Insure that colons marking targets are preceded by space, in orderto distinguish the target delimiter from a colon appearing aspart of a filespec.=cutsub maketext_filter { my($self, $text) = @_; $text =~ s/^([^\s:=]+)(:+\s)/$1 $2/mg; return $text;}=item prefixify (override)prefixifying on VMS is simple. Each should simply be: perl_root:[some.dir]which can just be converted to: volume:[your.prefix.some.dir]otherwise you get the default layout.In effect, your search prefix is ignored and $Config{vms_prefix} isused instead.=cutsub prefixify { my($self, $var, $sprefix, $rprefix, $default) = @_; # Translate $(PERLPREFIX) to a real path. $rprefix = $self->eliminate_macros($rprefix); $rprefix = VMS::Filespec::vmspath($rprefix) if $rprefix; $sprefix = VMS::Filespec::vmspath($sprefix) if $sprefix; $default = VMS::Filespec::vmsify($default) unless $default =~ /\[.*\]/; (my $var_no_install = $var) =~ s/^install//; my $path = $self->{uc $var} || $ExtUtils::MM_Unix::Config_Override{lc $var} || $Config{lc $var} || $Config{lc $var_no_install}; if( !$path ) { print STDERR " no Config found for $var.\n" if $Verbose >= 2; $path = $self->_prefixify_default($rprefix, $default); } elsif( !$self->{ARGS}{PREFIX} || !$self->file_name_is_absolute($path) ) { # do nothing if there's no prefix or if its relative } elsif( $sprefix eq $rprefix ) { print STDERR " no new prefix.\n" if $Verbose >= 2; } else { print STDERR " prefixify $var => $path\n" if $Verbose >= 2; print STDERR " from $sprefix to $rprefix\n" if $Verbose >= 2; my($path_vol, $path_dirs) = $self->splitpath( $path ); if( $path_vol eq $Config{vms_prefix}.':' ) { print STDERR " $Config{vms_prefix}: seen\n" if $Verbose >= 2; $path_dirs =~ s{^\[}{\[.} unless $path_dirs =~ m{^\[\.}; $path = $self->_catprefix($rprefix, $path_dirs); } else { $path = $self->_prefixify_default($rprefix, $default); } } print " now $path\n" if $Verbose >= 2; return $self->{uc $var} = $path;}sub _prefixify_default { my($self, $rprefix, $default) = @_; print STDERR " cannot prefix, using default.\n" if $Verbose >= 2; if( !$default ) { print STDERR "No default!\n" if $Verbose >= 1; return; } if( !$rprefix ) { print STDERR "No replacement prefix!\n" if $Verbose >= 1; return ''; } return $self->_catprefix($rprefix, $default);}sub _catprefix { my($self, $rprefix, $default) = @_; my($rvol, $rdirs) = $self->splitpath($rprefix); if( $rvol ) { return $self->catpath($rvol, $self->catdir($rdirs, $default), '' ) } else { return $self->catdir($rdirs, $default); }}=item cd=cutsub cd { my($self, $dir, @cmds) = @_; $dir = vmspath($dir); my $cmd = join "\n\t", map "$_", @cmds; # No leading tab makes it look right when embedded my $make_frag = sprintf <<'MAKE_FRAG', $dir, $cmd;startdir = F$Environment("Default") Set Default %s %s Set Default 'startdir'MAKE_FRAG # No trailing newline makes this easier to embed chomp $make_frag; return $make_frag;}=item oneliner=cutsub oneliner { my($self, $cmd, $switches) = @_; $switches = [] unless defined $switches; # Strip leading and trailing newlines $cmd =~ s{^\n+}{}; $cmd =~ s{\n+$}{}; $cmd = $self->quote_literal($cmd); $cmd = $self->escape_newlines($cmd); # Switches must be quoted else they will be lowercased. $switches = join ' ', map { qq{"$_"} } @$switches; return qq{\$(ABSPERLRUN) $switches -e $cmd "--"};}=item B<echo>perl trips up on "<foo>" thinking it's an input redirect. So we use thenative Write command instead. Besides, its faster.=cutsub echo { my($self, $text, $file, $appending) = @_; $appending ||= 0; my $opencmd = $appending ? 'Open/Append' : 'Open/Write'; my @cmds = ("\$(NOECHO) $opencmd MMECHOFILE $file "); push @cmds, map { '$(NOECHO) Write MMECHOFILE '.$self->quote_literal($_) } split /\n/, $text; push @cmds, '$(NOECHO) Close MMECHOFILE'; return @cmds;}=item quote_literal=cutsub quote_literal { my($self, $text) = @_; # I believe this is all we should need. $text =~ s{"}{""}g; return qq{"$text"};}=item escape_newlines=cutsub escape_newlines { my($self, $text) = @_; $text =~ s{\n}{-\n}g; return $text;}=item max_exec_len256 characters.=cutsub max_exec_len { my $self = shift; return $self->{_MAX_EXEC_LEN} ||= 256;}=item init_linker=cutsub init_linker { my $self = shift; $self->{EXPORT_LIST} ||= '$(BASEEXT).opt'; my $shr = $Config{dbgprefix} . 'PERLSHR'; if ($self->{PERL_SRC}) { $self->{PERL_ARCHIVE} ||= $self->catfile($self->{PERL_SRC}, "$shr.$Config{'dlext'}"); } else { $self->{PERL_ARCHIVE} ||= $ENV{$shr} ? $ENV{$shr} : "Sys\$Share:$shr.$Config{'dlext'}"; } $self->{PERL_ARCHIVE_AFTER} ||= '';}=item eliminate_macrosExpands MM[KS]/Make macros in a text string, using the contents ofidentically named elements of C<%$self>, and returns the resultas a file specification in Unix syntax.NOTE: This is the canonical version of the method. The version inFile::Spec::VMS is deprecated.=cutsub eliminate_macros { my($self,$path) = @_; return '' unless $path; $self = {} unless ref $self; if ($path =~ /\s/) { return join ' ', map { $self->eliminate_macros($_) } split /\s+/, $path; } my($npath) = unixify($path); # sometimes unixify will return a string with an off-by-one trailing null $npath =~ s{\0$}{}; my($complex) = 0; my($head,$macro,$tail); # perform m##g in scalar context so it acts as an iterator while ($npath =~ m#(.*?)\$\((\S+?)\)(.*)#gs) { if (defined $self->{$2}) { ($head,$macro,$tail) = ($1,$2,$3); if (ref $self->{$macro}) { if (ref $self->{$macro} eq 'ARRAY') { $macro = join ' ', @{$self->{$macro}}; } else { print "Note: can't expand macro \$($macro) containing ",ref($self->{$macro}), "\n\t(using MMK-specific deferred substitutuon; MMS will break)\n"; $macro = "\cB$macro\cB"; $complex = 1; } } else { ($macro = unixify($self->{$macro})) =~ s#/\Z(?!\n)##; } $npath = "$head$macro$tail"; } } if ($complex) { $npath =~ s#\cB(.*?)\cB#\${$1}#gs; } $npath;}=item fixpath my $path = $mm->fixpath($path); my $path = $mm->fixpath($path, $is_dir);Catchall routine to clean up problem MM[SK]/Make macros. Expands macrosin any directory specification, in order to avoid juxtaposing twoVMS-syntax directories when MM[SK] is run. Also expands expressions whichare all macro, so that we can tell how long the expansion is, and avoidoverrunning DCL's command buffer when MM[KS] is running.fixpath() checks to see whether the result matches the name of adirectory in the current default directory and returns a directory orfile specification accordingly. C<$is_dir> can be set to true toforce fixpath() to consider the path to be a directory or false to forceit to be a file.NOTE: This is the canonical version of the method. The version inFile::Spec::VMS is deprecated.=cutsub fixpath { my($self,$path,$force_path) = @_; return '' unless $path; $self = bless {} unless ref $self; my($fixedpath,$prefix,$name); if ($path =~ /[ \t]/) { return join ' ', map { $self->fixpath($_,$force_path) } split /[ \t]+/, $path; } if ($path =~ m#^\$\([^\)]+\)\Z(?!\n)#s || $path =~ m#[/:>\]]#) { if ($force_path or $path =~ /(?:DIR\)|\])\Z(?!\n)/) { $fixedpath = vmspath($self->eliminate_macros($path)); } else { $fixedpath = vmsify($self->eliminate_macros($path)); } } elsif ((($prefix,$name) = ($path =~ m#^\$\(([^\)]+)\)(.+)#s)) && $self->{$prefix}) { my($vmspre) = $self->eliminate_macros("\$($prefix)"); # is it a dir or just a name? $vmspre = ($vmspre =~ m|/| or $prefix =~ /DIR\Z(?!\n)/) ? vmspath($vmspre) : ''; $fixedpath = ($vmspre ? $vmspre : $self->{$prefix}) . $name; $fixedpath = vmspath($fixedpath) if $force_path; } else { $fixedpath = $path; $fixedpath = vmspath($fixedpath) if $force_path; } # No hints, so we try to guess if (!defined($force_path) and $fixedpath !~ /[:>(.\]]/) { $fixedpath = vmspath($fixedpath) if -d $fixedpath; } # Trim off root dirname if it's had other dirs inserted in front of it. $fixedpath =~ s/\.000000([\]>])/$1/; # Special case for VMS absolute directory specs: these will have had device # prepended during trip through Unix syntax in eliminate_macros(), since # Unix syntax has no way to express "absolute from the top of this device's # directory tree". if ($path =~ /^[\[>][^.\-]/) { $fixedpath =~ s/^[^\[<]+//; } return $fixedpath;}=item os_flavorVMS is VMS.=cutsub os_flavor { return('VMS');}=back=head1 AUTHOROriginal author Charles Bailey F<bailey@newman.upenn.edu>Maintained by Michael G Schwern F<schwern@pobox.com>See L<ExtUtils::MakeMaker> for patching and contact information.=cut1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -