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