af7488f484e808cc6d782fff3e4b24049f338da2
[p5sagit/p5-mst-13.2.git] / utils / perlcc.PL
1 #!/usr/local/bin/perl
2  
3 use Config;
4 use File::Basename qw(&basename &dirname);
5  
6 # List explicitly here the variables you want Configure to
7 # generate.  Metaconfig only looks for shell variables, so you
8 # have to mention them as if they were shell variables, not
9 # %Config entries.  Thus you write
10 #  $startperl
11 # to ensure Configure will look for $Config{startperl}.
12 # Wanted:  $archlibexp
13  
14 # This forces PL files to create target in same directory as PL file.
15 # This is so that make depend always knows where to find PL derivatives.
16 chdir dirname($0);
17 $file = basename($0, '.PL');
18 $file .= '.com' if $^O eq 'VMS';
19  
20 open OUT,">$file" or die "Can't create $file: $!";
21  
22 print "Extracting $file (with variable substitutions)\n";
23  
24 # In this section, perl variables will be expanded during extraction.
25 # You can use $Config{...} to use Configure variables.
26  
27 print OUT <<"!GROK!THIS!";
28 $Config{startperl}
29     eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
30     if \$running_under_some_shell;
31 !GROK!THIS!
32  
33 # In the following, perl variables are not expanded during extraction.
34  
35 print OUT <<'!NO!SUBS!';
36
37 use Config;
38 use strict;
39 use FileHandle;
40 use File::Basename qw(&basename &dirname);
41
42 use Getopt::Long;
43
44 $Getopt::Long::bundling_override = 1;
45 $Getopt::Long::passthrough = 0;
46 $Getopt::Long::ignore_case = 0;
47
48 my $options = {};
49 my $_fh;
50
51 main();
52
53 sub main
54 {
55
56     GetOptions
57             (
58             $options,   "L:s",
59                         "I:s",
60                         "C:s",
61                         "o:s",
62                         "e:s",
63                         "regex:s",
64                         "verbose:s",
65                         "log:s",
66                                                 "argv:s",
67                         "gen",
68                         "sav",
69                         "run",
70                         "prog",
71                         "mod"
72             );
73
74
75     my $key;
76
77     local($") = "|";
78
79     _usage() if (!_checkopts());
80     push(@ARGV, _maketempfile()) if ($options->{'e'});
81
82     _usage() if (!@ARGV);
83                 
84     my $file;
85     foreach $file (@ARGV)
86     {
87         _print("
88 --------------------------------------------------------------------------------
89 Compiling $file:
90 --------------------------------------------------------------------------------
91 ", 36 );
92         _doit($file);
93     }
94 }
95         
96 sub _doit
97 {
98     my ($file) = @_;
99
100     my ($program_ext, $module_ext) = _getRegexps();
101     my ($obj, $objfile, $so, $type);
102
103     if  (
104             (($file =~ m"@$program_ext") && ($file !~ m"@$module_ext"))
105             || (defined($options->{'prog'}) || defined($options->{'run'}))
106         )
107     {
108         $objfile = ($options->{'C'}) ?     $options->{'C'} : "$file.c";
109         $type = 'program';
110
111         $obj =         ($options->{'o'})?     $options->{'o'} : 
112                                             _getExecutable( $file,$program_ext);
113
114         return() if (!$obj);
115
116     }
117     elsif (($file =~ m"@$module_ext") || ($options->{'mod'}))
118     {
119         die "Shared objects are not supported on Win32 yet!!!!\n"
120                                       if ($Config{'osname'} eq 'MSWin32');
121
122         $obj =         ($options->{'o'})?    $options->{'o'} :
123                                             _getExecutable($file, $module_ext);
124         $so = "$obj.so";
125         $type = 'sharedlib';
126         return() if (!$obj);
127     }
128     else
129     {
130         _error("noextension", $file, $program_ext, $module_ext);
131         return();
132     }
133
134     if ($type eq 'program')
135     {
136         _print("Making C($objfile) for $file!\n", 36 );
137
138         my $errcode = _createCode($objfile, $file);
139         (_print( "ERROR: In generating code for $file!\n", -1), return()) 
140                                                                 if ($errcode);
141
142         _print("Compiling C($obj) for $file!\n", 36 ) if (!$options->{'gen'});
143         my $errcode = _compileCode($file, $objfile, $obj) 
144                                             if (!$options->{'gen'});
145
146         if ($errcode)
147                 {
148                         _print( "ERROR: In compiling code for $objfile !\n", -1);
149                         my $ofile = File::Basename::basename($objfile);
150                         $ofile =~ s"\.c$"\.o"s;
151                         
152                         _removeCode("$ofile"); 
153                         return()
154                 }
155     
156         _runCode($obj) if ($options->{'run'});
157
158         _removeCode($objfile) if (!$options->{'sav'} || 
159                                     ($options->{'e'} && !$options->{'C'}));
160
161         _removeCode($file) if ($options->{'e'}); 
162
163         _removeCode($obj) if (($options->{'e'} && 
164                                 ((!$options->{'sav'}) || !$options->{'o'})) || 
165                                 ($options->{'run'} && (!$options->{'sav'})));
166     }
167     else
168     {
169         _print( "Making C($objfile) for $file!\n", 36 );
170         my $errcode = _createCode($objfile, $file, $obj);
171         (_print( "ERROR: In generating code for $file!\n", -1), return()) 
172                                                                 if ($errcode);
173     
174         _print( "Compiling C($obj) for $file!\n", 36 ) if (!$options->{'gen'});
175
176         my $errorcode = 
177             _compileCode($file, $objfile, $obj, $so ) if (!$options->{'gen'});
178
179         (_print( "ERROR: In compiling code for $objfile!\n", -1), return()) 
180                                                                 if ($errcode);
181     }
182 }
183
184 sub _getExecutable
185 {
186     my ($sourceprog, $ext) = @_;
187     my ($obj);
188
189     if (defined($options->{'regex'}))
190     {
191         eval("(\$obj = \$sourceprog) =~ $options->{'regex'}");
192         return(0) if (_error('badeval', $@));
193         return(0) if (_error('equal', $obj, $sourceprog));
194     }
195     elsif (defined ($options->{'ext'}))
196     {
197         ($obj = $sourceprog) =~ s"@$ext"$options->{ext}"g;        
198         return(0) if (_error('equal', $obj, $sourceprog));
199     }
200         elsif (defined ($options->{'run'}))
201         {
202                 $obj = "perlc$$";
203         }
204     else
205     {
206         ($obj = $sourceprog) =~ s"@$ext""g;
207         return(0) if (_error('equal', $obj, $sourceprog));
208     }
209     return($obj);
210 }
211
212 sub _createCode
213 {
214     my ( $generated_cfile, $file, $final_output ) = @_;
215     my $return;
216
217     local($") = " -I";
218
219     if (@_ == 2)                                   # compiling a program   
220     {
221         _print( "$^X -I@INC -MO=CC,-o$generated_cfile $file\n", 36);
222         $return =  _run("$\18 -I@INC -MO=CC,-o$generated_cfile $file", 9);
223         $return;
224     }
225     else                                           # compiling a shared object
226     {            
227         _print( 
228             "$\18 -I@INC -MO=CC,-m$final_output,-o$generated_cfile $file\n", 36);
229         $return = 
230         _run("$\18 -I@INC -MO=CC,-m$final_output,-o$generated_cfile $file", 9);
231         $return;
232     }
233 }
234
235 sub _compileCode
236 {
237     my ($sourceprog, $generated_cfile, $output_executable, $shared_object) = @_;
238     my @return;
239
240     if (@_ == 3)                            # just compiling a program 
241     {
242         $return[0] = 
243         _ccharness($sourceprog, "-o", $output_executable, $generated_cfile);  
244         $return[0];
245     }
246     else
247     {
248         my $object_file = $generated_cfile;
249         $object_file =~ s"\.c$"\.o";   
250
251         $return[0] = _ccharness($sourceprog, "-c", $generated_cfile);
252         $return[1] = _ccharness
253                             (
254                                 $sourceprog, "-shared","-o", 
255                                 $shared_object, $object_file 
256                             );
257         return(1) if (grep ($_, @return));
258         return(0);
259     }
260 }
261
262 sub _runCode
263 {
264     my ($executable) = @_;
265     _print("$executable $options->{'argv'}\n", 36);
266     _run("$executable $options->{'argv'}", -1 );
267 }
268
269 sub _removeCode
270 {
271     my ($file) = @_;
272     unlink($file) if (-e $file);
273 }
274
275 sub _ccharness
276 {
277     my (@args) = @_;
278     local($") = " ";
279
280     my $sourceprog = shift(@args);
281     my ($libdir, $incdir);
282
283     if (-d "$Config{installarchlib}/CORE")
284     {
285         $libdir = "-L$Config{installarchlib}/CORE";
286         $incdir = "-I$Config{installarchlib}/CORE";
287     }
288     else
289     {
290         $libdir = "-L.."; 
291         $incdir = "-I..";
292     }
293
294     $libdir .= " -L$options->{L}" if (defined($options->{L}));
295     $incdir .= " -I$options->{L}" if (defined($options->{L}));
296
297     my $linkargs;
298
299     if (!grep(/^-[cS]$/, @ARGV))
300     {
301         $linkargs = sprintf("%s $libdir -lperl %s",@Config{qw(ldflags libs)});
302     }
303
304     my @sharedobjects = _getSharedObjects($sourceprog); 
305
306     my $cccmd = 
307         "$Config{cc} $Config{ccflags} $incdir @sharedobjects @args $linkargs";
308
309
310     _print ("$cccmd\n", 36);
311     _run("$cccmd", 18 );
312 }
313
314 sub _getSharedObjects
315 {
316     my ($sourceprog) = @_;
317     my ($tmpfile, $incfile);
318     my (@return);
319     local($") = " -I";
320
321     if ($Config{'osname'} eq 'MSWin32') 
322     { 
323         # _addstuff;    
324     }
325     else
326     {
327         my ($tmpprog);
328         ($tmpprog = $sourceprog) =~ s"(.*)[\/\\](.*)"$2";
329         $tmpfile = "/tmp/$tmpprog.tst";
330         $incfile = "/tmp/$tmpprog.val";
331     }
332
333     my $fd = new FileHandle("> $tmpfile") || die "Couldn't open $tmpfile!\n";
334     my $fd2 = 
335         new FileHandle("$sourceprog") || die "Couldn't open $sourceprog!\n";
336
337     my $perl = <$fd2>;  # strip off header;
338
339     print $fd 
340 <<"EOF";
341         use FileHandle;
342         my \$fh3  = new FileHandle("> $incfile") 
343                                         || die "Couldn't open $incfile\\n";
344
345         my \$key;
346         foreach \$key (keys(\%INC)) { print \$fh3 "\$key:\$INC{\$key}\\n"; }
347         close(\$fh3);
348         exit();
349 EOF
350
351     print $fd (   <$fd2>    );
352     close($fd);
353
354     _print("$\18 -I@INC $tmpfile\n", 36);
355     _run("$\18 -I@INC $tmpfile", 9 );
356
357     my $fd = new FileHandle ("$incfile"); 
358     my @lines = <$fd>;    
359
360     unlink($tmpfile);
361     unlink($incfile);
362
363     my $line;
364     my $autolib;
365
366     foreach $line (@lines) 
367     {
368         chomp($line);
369         my ($modname, $modpath) = split(':', $line);
370         my ($dir, $file) = ($modpath=~ m"(.*)[\\/]($modname)");
371         
372         if ($autolib = _lookforAuto($dir, $file))
373         {
374             push(@return, $autolib);
375         }
376     }
377
378     return(@return);
379 }
380
381 sub _maketempfile
382 {
383     my $return;
384
385 #    if ($Config{'osname'} eq 'MSWin32') 
386 #            { $return = "C:\\TEMP\\comp$$.p"; }
387 #    else
388 #            { $return = "/tmp/comp$$.p"; }
389
390     $return = "comp$$.p"; 
391
392     my $fd = new FileHandle( "> $return") || die "Couldn't open $return!\n";
393     print $fd $options->{'e'};
394     close($fd);
395
396     return($return);
397 }
398     
399     
400 sub _lookforAuto
401 {
402     my ($dir, $file) = @_;    
403
404     my $relshared;
405     my $return;
406
407     ($relshared = $file) =~ s"(.*)\.pm"$1";
408
409     my ($tmp, $modname) = ($relshared =~ m"(?:(.*)[\\/]){0,1}(.*)"s);
410
411     $relshared .= 
412         ($Config{'osname'} eq 'MSWin32')? "\\$modname.dll" : "/$modname.so";
413     
414
415
416     if (-e ($return = "$Config{'installarchlib'}/auto/$relshared") )
417     {
418         return($return);    
419     }
420     elsif (-e ($return = "$Config{'installsitearch'}/auto/$relshared"))
421     {
422         return($return);
423     }
424     elsif (-e ($return = "$dir/arch/auto/$relshared"))
425     {
426         return($return);    
427     }
428     else
429     {
430         return(undef);
431     }
432 }
433
434 sub _getRegexps    # make the appropriate regexps for making executables, 
435 {                  # shared libs
436
437     my ($program_ext, $module_ext) = ([],[]); 
438
439
440     @$program_ext = ($ENV{PERL_SCRIPT_EXT})? split(':', $ENV{PERL_SCRIPT_EXT}) :
441                                             ('.p$', '.pl$', '.bat$');
442
443
444     @$module_ext  = ($ENV{PERL_MODULE_EXT})? split(':', $ENV{PERL_MODULE_EXT}) :
445                                             ('.pm$');
446
447
448     _mungeRegexp( $program_ext );
449     _mungeRegexp( $module_ext  );    
450
451     return($program_ext, $module_ext);
452 }
453
454 sub _mungeRegexp
455 {
456     my ($regexp) = @_;
457
458     grep(s"(^|[^\\])\."$1\x0\\."g, @$regexp);
459     grep(s"(^|[^\x0])\\\."$1\."g,  @$regexp);
460     grep(s"\x0""g,                 @$regexp);
461 }
462
463
464 sub _error
465 {
466     my ($type, @args) = @_;
467
468     if ($type eq 'equal')
469     {
470             
471         if ($args[0] eq $args[1])
472         {
473             _print ("ERROR: The object file '$args[0]' does not generate a legitimate executable file! Skipping!\n", -1);
474             return(1);
475         }
476     }
477     elsif ($type eq 'badeval')
478     {
479         if ($args[0])
480         {
481             _print ("ERROR: $args[0]\n", -1);
482             return(1);
483         }
484     }
485     elsif ($type eq 'noextension')
486     {
487         my $progext = join(',', @{$args[1]});
488         my $modext  = join(',', @{$args[2]});
489
490         $progext =~ s"\\""g;
491         $modext  =~ s"\\""g;
492
493         $progext =~ s"\$""g;
494         $modext  =~ s"\$""g;
495
496         _print 
497         (
498 "
499 ERROR: '$args[0]' does not have a proper extension! Proper extensions are:
500
501     PROGRAM:       $progext 
502     SHARED OBJECT: $modext
503
504 Use the '-prog' flag to force your files to be interpreted as programs.
505 Use the '-mod' flag to force your files to be interpreted as modules.
506 ", -1
507         );
508         return(1);
509     }
510
511     return(0);
512 }
513
514 sub _checkopts
515 {
516     my @errors;
517     local($") = "\n";
518
519     if ($options->{'log'})
520     {
521         $_fh = new FileHandle(">> $options->{'log'}") || push(@errors, "ERROR: Couldn't open $options->{'log'}\n");
522     }
523
524     if (($options->{'c'}) && (@ARGV > 1) && ($options->{'sav'} ))
525     {
526         push(@errors, 
527 "ERROR: The '-sav' and '-C' options are incompatible when you have more than 
528        one input file! ('-C' explicitly names resulting C code, '-sav' saves it,
529        and hence, with more than one file, the c code will be overwritten for 
530        each file that you compile)\n");
531     }
532     if (($options->{'o'}) && (@ARGV > 1))
533     {
534         push(@errors, 
535 "ERROR: The '-o' option is incompatible when you have more than one input file! 
536        (-o explicitly names the resulting executable, hence, with more than 
537        one file the names clash)\n");
538     }
539
540     if ($options->{'e'} && $options->{'sav'} && !$options->{'o'} && 
541                                                             !$options->{'C'})
542     {
543         push(@errors, 
544 "ERROR: You need to specify where you are going to save the resulting 
545        executable or C code,  when using '-sav' and '-e'. Use '-o' or '-C'.\n");
546     }
547
548     if (($options->{'regex'} || $options->{'run'} || $options->{'o'}) 
549                                                     && $options->{'gen'})
550     {
551         push(@errors, 
552 "ERROR: The options '-regex', '-run', and '-o' are incompatible with '-gen'. 
553        '-gen' says to stop at C generation, and the other three modify the 
554        compilation and/or running process!\n");
555     }
556
557     if ($options->{'run'} && $options->{'mod'})
558     {
559         push(@errors, 
560 "ERROR: Can't run modules that you are compiling! '-run' and '-mod' are 
561        incompatible!\n"); 
562     }
563
564     if ($options->{'e'} && @ARGV)
565     {
566         push (@errors, 
567 "ERROR: The option '-e' needs to be all by itself without any other 
568        file arguments!\n");
569     }
570     if ($options->{'e'} && !($options->{'o'} || $options->{'run'}))
571     {
572         $options->{'run'} = 1;
573     }
574
575     if (!defined($options->{'verbose'})) 
576     { 
577         $options->{'verbose'} = ($options->{'log'})? 64 : 7; 
578     }
579
580     my $verbose_error;
581
582     if ($options->{'verbose'} =~ m"[^tagfcd]" && 
583             !( $options->{'verbose'} eq '0' || 
584                 ($options->{'verbose'} < 64 && $options->{'verbose'} > 0)))
585     {
586         $verbose_error = 1;
587         push(@errors, 
588 "ERROR: Illegal verbosity level.  Needs to have either the letters 
589        't','a','g','f','c', or 'd' in it or be between 0 and 63, inclusive.\n");
590     }
591
592     $options->{'verbose'} = ($options->{'verbose'} =~ m"[tagfcd]")? 
593                             ($options->{'verbose'} =~ m"d") * 32 +     
594                             ($options->{'verbose'} =~ m"c") * 16 +     
595                             ($options->{'verbose'} =~ m"f") * 8     +     
596                             ($options->{'verbose'} =~ m"t") * 4     +     
597                             ($options->{'verbose'} =~ m"a") * 2     +     
598                             ($options->{'verbose'} =~ m"g") * 1     
599                                                     : $options->{'verbose'};
600
601     if     (!$verbose_error && (    $options->{'log'} && 
602                                 !(
603                                     ($options->{'verbose'} & 8)   || 
604                                     ($options->{'verbose'} & 16)  || 
605                                     ($options->{'verbose'} & 32 ) 
606                                 )
607                             )
608         )
609     {
610         push(@errors, 
611 "ERROR: The verbosity level '$options->{'verbose'}' does not output anything 
612        to a logfile, and you specified '-log'!\n");
613     } # }
614
615     if     (!$verbose_error && (    !$options->{'log'} && 
616                                 (
617                                     ($options->{'verbose'} & 8)   || 
618                                     ($options->{'verbose'} & 16)  || 
619                                     ($options->{'verbose'} & 32)  || 
620                                     ($options->{'verbose'} & 64)
621                                 )
622                             )
623         )
624     {
625         push(@errors, 
626 "ERROR: The verbosity level '$options->{'verbose'}' requires that you also 
627        specify a logfile via '-log'\n");
628     } # }
629
630
631     (_print( "\n". join("\n", @errors), -1), return(0)) if (@errors);
632     return(1);
633 }
634
635 sub _print
636 {
637     my ($text, $flag ) = @_;
638     
639     my $logflag = int($flag/8) * 8;
640     my $regflag = $flag % 8;
641
642     if ($flag == -1 || ($flag & $options->{'verbose'}))
643     {
644         my $dolog = ((($logflag & $options->{'verbose'}) || $flag == -1) 
645                                                         && $options->{'log'}); 
646
647         my $doreg = (($regflag & $options->{'verbose'}) || $flag == -1);
648         
649         if ($doreg) { print( STDERR $text ); }
650         if ($dolog) { print $_fh $text; }
651     }
652 }
653
654 sub _run
655 {
656     my ($command, $flag) = @_;
657
658     my $logflag = ($flag != -1)? int($flag/8) * 8 : 0;
659     my $regflag = $flag % 8;
660
661     if ($flag == -1 || ($flag & $options->{'verbose'}))
662     {
663         my $dolog = ($logflag & $options->{'verbose'} && $options->{'log'});
664         my $doreg = (($regflag & $options->{'verbose'}) || $flag == -1);
665
666         if ($doreg && !$dolog) 
667             { system("$command"); }
668
669         elsif ($doreg && $dolog) 
670             { my $text = `$command 2>&1`; print $_fh $text; print STDERR $text;}
671         else 
672             { my $text = `$command 2>&1`; print $_fh $text; }
673     }
674     else 
675     {
676         `$command 2>&1`; 
677     }
678     return($?);
679 }
680
681 sub _usage
682 {
683     _print
684     ( 
685     <<"EOF"
686
687 Usage: $0 <file_list> 
688
689     Flags with arguments
690         -L       < extra library dirs for installation (form of 'dir1:dir2') >
691         -I       < extra include dirs for installation (form of 'dir1:dir2') >
692         -C       < explicit name of resulting C code > 
693         -o       < explicit name of resulting executable >
694         -e       < to compile 'one liners'. Need executable name (-o) or '-run'>
695         -regex   < rename regex, -regex 's/\.p/\.exe/' compiles a.p to a.exe >
696         -verbose < verbose level (1-63, or following letters 'gatfcd' >
697         -argv    < arguments for the executables to be run via '-run' or '-e' > 
698
699     Boolean flags
700         -gen     ( to just generate the c code. Implies '-sav' )
701         -sav     ( to save intermediate c code, (and executables with '-run'))
702         -run     ( to run the compiled program on the fly, as were interpreted.)
703         -prog    ( to indicate that the files on command line are programs )
704         -mod     ( to indicate that the files on command line are modules  )
705
706 EOF
707 , -1
708
709     );
710     exit(255);
711 }
712
713
714 __END__
715
716 =head1 NAME
717
718 perlcc - frontend for perl compiler
719
720 =head1 SYNOPSIS
721
722     %prompt  perlcc a.p        # compiles into executable 'a'
723
724     %prompt  perlcc A.pm       # compile into 'A.so'
725
726     %prompt  perlcc a.p -o execute  # compiles 'a.p' into 'execute'.
727
728     %prompt  perlcc a.p -o execute -run # compiles 'a.p' into execute, runs on
729                                         # the fly
730
731     %prompt  perlcc a.p -o execute -run -argv 'arg1 arg2 arg3' 
732                                         # compiles into execute, runs with 
733                                         # arg1 arg2 arg3 as @ARGV
734
735     %prompt perlcc a.p b.p c.p -regex 's/\.p/\.exe'
736                                         # compiles into 'a.exe','b.exe','c.exe'.
737
738     %prompt perlcc a.p -log compilelog  # compiles into 'a', saves compilation
739                                         # info into compilelog, as well
740                                         # as mirroring to screen
741
742     %prompt perlcc a.p -log compilelog -verbose cdf 
743                                         # compiles into 'a', saves compilation
744                                         # info into compilelog, being silent
745                                         # on screen.
746
747     %prompt perlcc a.p -C a.c -gen      # generates C code (into a.c) and 
748                                         # stops without compile.
749
750     %prompt perlcc a.p -L ../lib a.c 
751                                         # Compiles with the perl libraries 
752                                         # inside ../lib included.
753
754 =head1 DESCRIPTION
755
756 'perlcc' is the frontend into the perl compiler. Typing 'perlcc a.p'
757 compiles the code inside a.p into a standalone executable, and 
758 perlcc A.pm will compile into a shared object, A.so, suitable for inclusion 
759 into a perl program via "use A".
760
761 There are quite a few flags to perlcc which help with such issues as compiling 
762 programs in bulk, testing compiled programs for compatibility with the 
763 interpreter, and controlling.
764
765 =head1 OPTIONS 
766
767 =over 4
768
769 =item -L < library_directories >
770
771 Adds directories in B<library_directories> to the compilation command.
772
773 =item -I  < include_directories > 
774
775 Adds directories inside B<include_directories> to the compilation command.
776
777 =item -C   < c_code_name > 
778
779 Explicitly gives the name B<c_code_name> to the generated c code which is to 
780 be compiled. Can only be used if compiling one file on the command line.
781
782 =item -o   < executable_name >
783
784 Explicitly gives the name B<executable_name> to the executable which is to be
785 compiled. Can only be used if compiling one file on the command line.
786
787 =item -e   < perl_line_to_execute>
788
789 Compiles 'one liners', in the same way that B<perl -e> runs text strings at 
790 the command line. Default is to have the 'one liner' be compiled, and run all
791 in one go (see B<-run>); giving the B<-o> flag saves the resultant executable, 
792 rather than throwing it away. Use '-argv' to pass arguments to the executable
793 created.
794
795 =item -regex   <rename_regex>
796
797 Gives a rule B<rename_regex> - which is a legal perl regular expression - to 
798 create executable file names.
799
800 =item -verbose <verbose_level>
801
802 Show exactly what steps perlcc is taking to compile your code. You can change 
803 the verbosity level B<verbose_level> much in the same way that the '-D' switch 
804 changes perl's debugging level, by giving either a number which is the sum of 
805 bits you want or a list of letters representing what you wish to see. Here are 
806 the verbosity levels so far :
807
808     Bit 1(g):      Code Generation Errors to STDERR
809     Bit 2(a):      Compilation Errors to STDERR
810     Bit 4(t):      Descriptive text to STDERR 
811     Bit 8(f):      Code Generation Errors to file (B<-log> flag needed)
812     Bit 16(c):     Compilation Errors to file (B<-log> flag needed)
813     Bit 32(d):     Descriptive text to file (B<-log> flag needed) 
814
815 If the B<-log> tag is given, the default verbose level is 63 (ie: mirroring 
816 all of perlcc's output to both the screen and to a log file). If no B<-log>
817 tag is given, then the default verbose level is 7 (ie: outputting all of 
818 perlcc's output to STDERR).
819
820 NOTE: Because of buffering concerns, you CANNOT shadow the output of '-run' to
821 both a file, and to the screen! Suggestions are welcome on how to overcome this
822 difficulty, but for now it simply does not work properly, and hence will only go
823 to the screen.
824
825 =item -log <logname>
826
827 Opens, for append, a logfile to save some or all of the text for a given 
828 compile command. No rewrite version is available, so this needs to be done 
829 manually.
830
831 =item -argv <arguments>
832
833 In combination with '-run' or '-e', tells perlcc to run the resulting 
834 executable with the string B<arguments> as @ARGV.
835
836 =item -sav
837
838 Tells perl to save the intermediate C code. Usually, this C code is the name
839 of the perl code, plus '.c'; 'perlcode.p' gets generated in 'perlcode.p.c',
840 for example. If used with the '-e' operator, you need to tell perlcc where to 
841 save resulting executables.
842
843 =item -gen
844
845 Tells perlcc to only create the intermediate C code, and not compile the 
846 results. Does an implicit B<-sav>, saving the C code rather than deleting it.
847
848 =item -run
849
850 Immediately run the perl code that has been generated. NOTE: IF YOU GIVE THE 
851 B<-run> FLAG TO B<perlcc>, THEN THE REST OF @ARGV WILL BE INTERPRETED AS 
852 ARGUMENTS TO THE PROGRAM THAT YOU ARE COMPILING.
853
854 =item -prog
855
856 Indicate that the programs at the command line are programs, and should be
857 compiled as such. B<perlcc> will automatically determine files to be 
858 programs if they have B<.p>, B<.pl>, B<.bat> extensions.
859
860 =item -mod
861
862 Indicate that the programs at the command line are modules, and should be
863 compiled as such. B<perlcc> will automatically determine files to be 
864 modules if they have the extension B<.pm>.
865
866 =back
867
868 =head1 ENVIRONMENT
869
870 Most of the work of B<perlcc> is done at the command line. However, you can 
871 change the heuristic which determines what is a module and what is a program.
872 As indicated above, B<perlcc> assumes that the extensions:
873
874 .p$, .pl$, and .bat$
875
876 indicate a perl program, and:
877
878 .pm$
879
880 indicate a library, for the purposes of creating executables. And furthermore,
881 by default, these extensions will be replaced (and dropped ) in the process of 
882 creating an executable. 
883
884 To change the extensions which are programs, and which are modules, set the
885 environmental variables:
886
887 PERL_SCRIPT_EXT
888 PERL_MODULE_EXT
889
890 These two environmental variables take colon-separated, legal perl regular 
891 expressions, and are used by perlcc to decide which objects are which. 
892 For example:
893
894 setenv PERL_SCRIPT_EXT  '.prl$:.perl$'
895 prompt%   perlcc sample.perl
896
897 will compile the script 'sample.perl' into the executable 'sample', and
898
899 setenv PERL_MODULE_EXT  '.perlmod$:.perlmodule$'
900
901 prompt%   perlcc sample.perlmod
902
903 will  compile the module 'sample.perlmod' into the shared object 
904 'sample.so'
905
906 NOTE: the '.' in the regular expressions for PERL_SCRIPT_EXT and PERL_MODULE_EXT
907 is a literal '.', and not a wild-card. To get a true wild-card, you need to 
908 backslash the '.'; as in:
909
910 setenv PERL_SCRIPT_EXT '\.\.\.\.\.'
911
912 which would have the effect of compiling ANYTHING (except what is in 
913 PERL_MODULE_EXT) into an executable with 5 less characters in its name.
914
915 =head1 FILES
916
917 'perlcc' uses a temporary file when you use the B<-e> option to evaluate 
918 text and compile it. This temporary file is 'perlc$$.p'. The temporary C code is
919 perlc$$.p.c, and the temporary executable is perlc$$.
920
921 When you use '-run' and don't save your executable, the temporary executable is
922 perlc$$
923
924 =head1 BUGS
925
926 perlcc currently cannot compile shared objects on Win32. This should be fixed
927 by perl5.005.
928
929 =cut
930
931 !NO!SUBS!
932
933 close OUT or die "Can't close $file: $!";
934 chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
935 exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';