home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / perl / Perl / vms / ext / MM_VMS.pm < prev   
Encoding:
Perl POD Document  |  1995-05-22  |  43.9 KB  |  1,481 lines

  1. #   MM_VMS.pm
  2. #   MakeMaker default methods for VMS
  3. #   This package is inserted into @ISA of MakeMaker's MM before the
  4. #   built-in MM_Unix methods if MakeMaker.pm is run under VMS.
  5. #
  6. #   Version: 4.03
  7. #   Author:  Charles Bailey  bailey@genetics.upenn.edu
  8. #   Revised: 30-Jan-1995
  9.  
  10. package ExtUtils::MM_VMS;
  11.  
  12. use Config;
  13. require Exporter;
  14. use VMS::Filespec;
  15. use File::Basename;
  16.  
  17. Exporter::import('ExtUtils::MakeMaker',
  18.     qw(%att %skip %Recognized_Att_Keys $Verbose &neatvalue));
  19.  
  20.  
  21. sub fixpath {
  22.     my($path) = @_;
  23.     my($head,$macro,$tail);
  24.  
  25.     while (($head,$macro,$tail) = ($path =~ m#(.*?)\$\((\S+?)\)/(.*)#)) { 
  26.         ($macro = unixify($att{$macro})) =~ s#/$##;
  27.         $path = "$head$macro/$tail";
  28.     }
  29.     vmsify($path);
  30. }
  31.  
  32.  
  33. sub init_others {
  34.     &MM_Unix::init_others;
  35.     $att{NOOP} = "\tContinue";
  36.     $att{MAKEFILE} = '$(MAKEFILE)';
  37.     $att{RM_F} = '$(PERL) -e "foreach (@ARGV) { -d $_ ? rmdir $_ : unlink $_}"';
  38.     $att{RM_RF} = '$(PERL) -e "use File::Path; use VMS::Filespec; @dirs = map(unixify($_),@ARGV); rmtree(\@dirs,0,0)"';
  39.     $att{TOUCH} = '$(PERL) -e "$t=time; utime $t,$t,@ARGV"';
  40.     $att{CP} = 'Copy/NoConfirm';
  41.     $att{MV} = 'Rename/NoConfirm';
  42. }
  43.  
  44. sub constants {
  45.     my(@m,$def);
  46.     push @m, "
  47. NAME = $att{NAME}
  48. DISTNAME = $att{DISTNAME}
  49. VERSION = $att{VERSION}
  50.  
  51. # In which library should we install this extension?
  52. # This is typically the same as PERL_LIB.
  53. # (also see INST_LIBDIR and relationship to ROOTEXT)
  54. INST_LIB = ",vmspath($att{INST_LIB}),"
  55. INST_ARCHLIB = ",vmspath($att{INST_ARCHLIB}),"
  56. INST_EXE = ",vmspath($att{INST_EXE}),"
  57.  
  58. # Perl library to use when building the extension
  59. PERL_LIB = ",vmspath($att{PERL_LIB}),"
  60. PERL_ARCHLIB = ",vmspath($att{PERL_ARCHLIB}),"
  61. LIBPERL_A = ",vmsify($att{LIBPERL_A}),"
  62. ";
  63.  
  64. # Define I_PERL_LIBS to include the required -Ipaths
  65. # To be cute we only include PERL_ARCHLIB if different
  66. # To be portable we add quotes for VMS
  67. my(@i_perl_libs) = qw{-I$(PERL_ARCHLIB) -I$(PERL_LIB)};
  68. shift(@i_perl_libs) if ($att{PERL_ARCHLIB} eq $att{PERL_LIB});
  69. push @m, "I_PERL_LIBS = \"".join('" "',@i_perl_libs)."\"\n";
  70.  
  71. if ($att{PERL_SRC}) {
  72.      push @m, "
  73. # Where is the perl source code located?
  74. PERL_SRC = ",vmspath($att{PERL_SRC});
  75. }
  76.      push @m,"
  77. # Perl header files (will eventually be under PERL_LIB)
  78. PERL_INC = ",vmspath($att{PERL_INC}),"
  79. # Perl binaries
  80. PERL = $att{PERL}
  81. FULLPERL = $att{FULLPERL}
  82.  
  83. # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
  84. # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
  85. # ROOTEXT = Directory part of FULLEXT with leading slash (e.g /DBD)
  86. FULLEXT = ",vmspath($att{FULLEXT}),"
  87. BASEEXT = $att{BASEEXT}
  88. ROOTEXT = ",($att{ROOTEXT} eq '') ? '[]' : vmspath($att{ROOTEXT}),"
  89.  
  90. INC = ";
  91.  
  92.     if ($att{'INC'}) {
  93.     push @m,'/Include=(';
  94.     my(@includes) = split(/\s+/,$att{INC});
  95.     foreach (@includes) {
  96.         s/^-I//;
  97.         push @m,vmspath($_);
  98.     }
  99.     push @m, ")\n";
  100.     }
  101.  
  102.     if ($att{DEFINE} ne '') {
  103.     my(@defs) = split(/\s+/,$att{DEFINE});
  104.     foreach $def (@defs) {
  105.         $def =~ s/^-D//;
  106.         $def = "\"$def\"" if $def =~ /=/;
  107.     }
  108.     $att{DEFINE} = join ',',@defs;
  109.     }
  110.  
  111.     push @m,"
  112. DEFINE = $att{DEFINE}
  113. OBJECT = ",vmsify($att{OBJECT}),"
  114. LDFROM = ",vmsify($att{LDFROM}),"
  115. LINKTYPE = $att{LINKTYPE}
  116.  
  117. # Handy lists of source code files:
  118. XS_FILES = ",join(', ', sort keys %{$att{XS}}),"
  119. C_FILES  = ",join(', ', @{$att{C}}),"
  120. O_FILES  = ",join(', ', @{$att{O_FILES}}),"
  121. H_FILES  = ",join(', ', @{$att{H}}),"
  122.  
  123. .SUFFIXES : .xs
  124.  
  125. # This extension may link to it's own library (see SDBM_File)";
  126.     push @m,"
  127. MYEXTLIB = ",vmsify($att{MYEXTLIB}),"
  128.  
  129. # Here is the Config.pm that we are using/depend on
  130. CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h
  131.  
  132. # Where to put things:
  133. INST_LIBDIR = ",($att{'INST_LIBDIR'} = vmspath(unixpath($att{INST_LIB}) . unixpath($att{ROOTEXT}))),"
  134. INST_ARCHLIBDIR = ",($att{'INST_ARCHLIBDIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . unixpath($att{ROOTEXT}))),"
  135.  
  136. INST_AUTODIR = ",($att{'INST_AUTODIR'} = vmspath(unixpath($att{INST_LIB}) . 'auto/' . unixpath($att{FULLEXT}))),'
  137. INST_ARCHAUTODIR = ',($att{'INST_ARCHAUTODIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . 'auto/' . unixpath($att{FULLEXT}))),'
  138.  
  139. INST_STATIC = $(INST_ARCHAUTODIR)$(BASEEXT).olb
  140. INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
  141. INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
  142. INST_PM = ',join(', ',map(fixpath($_),sort values %{$att{PM}})),'
  143. ';
  144.  
  145.     join('',@m);
  146. }
  147.  
  148.  
  149. sub const_cccmd {
  150.     my($cmd) = $Config{'cc'};
  151.     my($name,$sys,@m);
  152.  
  153.     ( $name = $att{NAME} . "_cflags" ) =~ s/:/_/g ;
  154.     print STDOUT "Unix shell script ".$Config{"$att{'BASEEXT'}_cflags"}.
  155.          " required to modify CC command for $att{'BASEEXT'}\n"
  156.     if ($Config{$name});
  157.  
  158.     # Deal with $att{DEFINE} here since some C compilers pay attention
  159.     # to only one /Define clause on command line, so we have to
  160.     # conflate the ones from $Config{'cc'} and $att{DEFINE}
  161.     if ($att{DEFINE} ne '') {
  162.     if ($cmd =~ m:/define=\(?([^\(\/\)]+)\)?:i) {
  163.         $cmd = $` . "/Define=(" . $1 . ",$att{DEFINE})" . $';
  164.     }
  165.     else { $cmd .= "/Define=($att{DEFINE})" }
  166.     }
  167.  
  168.    $sys = ($cmd =~ /^gcc/i) ? 'GNU_CC_Include:[VMS]' : 'Sys$Library';
  169.         push @m,'
  170. .FIRST
  171.     @ If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS ',$sys,'
  172.  
  173. ';
  174.    push(@m, "CCCMD = $cmd\n");
  175.  
  176.    join('',@m);
  177. }
  178.  
  179.  
  180.  
  181. sub const_loadlibs{
  182.     my (@m);
  183.     push @m, "
  184. # $att{NAME} might depend on some other libraries.
  185. #
  186. # Dependent libraries are linked in either by the Link command
  187. # at build time or by the DynaLoader at bootstrap time.
  188. #
  189. # These comments may need revising:
  190. #
  191. # EXTRALIBS =    Full list of libraries needed for static linking.
  192. #        Only those libraries that actually exist are included.
  193. #
  194. # BSLOADLIBS =    List of those libraries that are needed but can be
  195. #        linked in dynamically.
  196. #
  197. # LDLOADLIBS =    List of those libraries which must be statically
  198. #        linked into the shared library.
  199. #
  200. EXTRALIBS  = ",map(vmsify($_) . ' ',$att{'EXTRALIBS'}),"
  201. BSLOADLIBS = ",map(vmsify($_) . ' ',$att{'BSLOADLIBS'}),"
  202. LDLOADLIBS = ",map(vmsify($_) . ' ',$att{'LDLOADLIBS'}),"\n";
  203.  
  204.     join('',@m);
  205. }
  206.  
  207. # --- Tool Sections ---
  208.  
  209. sub tool_autosplit{
  210.     my($self, %attribs) = @_;
  211.     my($asl) = "";
  212.     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
  213.     q{
  214. # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
  215. AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
  216. };
  217. }
  218.  
  219. sub tool_xsubpp{
  220.     my($xsdir) = unixpath($att{PERL_LIB}).'ExtUtils';
  221.     # drop back to old location if xsubpp is not in new location yet
  222.     $xsdir = unixpath($att{PERL_SRC}).'ext' unless (-f "$xsdir/xsubpp");
  223.     my(@tmdeps) = '$(XSUBPPDIR)typemap';
  224.     push(@tmdeps, "typemap") if -f "typemap";
  225.     my(@tmargs) = map("-typemap $_", @tmdeps);
  226.     "
  227. XSUBPPDIR = ".vmspath($xsdir)."
  228. XSUBPP = \$(PERL) \$(XSUBPPDIR)xsubpp
  229. XSUBPPDEPS = @tmdeps
  230. XSUBPPARGS = @tmargs
  231. ";
  232. }
  233.  
  234. sub tools_other {
  235.     "
  236. # Assumes \$(MMS) invokes MMS or MMK
  237. USEMAKEFILE = /Descrip=
  238. USEMACROS = /Macro=(
  239. MACROEND = )
  240. MAKEFILE = Descrip.MMS
  241. SHELL = Posix
  242. LD = $att{LD}
  243. TOUCH = $att{TOUCH}
  244. CP = $att{CP}
  245. RM_F  = $att{RM_F}
  246. RM_RF = $att{RM_RF}
  247. MKPATH = Create/Directory
  248. ";
  249. }
  250.  
  251.  
  252. # --- Translation Sections ---
  253.  
  254. sub c_o {
  255.     '
  256. .c.obj :
  257.     $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c
  258. ';
  259. }
  260.  
  261. sub xs_c {
  262.     '
  263. .xs.c :
  264.     $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
  265. ';
  266. }
  267.  
  268. sub xs_o {    # many makes are too dumb to use xs_c then c_o
  269.     '
  270. .xs.obj :
  271.     $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
  272.     $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c
  273. ';
  274. }
  275.  
  276.  
  277. # --- Target Sections ---
  278.  
  279. sub top_targets{
  280.     my(@m);
  281.     push @m, '
  282. all ::    config linkext $(INST_PM)
  283. '.$att{NOOP}.'
  284.  
  285. config :: '.$att{MAKEFILE}.'
  286.     @ $(MKPATH) $(INST_LIBDIR), $(INST_ARCHAUTODIR)
  287. ';
  288.     push @m, '
  289. $(O_FILES) : $(H_FILES)
  290. ' if @{$att{O_FILES} || []} && @{$att{H} || []};
  291.     join('',@m);
  292. }
  293.  
  294. sub dlsyms {
  295.     my($self,%attribs) = @_;
  296.     my($funcs) = $attribs{DL_FUNCS} || $att{DL_FUNCS} || {};
  297.     my($vars)  = $attribs{DL_VARS} || $att{DL_VARS} || [];
  298.     my(@m);
  299.  
  300.     push(@m,'
  301. dynamic :: perlshr.opt $(BASEEXT).opt
  302.     ',$att{NOOP},'
  303.  
  304. perlshr.opt : makefile.PL
  305.     $(PERL) -e "open O,\'>perlshr.opt\'; print O ""PerlShr/Share\n""; close O"
  306. ') unless $skip{'dynamic'};
  307.  
  308.     push(@m,'
  309. static :: $(BASEEXT).opt
  310.     ',$att{NOOP},'
  311. ') unless $skip{'static'};
  312.  
  313.     push(@m,'
  314. $(BASEEXT).opt : makefile.PL
  315.     $(PERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',neatvalue($att{DL_FUNCS}),', DL_VARS => ',neatvalue($att{DL_VARS}),',NAME => ',$att{NAME},')"
  316.     $(PERL) $(I_PERL_LIBS) -e "open OPT,\'>>$(MMS$TARGET)\'; print OPT ""$(INST_STATIC)/Include=$(BASEEXT)\n$(INST_STATIC)/Library\n"";close OPT"
  317. ');
  318.  
  319.     join('',@m);
  320. }
  321.  
  322.  
  323. # --- Dynamic Loading Sections ---
  324.  
  325. sub dynamic_lib {
  326.     my($self, %attribs) = @_;
  327.     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
  328.     my(@m);
  329.     push @m,"
  330.  
  331. OTHERLDFLAGS = $otherldflags
  332.  
  333. ";
  334.     push @m, '
  335. $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt perlshr.opt $(BASEEXT).opt
  336.     @ $(MKPATH) $(INST_ARCHAUTODIR)
  337.     Link $(LDFLAGS) /Shareable=$(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,perlshr.opt/Option,$(PERL_INC)perlshr_attr.opt/Option
  338. ';
  339.  
  340.     join('',@m);
  341. }
  342.  
  343. sub dynamic_bs {
  344.     my($self, %attribs) = @_;
  345.     '
  346. BOOTSTRAP = '."$att{BASEEXT}.bs".'
  347.  
  348. # As MakeMaker mkbootstrap might not write a file (if none is required)
  349. # we use touch to prevent make continually trying to remake it.
  350. # The DynaLoader only reads a non-empty file.
  351. $(BOOTSTRAP): '."$att{MAKEFILE} $att{BOOTDEP}".'
  352.     @ Write Sys$Output "Running mkbootstrap for $(NAME) ($(BSLOADLIBS))"
  353.     @ $(PERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; &mkbootstrap(""$(BSLOADLIBS)"");" "INST_LIB=$(INST_LIB)" "INST_ARCHLIB=$(INST_ARCHLIB)" "PERL_SRC=$(PERL_SRC)" "NAME=$(NAME)"
  354.     @ $(TOUCH) $(BOOTSTRAP)
  355.  
  356. $(INST_BOOT): $(BOOTSTRAP)
  357.     @ '.$att{RM_RF}.' $(INST_BOOT)
  358.     - '.$att{CP}.' $(BOOTSTRAP) $(INST_BOOT)
  359. ';
  360. }
  361. # --- Static Loading Sections ---
  362.  
  363. sub static_lib {
  364.     '
  365. $(INST_STATIC) : $(OBJECT), $(MYEXTLIB)
  366.     @ $(MKPATH) $(INST_ARCHAUTODIR)
  367.     If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
  368.     Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
  369. ';
  370. }
  371.  
  372.  
  373. sub installpm_x { # called by installpm perl file
  374.     my($self, $dist, $inst, $splitlib) = @_;
  375.     $inst = fixpath($inst);
  376.     $dist = vmsify($dist);
  377.     my($instdir) = dirname($inst);
  378.     my(@m);
  379.  
  380.     push(@m, "
  381. $inst : $dist $att{MAKEFILE}
  382. ",'    @ ',$att{RM_F},' $(MMS$TARGET);*
  383.     @ $(MKPATH) ',$instdir,'
  384.     @ ',$att{CP},' $(MMS$SOURCE) $(MMS$TARGET)
  385. ');
  386.     if ($splitlib and $inst =~ /\.pm$/) {
  387.       my($attdir) = $splitlib;
  388.       $attdir =~ s/\$\((.*)\)/$1/;
  389.       $attdir = $att{$attdir} if $att{$attdir};
  390.  
  391.       push(@m, '    $(AUTOSPLITFILE) $(MMS$TARGET) ',
  392.            vmspath(unixpath($attdir) . 'auto')."\n");
  393.       push(@m,"\n");
  394.     }
  395.  
  396.     join('',@m);
  397. }
  398.  
  399.  
  400. # --- Sub-directory Sections ---
  401.  
  402. sub exescan {
  403.    vmsify($_);
  404. }
  405.  
  406. sub subdir_x {
  407.     my($self, $subdir) = @_;
  408.     my(@m);
  409.     # The intention is that the calling Makefile.PL should define the
  410.     # $(SUBDIR_MAKEFILE_PL_ARGS) make macro to contain whatever
  411.     # information needs to be passed down to the other Makefile.PL scripts.
  412.     # If this does not suit your needs you'll need to write your own
  413.     # MY::subdir_x() method to override this one.
  414.     push @m, '
  415. config :: ',vmspath($subdir) . '$(MAKEFILE)
  416.     $(MMS) $(USEMAKEFILE) $(MMS$SOURCE) config $(USEMACROS)(INST_LIB=$(INST_LIB),INST_ARCHLIB=$(INST_ARCHLIB), \\
  417.     LINKTYPE=$(LINKTYPE),INST_EXE=$(INST_EXE),LIBPERL_A=$(LIBPERL_A)$(MACROEND) $(SUBDIR_MAKEFILE_PL_ARGS)
  418.  
  419. ',vmspath($subdir),'$(MAKEFILE) : ',vmspath($subdir),'Makefile.PL, $(CONFIGDEP)
  420.     @Write Sys$Output "Rebuilding $(MMS$TARGET) ..."
  421.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::MakeMaker; MM->runsubdirpl(qw('.$subdir.'))" \\
  422.     $(SUBDIR_MAKEFILE_PL_ARGS) INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB) \\
  423.     INST_EXE=$(INST_EXE) LIBPERL_A=$(LIBPERL_A) LINKTYPE=$(LINKTYPE)
  424.     @Write Sys$Output "Rebuild of $(MMS$TARGET) complete."
  425.  
  426. # The default clean, realclean and test targets in this Makefile
  427. # have automatically been given entries for $subdir.
  428.  
  429. subdirs ::
  430.     Set Default ',vmspath($subdir),'
  431.     $(MMS) all $(USEMACROS)LINKTYPE=$(LINKTYPE)$(MACROEND)
  432. ';
  433.     join('',@m);
  434. }
  435.  
  436.  
  437. # --- Cleanup and Distribution Sections ---
  438.  
  439. sub clean {
  440.     my($self, %attribs) = @_;
  441.     my(@m);
  442.     push @m, '
  443. # Delete temporary files but do not touch installed files
  444. # We don\'t delete the Makefile here so that a
  445. # later make realclean still has a makefile to work from
  446. clean ::
  447. ';
  448.     foreach (@{$att{DIR}}) { # clean subdirectories first
  449.     my($vmsdir) = vmspath($_);
  450.     push( @m, '    If F$Search("'.$vmsdir.'$(MAKEFILE)") Then $(MMS) $(USEMAKEFILE)'.$vmsdir.'$(MAKEFILE) clean'."\n");
  451.     }
  452.     push @m, "
  453.     $att{RM_F} *.Map;* *.lis;* *.cpp;* *.Obj;* *.Olb;* \$(BOOTSTRAP);* \$(BASEEXT).bso;*
  454. ";
  455.  
  456.     my(@otherfiles) = values %{$att{XS}}; # .c files from *.xs files
  457.     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
  458.     push(@otherfiles, "blib.dir");
  459.     push(@m, "    $att{RM_F} ".join(";* ", map(fixpath($_),@otherfiles)),";*\n");
  460.     # See realclean and ext/utils/make_ext for usage of Makefile.old
  461.     push(@m, "    $att{MV} $att{MAKEFILE} $att{MAKEFILE}_old");
  462.     push(@m, "    $attribs{POSTOP}\n") if $attribs{POSTOP};
  463.     join('', @m);
  464. }
  465.  
  466.  
  467. sub realclean {
  468.     my($self, %attribs) = @_;
  469.     my(@m);
  470.     push(@m,'
  471. # Delete temporary files (via clean) and also delete installed files
  472. realclean :: clean
  473. ');
  474.     foreach(@{$att{DIR}}){
  475.     my($vmsdir) = vmspath($_);
  476.     push(@m, '    If F$Search("'."$vmsdir$att{MAKEFILE}".'").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".' realclean'."\n");
  477.     push(@m, '    If F$Search("'."$vmsdir$att{MAKEFILE}".'_old").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".'_old realclean'."\n");
  478.     }
  479.     push @m,'
  480.     ',$att{RM_RF},' $(INST_AUTODIR) $(INST_ARCHAUTODIR)
  481.     ',$att{RM_F},' *.Opt;* $(INST_DYNAMIC);* $(INST_STATIC);* $(INST_BOOT);* $(INST_PM);*
  482.     ',$att{RM_F},' $(OBJECT);* $(MAKEFILE);* $(MAKEFILE)_old;*
  483. ';
  484.     push(@m, "    $att{RM_RF} ".join(";* ", map(fixpath($_),$attribs{'FILES'})),";*\n") if $attribs{'FILES'};
  485.     push(@m, "    $attribs{POSTOP}\n")                     if $attribs{POSTOP};
  486.     join('', @m);
  487. }
  488.  
  489.  
  490. sub distclean {
  491.     my($self, %attribs) = @_;
  492.     my($preop)    = $attribs{PREOP}  || '@ !'; # e.g., update MANIFEST
  493.     my($zipname)  = $attribs{TARNAME}  || '$(DISTNAME)-$(VERSION)';
  494.     my($zipflags) = $attribs{ZIPFLAGS} || '-Vu';
  495.     my($postop)   = $attribs{POSTOP} || "";
  496.     my($mkfiles)  = join(' ', map("$_\$(MAKEFILE) $_\$(MAKEFILE)_old",map(vmspath($_),@{$att{'DIR'}})));
  497.  
  498.     "
  499. distclean : clean
  500.     $preop
  501.     $att{RM_F} $mkfiles
  502.     Zip \"$zipflags\" $zipname \$(BASEEXT).* Makefile.PL
  503.     $postop
  504. ";
  505. }
  506.  
  507.  
  508. # --- Test and Installation Sections ---
  509.  
  510. sub test {
  511.     my($self, %attribs) = @_;
  512.     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
  513.     my(@m);
  514.     push @m,'
  515. test : all
  516. ';
  517.     push(@m,'    $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) -e "use Test::Harness; runtests @ARGV;" '.$tests."\n")
  518.       if $tests;
  519.     push(@m,'    $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) test.pl',"\n")
  520.       if -f 'test.pl';
  521.     foreach(@{$att{DIR}}){
  522.       my($vmsdir) = vmspath($_);
  523.       push(@m, '    If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir,
  524.            '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) $(USEMACRO)LINKTYPE=$(LINKTYPE)$(MACROEND) test`'."\n");
  525.     }
  526.     push(@m, "\t\@echo 'No tests defined for \$(NAME) extension.'\n") unless @m > 1;
  527.  
  528.     join('',@m);
  529. }
  530.  
  531. sub install {
  532.     my($self, %attribs) = @_;
  533.     my(@m);
  534.     push @m, q{
  535. doc_install ::
  536.     @ $(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS)  \\
  537.         -e "use ExtUtils::MakeMaker; MM->writedoc('Module', '$(NAME)', \\
  538.         'LINKTYPE=$(LINKTYPE)', 'VERSION=$(VERSION)', 'EXE_FILES=$(EXE_FILES)')"
  539. };
  540.  
  541.     push(@m, "
  542. install :: pure_install doc_install
  543.  
  544. pure_install :: all
  545. ");
  546.     # install subdirectories first
  547.     foreach(@{$att{DIR}}){
  548.       my($vmsdir) = vmspath($_);
  549.       push(@m, '    If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir,
  550.            '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) install`'."\n");
  551.     }
  552.  
  553.     push(@m, "\t! perl5.000 used to autosplit into INST_ARCHLIB, we delete these old files here
  554.     $att{RM_F} ",fixpath(unixpath($Config{'installarchlib'}).'auto/$(FULLEXT)/*.al'),';* ',
  555.                  fixpath(unixpath($Config{'installarchlib'}).'auto/$(FULLEXT)/*.ix'),";*
  556.     \$(MMS) \$(USEMACROS)INST_LIB=$Config{'installprivlib'},INST_ARCHLIB=$Config{'installarchlib'},INST_EXE=$Config{'installbin'}\$(MACROEND)
  557. ");
  558.  
  559.     join("",@m);
  560. }
  561.  
  562. sub perldepend {
  563.     my(@m);
  564.  
  565.     push @m, '
  566. $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
  567. $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
  568. $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
  569. $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
  570. $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
  571. $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
  572. $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
  573.  
  574. ';
  575.     push(@m,'
  576.  
  577. $(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh
  578.     @ Write Sys$Error "$(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh"
  579.     Set Default $(PERL_SRC)
  580.     $(MMS) $(USEMAKEFILE)[.VMS]$(MAKEFILE) [.lib]config.pm
  581. ');
  582.  
  583.     push(@m, join(" ", map(vmsify($_),values %{$att{XS}}))." : \$(XSUBPPDEPS)\n")
  584.       if %{$att{XS}};
  585.  
  586.     join('',@m);
  587. }
  588.  
  589. sub makefile {
  590.     my(@m,@cmd);
  591.     push(@m,'
  592.  
  593. # We take a very conservative approach here, but it\'s worth it.
  594. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
  595. $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
  596.     @ Write Sys$Output "',$att{MAKEFILE},' out-of-date with respect to $(MMS$SOURCE_LIST)"
  597.     @ Write Sys$Output "Cleaning current config before rebuilding ',$att{MAKEFILE},'...
  598.     - ',"$att{MV} $att{MAKEFILE} $att{MAKEFILE}_old",'
  599.     - $(MMS) $(USEMAKEFILE)',$att{MAKEFILE},'_old clean
  600.     $(PERL) $(I_PERL_LIBS) Makefile.PL
  601.     @ Write Sys$Output "Now you must rerun $(MMS)."
  602. ');
  603.  
  604.     join('',@m);
  605. }
  606.  
  607.  
  608. # --- Determine libraries to use and how to use them ---
  609.  
  610. sub makeaperl {
  611.     my($self, %attribs) = @_;
  612.     my($makefilename, $searchdirs, $static, $extra, $perlinc, $target, $tmp, $libperl) = 
  613.       @attribs{qw(MAKE DIRS STAT EXTRA INCL TARGET TMP LIBPERL)};
  614.     my(@m);
  615.     my($linkcmd,@staticopts,@staticpkgs,$extralist,$target,$targdir,$libperldir);
  616.  
  617.     # The front matter of the linkcommand...
  618.     $linkcmd = join ' ', $Config{'ld'},
  619.         grep($_, @Config{qw(large split ldflags ccdlflags)});
  620.     $linkcmd =~ s/\s+/ /g;
  621.  
  622.     # Which *.olb files could we make use of...
  623.     local(%olbs);
  624.     File::Find::find(sub {
  625.     return unless m/\.olb$/;
  626.     return if m/^libperl/;
  627.     $olbs{$ENV{DEFAULT}} = $_;
  628.     }, grep( -d $_, @{$searchdirs || []}), grep( -f $_, @{$static || []}) );
  629.  
  630.     $extra = [] unless $extra && ref $extra eq 'ARRAY';
  631.     # Sort the object libraries in inverse order of
  632.     # filespec length to try to insure that dependent extensions
  633.     # will appear before their parents, so the linker will
  634.     # search the parent library to resolve references.
  635.     # (e.g. Intuit::DWIM will precede Intuit, so unresolved
  636.     # references from [.intuit.dwim]dwim.obj can be found
  637.     # in [.intuit]intuit.olb).
  638.     for (sort keys %olbs) {
  639.     next unless $olbs{$_} =~ /\.olb$/;
  640.     my($dir) = vmspath($_);
  641.     my($extralibs) = $dir . "extralibs.ld";
  642.     my($extopt) = $dir . $olbs{$_};
  643.     $extopt =~ s/\.olb$/.opt/;
  644.     if (-f $extralibs ) {
  645.         open LIST,$extralibs or warn $!,next;
  646.         push @$extra, <LIST>;
  647.         close LIST;
  648.     }
  649.     if (-f $extopt) {
  650.         open OPT,$extopt or die $!;
  651.         while (<OPT>) {
  652.         next unless /(?:UNIVERSAL|VECTOR)=boot_([\w_]+)/;
  653.         # ExtUtils::Miniperl expects Unix paths
  654.         (my($pkg) = "$2_$2.a") =~ s#_*#/#g;
  655.         push @staticpkgs,$pkg;
  656.         }
  657.         push @staticopts, $extopt;
  658.     }
  659.     }
  660.  
  661.     $target = "Perl.Exe" unless $target;
  662.     ($shrtarget,$targdir) = fileparse($target);
  663.     $shrtarget =~ s/^([^.]*)/$1Shr/;
  664.     $shrtarget = $targdir . $shrtarget;
  665.     $target = "Perlshr$Config{'dlext'}" unless $target;
  666.     $tmp = "[]" unless $tmp;
  667.     $tmp = unixpath($tmp);
  668.     if (@$extra) {
  669.     $extralist = join(' ',@$extra);
  670.     $extralist =~ s/[,\s\n]+/, /g;
  671.     }
  672.     else { $extralist = ''; }
  673.     if ($libperl) {
  674.     unless (-f $libperl || -f ($libperl = unixpath($Config{'installarchlib'})."CORE/$libperl")){
  675.         print STDOUT "Warning: $libperl not found";
  676.         undef $libperl;
  677.     }
  678.     }
  679.     unless ($libperl) {
  680.     if (defined $att{PERL_SRC}) {
  681.         $libperl = "$att{PERL_SRC}/libperl.olb";
  682.     } elsif ( -f ( $libperl = unixpath($Config{'installarchlib'}).'CORE/libperl.olb' )) {
  683.     } else {
  684.         print STDOUT "Warning: $libperl not found";
  685.     }
  686.     }
  687.     $libperldir = vmspath((fileparse($libperl))[1]);
  688.  
  689.     push @m, '
  690. # Fill in the target you want to produce if it\'s not perl
  691. MAP_TARGET    = ',vmsify($target),'
  692. MAP_SHRTARGET = ',vmsify($shrtarget),"
  693. FULLPERL      = $att{'FULLPERL'}
  694. MAP_LINKCMD   = $linkcmd
  695. MAP_PERLINC   = ", $perlinc ? map('"-I'.vmspath($_).'" ',@{$perlinc}) : '$(I_PERL_LIB)','
  696. # We use the linker options files created with each extension, rather than
  697. #specifying the object files directly on the command line.
  698. MAP_STATIC    = ',@staticopts ? join(' ', @staticopts) : '','
  699. MAP_OPTS    = ',@staticopts ? ','.join(',', map($_.'/Option', @staticopts)) : '',"
  700. MAP_EXTRA     = $extralist
  701. MAP_LIBPERL = ",vmsify($libperl),'
  702. ';
  703.  
  704.  
  705.     push @m,'
  706. $(MAP_SHRTARGET) : $(MAP_LIBPERL) $(MAP_STATIC) ',"${libperldir}Perlshr_Attr.Opt",'
  707.     $(MAP_LINKCMD)/Shareable=$(MMS$TARGET) $(MAP_OPTS), $(MAP_EXTRA), $(MAP_LIBPERL) ',"${libperldir}Perlshr_Attr.Opt",'
  708. $(MAP_TARGET) : $(MAP_SHRTARGET) ',vmsify("${tmp}perlmain.obj"),' ',vmsify("${tmp}PerlShr.Opt"),'
  709.     $(MAP_LINKCMD) ',vmsify("${tmp}perlmain.obj"),', PerlShr.Opt/Option
  710.     @ Write Sys$Output "To install the new ""$(MAP_TARGET)"" binary, say"
  711.     @ Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) inst_perl $(USEMACROS)MAP_TARGET=$(MAP_TARGET)$(ENDMACRO)"
  712.     @ Write Sys$Output "To remove the intermediate files, say
  713.     @ Write Sys$Output "    $(MMS)$(USEMAKEFILE)$(MAKEFILE) map_clean"
  714. ';
  715.     push @m,'
  716. ',vmsify("${tmp}perlmain.c"),' : $(MAKEFILE)
  717.     @ $(PERL) $(MAP_PERLINC) -e "use ExtUtils::Miniperl; writemain(qw|',@staticpkgs,'|)" >$(MMS$TARGET)
  718. ';
  719.  
  720.     push @m, q{
  721. doc_inst_perl :
  722.     @ $(PERL) -e "use ExtUtils::MakeMaker; MM->writedoc('Perl binary','$(MAP_TARGET)','MAP_STATIC=$(MAP_STATIC)','MAP_EXTRA=$(MAP_EXTRA)','MAP_LIBPERL=$(MAP_LIBPERL)')"
  723. };
  724.  
  725.     push @m, "
  726. inst_perl : pure_inst_perl doc_inst_perl
  727.  
  728. pure_inst_perl : \$(MAP_TARGET)
  729.     $att{CP} \$(MAP_SHRTARGET) ",vmspath($Config{'installbin'}),"
  730.     $att{CP} \$(MAP_TARGET) ",vmspath($Config{'installbin'}),"
  731.  
  732. map_clean :
  733.     $att{RM_F} ",vmsify("${tmp}perlmain.obj"),vmsify("${tmp}perlmain.c"),
  734.                  vmsify("${tmp}PerlShr.Opt")," $makefilename
  735. ";
  736.  
  737.     join '', @m;
  738. }
  739.   
  740. sub extliblist {
  741.     '','','';
  742. }
  743.  
  744. sub old_extliblist {
  745.     '','',''
  746. }
  747.  
  748. sub new_extliblist {
  749.     '','',''
  750. }
  751.  
  752. # --- Write a DynaLoader bootstrap file if required
  753.  
  754. # VMS doesn't require a bootstrap file as a rule
  755. sub mkbootstrap {
  756.     1;
  757. }
  758.  
  759. sub mksymlists {
  760.     my($self,%attribs) = @_;
  761.  
  762.     MY->init_main() unless $att{BASEEXT};
  763.  
  764.     my($vars) = $attribs{DL_VARS} || $att{DL_VARS} || [];
  765.     my($procs) = $attribs{DL_FUNCS} || $att{DL_FUNCS};
  766.     my($package,$packprefix,$sym);
  767.     if (!%$procs) {
  768.         $package = $attribs{NAME} || $att{NAME};
  769.         $package =~ s/\W/_/g;
  770.         $procs = { $package => ["boot_$package"] };
  771.     }
  772.     my($isvax) = $Config{'arch'} =~ /VAX/i;
  773.  
  774.     # Options file declaring universal symbols
  775.     # Used when linking shareable image for dynamic extension,
  776.     # or when linking PerlShr into which we've added this package
  777.     # as a static extension
  778.     # We don't do anything to preserve order, so we won't relax
  779.     # the GSMATCH criteria for a dynamic extension
  780.     open OPT, ">$att{BASEEXT}.opt";
  781.     foreach $package (keys %$procs) {
  782.         ($packprefix = $package) =~ s/\W/_/g;
  783.         foreach $sym (@{$$procs{$package}}) {
  784.             $sym = "XS_${packprefix}_$sym" unless $sym =~ /^boot_/;
  785.             if ($isvax) { print OPT "UNIVERSAL=$sym\n" }
  786.             else        { print OPT "SYMBOL_VECTOR=($sym=PROCEDURE)\n"; }
  787.         }
  788.     }
  789.     foreach $sym (@$vars) {
  790.         print OPT "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n";
  791.         if ($isvax) { print OPT "UNIVERSAL=$sym\n" }
  792.         else        { print OPT "SYMBOL_VECTOR=($sym=DATA)\n"; }
  793.     }
  794.     close OPT;
  795. }
  796.  
  797. # --- Output postprocessing section ---
  798.  
  799. sub nicetext {
  800.     # Insure that colons marking targets are preceded by space -
  801.     # most Unix Makes don't need this, but it's necessary under VMS
  802.     # to distinguish the target delimiter from a colon appearing as
  803.     # part of a filespec.
  804.  
  805.     my($self,$text) = @_;
  806.     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
  807.     $text;
  808. }
  809.  
  810. 1;
  811.  
  812. __END__
  813. #   MM_VMS.pm
  814. #   MakeMaker default methods for VMS
  815. #   This package is inserted into @ISA of MakeMaker's MM before the
  816. #   built-in MM_Unix methods if MakeMaker.pm is run under VMS.
  817. #
  818. #   Version: 4.03
  819. #   Author:  Charles Bailey  bailey@genetics.upenn.edu
  820. #   Revised: 30-Jan-1995
  821.  
  822. package ExtUtils::MM_VMS;
  823.  
  824. use Config;
  825. require Exporter;
  826. use File::VMSspec;
  827. use File::Basename;
  828.  
  829. Exporter::import('ExtUtils::MakeMaker',
  830.     qw(%att %skip %Recognized_Att_Keys $Verbose &neatvalue));
  831.  
  832.  
  833. sub fixpath {
  834.     my($path) = @_;
  835.     my($head,$macro,$tail);
  836.  
  837.     while (($head,$macro,$tail) = ($path =~ m#(.*?)\$\((\S+?)\)/(.*)#)) { 
  838.         ($macro = unixify($att{$macro})) =~ s#/$##;
  839.         $path = "$head$macro/$tail";
  840.     }
  841.     vmsify($path);
  842. }
  843.  
  844.  
  845. sub init_others {
  846.     &MM_Unix::init_others;
  847.     $att{NOOP} = "\tContinue";
  848.     $att{MAKEFILE} = '$(MAKEFILE)';
  849.     $att{RM_F} = '$(PERL) -e "foreach (@ARGV) { -d $_ ? rmdir $_ : unlink $_}"';
  850.     $att{RM_RF} = '$(FULLPERL) -e "use File::Path; use File::VMSspec; @dirs = map(unixify($_),@ARGV); rmtree(\@dirs,0,0)"';
  851.     $att{TOUCH} = '$(PERL) -e "$t=time; utime $t,$t,@ARGV"';
  852.     $att{CP} = 'Copy/NoConfirm';
  853.     $att{MV} = 'Rename/NoConfirm';
  854. }
  855.  
  856. sub constants {
  857.     my(@m,$def);
  858.     push @m, "
  859. NAME = $att{NAME}
  860. DISTNAME = $att{DISTNAME}
  861. VERSION = $att{VERSION}
  862.  
  863. # In which library should we install this extension?
  864. # This is typically the same as PERL_LIB.
  865. # (also see INST_LIBDIR and relationship to ROOTEXT)
  866. INST_LIB = ",vmspath($att{INST_LIB}),"
  867. INST_ARCHLIB = ",vmspath($att{INST_ARCHLIB}),"
  868.  
  869. # Perl library to use when building the extension
  870. PERL_LIB = ",vmspath($att{PERL_LIB}),"
  871. PERL_ARCHLIB = ",vmspath($att{PERL_ARCHLIB}),"
  872. ";
  873.  
  874. # Define I_PERL_LIBS to include the required -Ipaths
  875. # To be cute we only include PERL_ARCHLIB if different
  876. # To be portable we add quotes for VMS
  877. my(@i_perl_libs) = qw{-I$(PERL_ARCHLIB) -I$(PERL_LIB)};
  878. shift(@i_perl_libs) if ($att{PERL_ARCHLIB} eq $att{PERL_LIB});
  879. push @m, "I_PERL_LIBS = \"".join('" "',@i_perl_libs)."\"\n";
  880.  
  881.      push @m, "
  882. # Where is the perl source code located? (Eventually we should
  883. # be able to build extensions without requiring the perl source
  884. # but that's a long way off yet).
  885. PERL_SRC = ",vmspath($att{PERL_SRC}),"
  886. # Perl header files (will eventually be under PERL_LIB)
  887. PERL_INC = ",vmspath($att{PERL_INC}),"
  888. # Perl binaries
  889. PERL = $att{PERL}
  890. FULLPERL = $att{FULLPERL}
  891.  
  892. # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
  893. # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
  894. # ROOTEXT = Directory part of FULLEXT with leading slash (e.g /DBD)
  895. FULLEXT = ",vmsify($att{FULLEXT}),"
  896. BASEEXT = $att{BASEEXT}
  897. ROOTEXT = ",$att{ROOTEXT} eq '' ? '[]' : vmspath($att{ROOTEXT}),"
  898.  
  899. INC = ";
  900.  
  901.     if ($att{'INC'}) {
  902.     push @m,'/Include=(';
  903.     my(@includes) = split(/\s+/,$att{INC});
  904.     foreach (@includes) {
  905.         s/^-I//;
  906.         push @m,vmspath($_);
  907.     }
  908.     push @m, ")\n";
  909.     }
  910.  
  911.     if ($att{DEFINE} ne '') {
  912.     my(@defs) = split(/\s+/,$att{DEFINE});
  913.     foreach $def (@defs) {
  914.         $def =~ s/^-D//;
  915.         $def = "\"$def\"" if $def =~ /=/;
  916.     }
  917.     $att{DEFINE} = join ',',@defs;
  918.     }
  919.  
  920.     push @m,"
  921. DEFINE = $att{DEFINE}
  922. OBJECT = ",vmsify($att{OBJECT}),"
  923. LDFROM = ",vmsify($att{LDFROM}),"
  924. LINKTYPE = $att{LINKTYPE}
  925.  
  926. # Handy lists of source code files:
  927. XS_FILES = ",join(', ', sort keys %{$att{XS}}),"
  928. C_FILES  = ",join(', ', @{$att{C}}),"
  929. O_FILES  = ",join(', ', @{$att{O_FILES}}),"
  930. H_FILES  = ",join(', ', @{$att{H}}),"
  931.  
  932. .SUFFIXES : .xs
  933.  
  934. # This extension may link to it's own library (see SDBM_File)";
  935.     push @m,"
  936. MYEXTLIB = ",vmsify($att{MYEXTLIB}),"
  937.  
  938. # Here is the Config.pm that we are using/depend on
  939. CONFIGDEP = \$(PERL_ARCHLIB)Config.pm, \$(PERL_INC)config.h
  940.  
  941. # Where to put things:
  942. INST_LIBDIR = ",($att{'INST_LIBDIR'} = vmspath(unixpath($att{INST_LIB}) . unixpath($att{ROOTEXT}))),"
  943. INST_ARCHLIBDIR = ",($att{'INST_ARCHLIBDIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . unixpath($att{ROOTEXT}))),"
  944.  
  945. INST_AUTODIR = ",($att{'INST_AUTODIR'} = vmspath(unixpath($att{INST_LIB}) . 'auto/' . unixpath($att{FULLEXT}))),'
  946. INST_ARCHAUTODIR = ',($att{'INST_ARCHAUTODIR'} = vmspath(unixpath($att{INST_ARCHLIB}) . 'auto/' . unixpath($att{FULLEXT}))),'
  947.  
  948. INST_STATIC = $(INST_ARCHLIBDIR)$(BASEEXT).olb
  949. INST_DYNAMIC = $(INST_ARCHAUTODIR)$(BASEEXT).$(DLEXT)
  950. INST_BOOT = $(INST_ARCHAUTODIR)$(BASEEXT).bs
  951. INST_PM = ',join(', ',map(fixpath($_),sort values %{$att{PM}})),'
  952. ';
  953.  
  954.     join('',@m);
  955. }
  956.  
  957.  
  958. sub const_cccmd {
  959.     my($cmd) = $Config{'cc'};
  960.     my($name,$sys,@m);
  961.  
  962.     ( $name = $att{NAME} . "_cflags" ) =~ s/:/_/g ;
  963.     warn "Unix shell script ".$Config{"$att{'BASEEXT'}_cflags"}.
  964.          " required to modify CC command for $att{'BASEEXT'}\n"
  965.     if ($Config{$name});
  966.  
  967.     # Deal with $att{DEFINE} here since some C compilers pay attention
  968.     # to only one /Define clause on command line, so we have to
  969.     # conflate the ones from $Config{'cc'} and $att{DEFINE}
  970.     if ($att{DEFINE} ne '') {
  971.     if ($cmd =~ m:/define=\(?([^\(\/\)]+)\)?:i) {
  972.         $cmd = $` . "/Define=(" . $1 . ",$att{DEFINE})" . $';
  973.     }
  974.     else { $cmd .= "/Define=($att{DEFINE})" }
  975.     }
  976.  
  977.    $sys = ($cmd =~ /^gcc/i) ? 'GNU_CC_Include:[VMS]' : 'Sys$Library';
  978.         push @m,'
  979. .FIRST
  980.     @ If F$TrnLnm("Sys").eqs."" Then Define/NoLog SYS ',$sys,'
  981.  
  982. ';
  983.    push(@m, "CCCMD = $cmd\n");
  984.  
  985.    join('',@m);
  986. }
  987.  
  988.  
  989.  
  990. sub const_loadlibs{
  991.     my (@m);
  992.     push @m, "
  993. # $att{NAME} might depend on some other libraries.
  994. #
  995. # Dependent libraries are linked in either by the Link command
  996. # at build time or by the DynaLoader at bootstrap time.
  997. #
  998. # These comments may need revising:
  999. #
  1000. # EXTRALIBS =    Full list of libraries needed for static linking.
  1001. #        Only those libraries that actually exist are included.
  1002. #
  1003. # BSLOADLIBS =    List of those libraries that are needed but can be
  1004. #        linked in dynamically.
  1005. #
  1006. # LDLOADLIBS =    List of those libraries which must be statically
  1007. #        linked into the shared library.
  1008. #
  1009. EXTRALIBS  = ",map(vmsify($_) . ' ',$att{'EXTRALIBS'}),"
  1010. BSLOADLIBS = ",map(vmsify($_) . ' ',$att{'BSLOADLIBS'}),"
  1011. LDLOADLIBS = ",map(vmsify($_) . ' ',$att{'LDLOADLIBS'}),"\n";
  1012.  
  1013.     join('',@m);
  1014. }
  1015.  
  1016. # --- Tool Sections ---
  1017.  
  1018. sub tool_autosplit{
  1019.     my($self, %attribs) = @_;
  1020.     my($asl) = "";
  1021.     $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
  1022.     q{
  1023. # Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
  1024. AUTOSPLITFILE = $(PERL) $(I_PERL_LIBS) -e "use AutoSplit;}.$asl.q{ AutoSplit::autosplit($ARGV[0], $ARGV[1], 0, 1, 1) ;"
  1025. };
  1026. }
  1027.  
  1028. sub tool_xsubpp{
  1029.     my($xsdir) = unixpath($att{PERL_LIB}).'ExtUtils';
  1030.     # drop back to old location if xsubpp is not in new location yet
  1031.     $xsdir = unixpath($att{PERL_SRC}).'ext' unless (-f "$xsdir/xsubpp");
  1032.     my(@tmdeps) = '$(XSUBPPDIR)typemap';
  1033.     push(@tmdeps, "typemap") if -f "typemap";
  1034.     my(@tmargs) = map("-typemap $_", @tmdeps);
  1035.     "
  1036. XSUBPPDIR = ".vmspath($xsdir)."
  1037. XSUBPP = \$(PERL) \$(XSUBPPDIR)xsubpp
  1038. XSUBPPDEPS = @tmdeps
  1039. XSUBPPARGS = @tmargs
  1040. ";
  1041. }
  1042.  
  1043. sub tools_other {
  1044.     "
  1045. # Assumes \$(MMS) invokes MMS or MMK
  1046. USEMAKEFILE = /Descrip=
  1047. USEMACROS = /Macro=(
  1048. MACROEND = )
  1049. MAKEFILE = Descrip.MMS
  1050. SHELL = Posix
  1051. LD = $att{LD}
  1052. TOUCH = $att{TOUCH}
  1053. CP = $att{CP}
  1054. RM_F  = $att{RM_F}
  1055. RM_RF = $att{RM_RF}
  1056. MKPATH = Create/Directory
  1057. ";
  1058. }
  1059.  
  1060.  
  1061. # --- Translation Sections ---
  1062.  
  1063. sub c_o {
  1064.     '
  1065. .c.obj :
  1066.     $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c
  1067. ';
  1068. }
  1069.  
  1070. sub xs_c {
  1071.     '
  1072. .xs.c :
  1073.     $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET)
  1074. ';
  1075. }
  1076.  
  1077. sub xs_o {    # many makes are too dumb to use xs_c then c_o
  1078.     '
  1079. .xs.obj :
  1080.     $(XSUBPP) $(XSUBPPARGS) $(MMS$TARGET_NAME).xs >$(MMS$TARGET_NAME).c
  1081.     $(CCCMD) $(CCCDLFLAGS) /Include=($(PERL_INC)) $(INC) $(MMS$TARGET_NAME).c
  1082. ';
  1083. }
  1084.  
  1085.  
  1086. # --- Target Sections ---
  1087.  
  1088. sub top_targets{
  1089.     '
  1090. all ::    config linkext $(INST_PM)
  1091. '.$att{NOOP}.'
  1092.  
  1093. config :: '.$att{MAKEFILE}.'
  1094.     @ $(MKPATH) $(INST_LIBDIR), $(INST_ARCHAUTODIR)
  1095. ';
  1096. }
  1097.  
  1098. sub dlsyms {
  1099.     my($self,%attribs) = @_;
  1100.     my($funcs) = $attribs{DL_FUNCS} || $att{DL_FUNCS} || {};
  1101.     my($vars)  = $attribs{DL_VARS} || $att{DL_VARS} || [];
  1102.     my(@m);
  1103.  
  1104.     push(@m,'
  1105. dynamic :: perlshr.opt $(BASEEXT).opt
  1106.     ',$att{NOOP},'
  1107.  
  1108. perlshr.opt : makefile.PL
  1109.     $(FULLPERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',
  1110.     %$funcs ? neatvalue($funcs) : "' '",', DL_VARS => ',
  1111.     @$vars  ? neatvalue($vars) : "' '",')"
  1112. ') unless $skip{'dynamic'};
  1113.  
  1114.     push(@m,'
  1115. static :: $(BASEEXT).opt
  1116.     ',$att{NOOP},'
  1117. ') unless $skip{'static'};
  1118.  
  1119.     push(@m,'
  1120. $(BASEEXT).opt : makefile.PL
  1121.     $(FULLPERL) $(I_PERL_LIBS) -e "use ExtUtils::MakeMaker; mksymlists(DL_FUNCS => ',neatvalue($att{DL_FUNCS}),', DL_VARS => ',neatvalue($att{DL_VARS}),')"
  1122. ');
  1123.  
  1124.     join('',@m);
  1125. }
  1126.  
  1127.  
  1128. # --- Dynamic Loading Sections ---
  1129.  
  1130. sub dynamic_lib {
  1131.     my($self, %attribs) = @_;
  1132.     my($otherldflags) = $attribs{OTHERLDFLAGS} || "";
  1133.     my(@m);
  1134.     push @m,"
  1135.  
  1136. OTHERLDFLAGS = $otherldflags
  1137.  
  1138. ";
  1139.     push @m, '
  1140. $(INST_DYNAMIC) : $(OBJECT) $(MYEXTLIB) $(PERL_INC)perlshr_attr.opt $(PERL_INC)crtl.opt perlshr.opt $(BASEEXT).opt
  1141.     @ $(MKPATH) $(INST_ARCHAUTODIR)
  1142.     Link $(LDFLAGS) /Shareable/Executable=$(MMS$TARGET)$(OTHERLDFLAGS) $(OBJECT),$(PERL_INC)perlshr_attr.opt/Option,$(PERL_INC)crtl.opt/Option,[]perlshr.opt/Option,[]$(BASEEXT).opt/Option
  1143. ';
  1144.  
  1145.     join('',@m);
  1146. }
  1147.  
  1148. # --- Static Loading Sections ---
  1149.  
  1150. sub static_lib {
  1151.     my(@m);
  1152.     push @m, <<'END';
  1153. $(INST_STATIC) : $(OBJECT), $(MYEXTLIB)
  1154.     If F$Search("$(MMS$TARGET)").eqs."" Then Library/Object/Create $(MMS$TARGET)
  1155.     Library/Object/Replace $(MMS$TARGET) $(MMS$SOURCE_LIST)
  1156. END
  1157.     push @m,"
  1158.     $att{CP}",'$(MMS$SOURCE) $(INST_ARCHAUTODIR)
  1159.     $(PERL) -e "print ""$(MMS$TARGET)\n""" >$(INST_ARCHAUTODIR)extralibs.ld
  1160. ';
  1161.     push @m, <<'END' if $att{PERL_SRC};
  1162.     @! Old mechanism - still needed:
  1163.     $(PERL) -e "print ""$(MMS$TARGET)\n""" >>$(PERL_SRC)ext.libs
  1164. END
  1165.  
  1166.     join('',@m);
  1167. }
  1168.  
  1169.  
  1170. sub installpm_x { # called by installpm perl file
  1171.     my($self, $dist, $inst, $splitlib) = @_;
  1172.     $inst = fixpath($inst);
  1173.     $dist = vmsify($dist);
  1174.     my($instdir) = dirname($inst);
  1175.     my(@m);
  1176.  
  1177.     push(@m, "
  1178. $inst : $dist
  1179. ",'    @ ',$att{RM_F},' $(MMS$TARGET);*
  1180.     @ $(MKPATH) ',$instdir,'
  1181.     @ ',$att{CP},' $(MMS$SOURCE) $(MMS$TARGET)
  1182. ');
  1183.     if ($splitlib and $inst =~ /\.pm$/) {
  1184.       my($attdir) = $splitlib;
  1185.       $attdir =~ s/\$\((.*)\)/$1/;
  1186.       $attdir = $att{$attdir} if $att{$attdir};
  1187.  
  1188.       push(@m, '    $(AUTOSPLITFILE) $(MMS$TARGET) ',
  1189.            vmspath(unixpath($attdir) . 'auto')."\n");
  1190.       push(@m,"\n");
  1191.     }
  1192.  
  1193.     join('',@m);
  1194. }
  1195.  
  1196.  
  1197. # --- Sub-directory Sections ---
  1198.  
  1199. sub subdir_x {
  1200.     my($self, $subdir) = @_;
  1201.     my(@m);
  1202.     # The intention is that the calling Makefile.PL should define the
  1203.     # $(SUBDIR_MAKEFILE_PL_ARGS) make macro to contain whatever
  1204.     # information needs to be passed down to the other Makefile.PL scripts.
  1205.     # If this does not suit your needs you'll need to write your own
  1206.     # MY::subdir_x() method to override this one.
  1207.     push @m, '
  1208. config :: ',vmspath($subdir) . '$(MAKEFILE)
  1209.     $(MMS) $(USEMAKEFILE) $(MMS$SOURCE) config $(USEMACROS)(INST_LIB=$(INST_LIB),INST_ARCHLIB=$(INST_ARCHLIB),LINKTYPE=$(LINKTYPE)$(MACROEND)
  1210.  
  1211. ',vmspath($subdir),'$(MAKEFILE) : ',vmspath($subdir),'Makefile.PL, $(CONFIGDEP)
  1212.     @Write Sys$Output "Rebuilding $(MMS$TARGET) ..."
  1213.     $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -e "use ExtUtils::MakeMaker; MM->runsubdirpl(qw('.$subdir.'))" \\
  1214.     $(SUBDIR_MAKEFILE_PL_ARGS) INST_LIB=$(INST_LIB) INST_ARCHLIB=$(INST_ARCHLIB)
  1215.     @Write Sys$Output "Rebuild of $(MMS$TARGET) complete."
  1216.  
  1217. # The default clean, realclean and test targets in this Makefile
  1218. # have automatically been given entries for $subdir.
  1219.  
  1220. subdirs ::
  1221.     Set Default ',vmspath($subdir),'
  1222.     $(MMS) all $(USEMACROS)LINKTYPE=$(LINKTYPE)$(MACROEND)
  1223. ';
  1224.     join('',@m);
  1225. }
  1226.  
  1227.  
  1228. # --- Cleanup and Distribution Sections ---
  1229.  
  1230. sub clean {
  1231.     my($self, %attribs) = @_;
  1232.     my(@m);
  1233.     push @m, '
  1234. # Delete temporary files but do not touch installed files
  1235. # We don\'t delete the Makefile here so that a
  1236. # later make realclean still has a makefile to work from
  1237. clean ::
  1238. ';
  1239.     foreach (@{$att{DIR}}) { # clean subdirectories first
  1240.     my($vmsdir) = vmspath($_);
  1241.     push( @m, '    If F$Search("'.$vmsdir.'$(MAKEFILE)") Then $(MMS) $(USEMAKEFILE)'.$vmsdir.'$(MAKEFILE) clean'."\n");
  1242.     }
  1243.     push @m, "
  1244.     $att{RM_F} *.Map;* *.lis;* *.cpp;* *.Obj;* *.Olb;* \$(BOOTSTRAP);* \$(BASEEXT).bso;*
  1245. ";
  1246.  
  1247.     my(@otherfiles) = values %{$att{XS}}; # .c files from *.xs files
  1248.     push(@otherfiles, $attribs{FILES}) if $attribs{FILES};
  1249.     push(@otherfiles, "blib.dir");
  1250.     push(@m, "    $att{RM_F} ".join(";* ", map(fixpath($_),@otherfiles)),";*\n");
  1251.     # See realclean and ext/utils/make_ext for usage of Makefile.old
  1252.     push(@m, "    $att{MV} $att{MAKEFILE} $att{MAKEFILE}_old");
  1253.     push(@m, "    $attribs{POSTOP}\n") if $attribs{POSTOP};
  1254.     join('', @m);
  1255. }
  1256.  
  1257.  
  1258. sub realclean {
  1259.     my($self, %attribs) = @_;
  1260.     my(@m);
  1261.     push(@m,'
  1262. # Delete temporary files (via clean) and also delete installed files
  1263. realclean :: clean
  1264. ');
  1265.     foreach(@{$att{DIR}}){
  1266.     my($vmsdir) = vmspath($_);
  1267.     push(@m, '    If F$Search("'."$vmsdir$att{MAKEFILE}".'").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".' realclean'."\n");
  1268.     push(@m, '    If F$Search("'."$vmsdir$att{MAKEFILE}".'_old").nes."" Then $(MMS) $(USEMAKEFILE)'."$vmsdir$att{MAKEFILE}".'_old realclean'."\n");
  1269.     }
  1270.     push @m,'
  1271.     ',$att{RM_RF},' $(INST_AUTODIR) $(INST_ARCHAUTODIR)
  1272.     ',$att{RM_F},' *.Opt;* $(INST_DYNAMIC);* $(INST_STATIC);* $(INST_BOOT);* $(INST_PM);*
  1273.     ',$att{RM_F},' $(OBJECT);* $(MAKEFILE);* $(MAKEFILE)_old;*
  1274. ';
  1275.     push(@m, "    $att{RM_RF} ".join(";* ", map(fixpath($_),$attribs{'FILES'})),";*\n") if $attribs{'FILES'};
  1276.     push(@m, "    $attribs{POSTOP}\n")                     if $attribs{POSTOP};
  1277.     join('', @m);
  1278. }
  1279.  
  1280.  
  1281. sub distclean {
  1282.     my($self, %attribs) = @_;
  1283.     my($preop)    = $attribs{PREOP}  || '@ !'; # e.g., update MANIFEST
  1284.     my($zipname)  = $attribs{ZIPNAME}  || '$(DISTNAME)-$(VERSION)';
  1285.     my($zipflags) = $attribs{ZIPFLAGS} || '-Vu';
  1286.     my($postop)   = $attribs{POSTOP} || "";
  1287.     my(@mkfildirs)  = map(vmspath($_),@{$att{'DIR'}});
  1288.     my(@m,$dir);
  1289.  
  1290.     push @m,'
  1291. distclean : realclean
  1292.     ',$preop,'
  1293.     If F$Search("$(MAKEFILE)").nes."" Then ',$att{RM_F},' $(MAKEFILE);*
  1294. ';
  1295.     foreach $dir (@mkfildirs) {
  1296.       push(@m,'If F$Search("',$dir,'$(MAKEFILE)") Then Delete/Log/NoConfirm ',
  1297.               $dir,'$(MAKEFILE);*',"\n");
  1298.     }
  1299.  
  1300.     push(@m,"    Zip \"$zipflags\" $zipname \$(BASEEXT).* Makefile.PL
  1301.     $postop
  1302. ");
  1303.  
  1304.     join('',@m);
  1305. }
  1306.  
  1307.  
  1308. # --- Test and Installation Sections ---
  1309.  
  1310. sub test {
  1311.     my($self, %attribs) = @_;
  1312.     my($tests) = $attribs{TESTS} || ( -d 't' ? 't/*.t' : '');
  1313.     my(@m);
  1314.     push @m,'
  1315. test : all
  1316. ';
  1317.     push(@m,'    $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" $(I_PERL_LIBS) -e "use Test::Harness; runtests @ARGV;" '.$tests."\n")
  1318.       if $tests;
  1319.     push(@m,'    $(FULLPERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" test.pl',"\n")
  1320.       if -f 'test.pl';
  1321.     foreach(@{$att{DIR}}){
  1322.       my($vmsdir) = vmspath($_);
  1323.       push(@m, '    If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir,
  1324.            '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) $(USEMACRO)LINKTYPE=$(LINKTYPE)$(MACROEND) test`'."\n");
  1325.     }
  1326.     push(@m, "\t\@echo 'No tests defined for \$(NAME) extension.'\n") unless @m > 1;
  1327.  
  1328.     join('',@m);
  1329. }
  1330.  
  1331. sub install {
  1332.     my($self, %attribs) = @_;
  1333.     my(@m);
  1334.     push(@m, "
  1335. install :: all
  1336. ");
  1337.     # install subdirectories first
  1338.     foreach(@{$att{DIR}}){
  1339.       my($vmsdir) = vmspath($_);
  1340.       push(@m, '    If F$Search("',$vmsdir,'$(MAKEFILE)").nes."" Then $(PERL) -e "chdir \'',$vmsdir,
  1341.            '\'; print `$(MMS) $(USEMAKEFILE)$(MAKEFILE) install`'."\n");
  1342.     }
  1343.  
  1344.     push(@m, "\t! perl5.000 used to autosplit into INST_ARCHLIB, we delete these old files here
  1345.     $att{RM_F} ",fixpath('$(INST_ARCHLIB)/auto/$(FULLEXT)/*.al'),";*,",fixpath('$(INST_ARCHLIB)/auto/$(FULLEXT)/*.ix'),';*
  1346.     $(MMS) $(USEMACROS)INST_LIB=\$(INST_PRIVLIB),INST_ARCHLIB=\$(INST_ARCHLIB)$(MACROEND)
  1347. ');
  1348.  
  1349.     join("",@m);
  1350. }
  1351.  
  1352. sub perldepend {
  1353.     my(@m);
  1354.  
  1355.     push @m, '
  1356. $(OBJECT) : $(PERL_INC)EXTERN.h, $(PERL_INC)INTERN.h, $(PERL_INC)XSUB.h, $(PERL_INC)av.h
  1357. $(OBJECT) : $(PERL_INC)cop.h, $(PERL_INC)cv.h, $(PERL_INC)embed.h, $(PERL_INC)form.h
  1358. $(OBJECT) : $(PERL_INC)gv.h, $(PERL_INC)handy.h, $(PERL_INC)hv.h, $(PERL_INC)keywords.h
  1359. $(OBJECT) : $(PERL_INC)mg.h, $(PERL_INC)op.h, $(PERL_INC)opcode.h, $(PERL_INC)patchlevel.h
  1360. $(OBJECT) : $(PERL_INC)perl.h, $(PERL_INC)perly.h, $(PERL_INC)pp.h, $(PERL_INC)proto.h
  1361. $(OBJECT) : $(PERL_INC)regcomp.h, $(PERL_INC)regexp.h, $(PERL_INC)scope.h, $(PERL_INC)sv.h
  1362. $(OBJECT) : $(PERL_INC)vmsish.h, $(PERL_INC)util.h, $(PERL_INC)config.h
  1363. $(O_FILES) : $(H_FILES)
  1364.  
  1365. ';
  1366.     push(@m,'
  1367.  
  1368. $(PERL_ARCHLIB)/Config.pm: $(PERL_SRC)/config.sh
  1369.     @ Write Sys$Error "$(PERL_ARCHLIB)/Config.pm may be out of date with $(PERL_SRC)/config.sh"
  1370.     Set Default $(PERL_SRC)
  1371.     $(MMS) $(USEMAKEFILE)[.VMS]$(MAKEFILE) [.lib]config.pm
  1372. ');
  1373.  
  1374.     push(@m, join(" ", map(vmsify($_),values %{$att{XS}}))." : \$(XSUBPPDEPS)\n")
  1375.       if %{$att{XS}};
  1376.  
  1377.     join('',@m);
  1378. }
  1379.  
  1380. sub makefile {
  1381.     my(@m,@cmd);
  1382.     @cmd = grep(/^\s/,split(/\n/,MY->c_o()));
  1383.     push(@m,join("\n",@cmd));
  1384.     push(@m,'
  1385.  
  1386. # We take a very conservative approach here, but it\'s worth it.
  1387. # We move $(MAKEFILE) to $(MAKEFILE)_old here to avoid gnu make looping.
  1388. $(MAKEFILE) : Makefile.PL $(CONFIGDEP)
  1389.     @ Write Sys$Output "',$att{MAKEFILE},' out-of-date with respect to $(MMS$SOURCE_LIST)"
  1390.     @ Write Sys$Output "Cleaning current config before rebuilding ',$att{MAKEFILE},'...
  1391.     - ',"$att{MV} $att{MAKEFILE} $att{MAKEFILE}_old",'
  1392.     - $(MMS) $(USEMAKEFILE)',$att{MAKEFILE},'_old clean
  1393.     $(PERL) $(I_PERL_LIBS) Makefile.PL
  1394.     @ Write Sys$Output "Now you must rerun $(MMS)."
  1395. ');
  1396.  
  1397.     join('',@m);
  1398. }
  1399.  
  1400.  
  1401. # --- Determine libraries to use and how to use them ---
  1402.  
  1403. sub extliblist {
  1404.     '','','';
  1405. }
  1406.  
  1407. sub old_extliblist {
  1408.     '','',''
  1409. }
  1410.  
  1411. sub new_extliblist {
  1412.     '','',''
  1413. }
  1414.  
  1415. # --- Write a DynaLoader bootstrap file if required
  1416.  
  1417. # VMS doesn't require a bootstrap file as a rule
  1418. sub mkbootstrap {
  1419.     1;
  1420. }
  1421.  
  1422. sub mksymlists {
  1423.     my($self,%attribs) = @_;
  1424.  
  1425.     MY->init_main() unless $att{BASEEXT};
  1426.  
  1427.     my($vars) = $attribs{DL_VARS} || $att{DL_VARS} || [];
  1428.     my($procs) = $attribs{DL_FUNCS} || $att{DL_FUNCS};
  1429.     my($package,$packprefix,$sym);
  1430.     if (!%$procs) {
  1431.         $package = $attribs{NAME} || $att{NAME};
  1432.         $package =~ s/\W/_/g;
  1433.         $procs = { $package => ["boot_$package"] };
  1434.     }
  1435.     my($isvax) = $Config{'arch'} =~ /VAX/i;
  1436.     # First, a short linker options file to specify PerlShr
  1437.     # used only when linking dynamic extension
  1438.     open OPT, ">PerlShr.Opt";
  1439.     print OPT "PerlShr/Share\n";
  1440.     close OPT;
  1441.  
  1442.     # Next, the options file declaring universal symbols
  1443.     # Used when linking shareable image for dynamic extension,
  1444.     # or when linking PerlShr into which we've added this package
  1445.     # as a static extension
  1446.     # We don't do anything to preserve order, so we won't relax
  1447.     # the GSMATCH criteria for a dynamic extension
  1448.     open OPT, ">$att{BASEEXT}.opt";
  1449.     foreach $package (keys %$procs) {
  1450.         ($packprefix = $package) =~ s/\W/_/g;
  1451.         foreach $sym (@{$$procs{$package}}) {
  1452.             $sym = "XS_${packprefix}_$sym" unless $sym =~ /^boot_/;
  1453.             if ($isvax) { print OPT "UNIVERSAL=$sym\n" }
  1454.             else        { print OPT "SYMBOL_VECTOR=($sym=PROCEDURE)\n"; }
  1455.         }
  1456.     }
  1457.     foreach $sym (@$vars) {
  1458.         print OPT "PSECT_ATTR=${sym},PIC,OVR,RD,NOEXE,WRT,NOSHR\n";
  1459.         if ($isvax) { print OPT "UNIVERSAL=$sym\n" }
  1460.         else        { print OPT "SYMBOL_VECTOR=($sym=DATA)\n"; }
  1461.     }
  1462.     close OPT;
  1463. }
  1464.  
  1465. # --- Output postprocessing section ---
  1466.  
  1467. sub nicetext {
  1468.     # Insure that colons marking targets are preceded by space -
  1469.     # most Unix Makes don't need this, but it's necessary under VMS
  1470.     # to distinguish the target delimiter from a colon appearing as
  1471.     # part of a filespec.
  1472.  
  1473.     my($self,$text) = @_;
  1474.     $text =~ s/([^\s:])(:+\s)/$1 $2/gs;
  1475.     $text;
  1476. }
  1477.  
  1478. 1;
  1479.  
  1480. __END__
  1481.