Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / bin / perlcc
CommitLineData
86530b38
AT
1#!/import/bw/tools/local/perl-5.8.0/bin/perl
2 eval 'exec /import/bw/tools/local/perl-5.8.0/bin/perl -S $0 ${1+"$@"}'
3 if $running_under_some_shell;
4--$running_under_some_shell;
5
6# Version 2.0, Simon Cozens, Thu Mar 30 17:52:45 JST 2000
7# Version 2.01, Tom Christiansen, Thu Mar 30 08:25:14 MST 2000
8# Version 2.02, Simon Cozens, Sun Apr 16 01:53:36 JST 2000
9# Version 2.03, Edward Peschko, Mon Feb 26 12:04:17 PST 2001
10
11use strict;
12use warnings;
13use 5.006_000;
14
15use FileHandle;
16use Config;
17use Fcntl qw(:DEFAULT :flock);
18use File::Temp qw(tempfile);
19use Cwd;
20our $VERSION = 2.03;
21$| = 1;
22
23$SIG{INT} = sub { exit(); }; # exit gracefully and clean up after ourselves.
24
25use subs qw{
26 cc_harness check_read check_write checkopts_byte choose_backend
27 compile_byte compile_cstyle compile_module generate_code
28 grab_stash parse_argv sanity_check vprint yclept spawnit
29};
30sub opt(*); # imal quoting
31sub is_win32();
32sub is_msvc();
33
34our ($Options, $BinPerl, $Backend);
35our ($Input => $Output);
36our ($logfh);
37our ($cfile);
38our (@begin_output); # output from BEGIN {}, for testsuite
39
40# eval { main(); 1 } or die;
41
42main();
43
44sub main {
45 parse_argv();
46 check_write($Output);
47 choose_backend();
48 generate_code();
49 run_code();
50 _die("XXX: Not reached?");
51}
52
53#######################################################################
54
55sub choose_backend {
56 # Choose the backend.
57 $Backend = 'C';
58 if (opt(B)) {
59 checkopts_byte();
60 $Backend = 'Bytecode';
61 }
62 if (opt(S) && opt(c)) {
63 # die "$0: Do you want me to compile this or not?\n";
64 delete $Options->{S};
65 }
66 $Backend = 'CC' if opt(O);
67}
68
69
70sub generate_code {
71
72 vprint 0, "Compiling $Input";
73
74 $BinPerl = yclept(); # Calling convention for perl.
75
76 if (opt(shared)) {
77 compile_module();
78 } else {
79 if ($Backend eq 'Bytecode') {
80 compile_byte();
81 } else {
82 compile_cstyle();
83 }
84 }
85 exit(0) if (!opt('r'));
86}
87
88sub run_code {
89 vprint 0, "Running code";
90 run("$Output @ARGV");
91 exit(0);
92}
93
94# usage: vprint [level] msg args
95sub vprint {
96 my $level;
97 if (@_ == 1) {
98 $level = 1;
99 } elsif ($_[0] =~ /^\d$/) {
100 $level = shift;
101 } else {
102 # well, they forgot to use a number; means >0
103 $level = 0;
104 }
105 my $msg = "@_";
106 $msg .= "\n" unless substr($msg, -1) eq "\n";
107 if (opt(v) > $level)
108 {
109 print "$0: $msg" if !opt('log');
110 print $logfh "$0: $msg" if opt('log');
111 }
112}
113
114sub parse_argv {
115
116 use Getopt::Long;
117
118 # disallows using long arguments
119 # Getopt::Long::Configure("bundling");
120
121 Getopt::Long::Configure("no_ignore_case");
122
123 # no difference in exists and defined for %ENV; also, a "0"
124 # argument or a "" would not help cc, so skip
125 unshift @ARGV, split ' ', $ENV{PERLCC_OPTS} if $ENV{PERLCC_OPTS};
126
127 $Options = {};
128 Getopt::Long::GetOptions( $Options,
129 'L:s', # lib directory
130 'I:s', # include directories (FOR C, NOT FOR PERL)
131 'o:s', # Output executable
132 'v:i', # Verbosity level
133 'e:s', # One-liner
134 'r', # run resulting executable
135 'B', # Byte compiler backend
136 'O', # Optimised C backend
137 'c', # Compile only
138 'h', # Help me
139 'S', # Dump C files
140 'r', # run the resulting executable
141 'T', # run the backend using perl -T
142 't', # run the backend using perl -t
143 'static', # Dirty hack to enable -shared/-static
144 'shared', # Create a shared library (--shared for compat.)
145 'log:s', # where to log compilation process information
146 'Wb:s', # pass (comma-sepearated) options to backend
147 'testsuite', # try to be nice to testsuite
148 );
149
150 $Options->{v} += 0;
151
152 if( opt(t) && opt(T) ) {
153 warn "Can't specify both -T and -t, -t ignored";
154 $Options->{t} = 0;
155 }
156
157 helpme() if opt(h); # And exit
158
159 $Output = opt(o) || ( is_win32 ? 'a.exe' : 'a.out' );
160 $Output = is_win32() ? $Output : relativize($Output);
161 $logfh = new FileHandle(">> " . opt('log')) if (opt('log'));
162
163 if (opt(e)) {
164 warn "$0: using -e 'code' as input file, ignoring @ARGV\n" if @ARGV;
165 # We don't use a temporary file here; why bother?
166 # XXX: this is not bullet proof -- spaces or quotes in name!
167 $Input = is_win32() ? # Quotes eaten by shell
168 '-e "'.opt(e).'"' :
169 "-e '".opt(e)."'";
170 } else {
171 $Input = shift @ARGV; # XXX: more files?
172 _usage_and_die("$0: No input file specified\n") unless $Input;
173 # DWIM modules. This is bad but necessary.
174 $Options->{shared}++ if $Input =~ /\.pm\z/;
175 warn "$0: using $Input as input file, ignoring @ARGV\n" if @ARGV;
176 check_read($Input);
177 check_perl($Input);
178 sanity_check();
179 }
180
181}
182
183sub opt(*) {
184 my $opt = shift;
185 return exists($Options->{$opt}) && ($Options->{$opt} || 0);
186}
187
188sub compile_module {
189 die "$0: Compiling to shared libraries is currently disabled\n";
190}
191
192sub compile_byte {
193 require ByteLoader;
194 my $stash = grab_stash();
195 my $command = "$BinPerl -MO=Bytecode,$stash $Input";
196 # The -a option means we'd have to close the file and lose the
197 # lock, which would create the tiniest of races. Instead, append
198 # the output ourselves.
199 vprint 1, "Writing on $Output";
200
201 my $openflags = O_WRONLY | O_CREAT;
202 $openflags |= O_BINARY if eval { O_BINARY; 1 };
203 $openflags |= O_EXLOCK if eval { O_EXLOCK; 1 };
204
205 # these dies are not "$0: .... \n" because they "can't happen"
206
207 sysopen(OUT, $Output, $openflags)
208 or die "can't write to $Output: $!";
209
210 # this is blocking; hold on; why are we doing this??
211 # flock OUT, LOCK_EX or die "can't lock $Output: $!"
212 # unless eval { O_EXLOCK; 1 };
213
214 truncate(OUT, 0)
215 or die "couldn't trunc $Output: $!";
216
217 print OUT <<EOF;
218#!$^X
219use ByteLoader $ByteLoader::VERSION;
220EOF
221
222 # Now the compile:
223 vprint 1, "Compiling...";
224 vprint 3, "Calling $command";
225
226 my ($output_r, $error_r) = spawnit($command);
227
228 if (@$error_r && $? != 0) {
229 _die("$0: $Input did not compile, which can't happen:\n@$error_r\n");
230 } else {
231 my @error = grep { !/^$Input syntax OK$/o } @$error_r;
232 warn "$0: Unexpected compiler output:\n@error" if @error;
233 }
234
235 # Write it and leave.
236 print OUT @$output_r or _die("can't write $Output: $!");
237 close OUT or _die("can't close $Output: $!");
238
239 # wait, how could it be anything but what you see next?
240 chmod 0777 & ~umask, $Output or _die("can't chmod $Output: $!");
241 exit 0;
242}
243
244sub compile_cstyle {
245 my $stash = grab_stash();
246 my $taint = opt(T) ? '-T' :
247 opt(t) ? '-t' : '';
248
249 # What are we going to call our output C file?
250 my $lose = 0;
251 my ($cfh);
252 my $testsuite = '';
253 my $addoptions = opt(Wb);
254
255 if( $addoptions ) {
256 $addoptions .= ',' if $addoptions !~ m/,$/;
257 }
258
259 if (opt(testsuite)) {
260 my $bo = join '', @begin_output;
261 $bo =~ s/\\/\\\\\\\\/gs;
262 $bo =~ s/\n/\\n/gs;
263 $bo =~ s/,/\\054/gs;
264 # don't look at that: it hurts
265 $testsuite = q{-fuse-script-name,-fsave-data,-fsave-sig-hash,}.
266 qq[-e"print q{$bo}",] .
267 q{-e"open(Test::Builder::TESTOUT\054 '>&STDOUT') or die $!",} .
268 q{-e"open(Test::Builder::TESTERR\054 '>&STDERR') or die $!",};
269 }
270 if (opt(S) || opt(c)) {
271 # We need to keep it.
272 if (opt(e)) {
273 $cfile = "a.out.c";
274 } else {
275 $cfile = $Input;
276 # File off extension if present
277 # hold on: plx is executable; also, careful of ordering!
278 $cfile =~ s/\.(?:p(?:lx|l|h)|m)\z//i;
279 $cfile .= ".c";
280 $cfile = $Output if opt(c) && $Output =~ /\.c\z/i;
281 }
282 check_write($cfile);
283 } else {
284 # Don't need to keep it, be safe with a tempfile.
285 $lose = 1;
286 ($cfh, $cfile) = tempfile("pccXXXXX", SUFFIX => ".c");
287 close $cfh; # See comment just below
288 }
289 vprint 1, "Writing C on $cfile";
290
291 my $max_line_len = '';
292 if ($^O eq 'MSWin32' && $Config{cc} =~ /^cl/i) {
293 $max_line_len = '-l2000,';
294 }
295
296 # This has to do the write itself, so we can't keep a lock. Life
297 # sucks.
298 my $command = "$BinPerl $taint -MO=$Backend,$addoptions$testsuite$max_line_len$stash,-o$cfile $Input";
299 vprint 1, "Compiling...";
300 vprint 1, "Calling $command";
301
302 my ($output_r, $error_r) = spawnit($command);
303 my @output = @$output_r;
304 my @error = @$error_r;
305
306 if (@error && $? != 0) {
307 _die("$0: $Input did not compile, which can't happen:\n@error\n");
308 }
309
310 is_msvc ?
311 cc_harness_msvc($cfile,$stash) :
312 cc_harness($cfile,$stash) unless opt(c);
313
314 if ($lose) {
315 vprint 2, "unlinking $cfile";
316 unlink $cfile or _die("can't unlink $cfile: $!");
317 }
318}
319
320sub cc_harness_msvc {
321 my ($cfile,$stash)=@_;
322 use ExtUtils::Embed ();
323 my $obj = "${Output}.obj";
324 my $compile = ExtUtils::Embed::ccopts." -c -Fo$obj $cfile ";
325 my $link = "-out:$Output $obj";
326 $compile .= " -I".$_ for split /\s+/, opt(I);
327 $link .= " -libpath:".$_ for split /\s+/, opt(L);
328 my @mods = split /-?u /, $stash;
329 $link .= " ".ExtUtils::Embed::ldopts("-std", \@mods);
330 $link .= " perl57.lib kernel32.lib msvcrt.lib";
331 vprint 3, "running $Config{cc} $compile";
332 system("$Config{cc} $compile");
333 vprint 3, "running $Config{ld} $link";
334 system("$Config{ld} $link");
335}
336
337sub cc_harness {
338 my ($cfile,$stash)=@_;
339 use ExtUtils::Embed ();
340 my $command = ExtUtils::Embed::ccopts." -o $Output $cfile ";
341 $command .= " -I".$_ for split /\s+/, opt(I);
342 $command .= " -L".$_ for split /\s+/, opt(L);
343 my @mods = split /-?u /, $stash;
344 $command .= " ".ExtUtils::Embed::ldopts("-std", \@mods);
345 $command .= " -lperl";
346 vprint 3, "running $Config{cc} $command";
347 system("$Config{cc} $command");
348}
349
350# Where Perl is, and which include path to give it.
351sub yclept {
352 my $command = "$^X ";
353
354 # DWIM the -I to be Perl, not C, include directories.
355 if (opt(I) && $Backend eq "Bytecode") {
356 for (split /\s+/, opt(I)) {
357 if (-d $_) {
358 push @INC, $_;
359 } else {
360 warn "$0: Include directory $_ not found, skipping\n";
361 }
362 }
363 }
364
365 $command .= "-I$_ " for @INC;
366 return $command;
367}
368
369# Use B::Stash to find additional modules and stuff.
370{
371 my $_stash;
372 sub grab_stash {
373
374 warn "already called get_stash once" if $_stash;
375
376 my $taint = opt(T) ? '-T' :
377 opt(t) ? '-t' : '';
378 my $command = "$BinPerl $taint -MB::Stash -c $Input";
379 # Filename here is perfectly sanitised.
380 vprint 3, "Calling $command\n";
381
382 my ($stash_r, $error_r) = spawnit($command);
383 my @stash = @$stash_r;
384 my @error = @$error_r;
385
386 if (@error && $? != 0) {
387 _die("$0: $Input did not compile:\n@error\n");
388 }
389
390 # band-aid for modules with noisy BEGIN {}
391 foreach my $i ( @stash ) {
392 $i =~ m/-u(?:[\w:]+|\<none\>)$/ and $stash[0] = $i and next;
393 push @begin_output, $i;
394 }
395 chomp $stash[0];
396 $stash[0] =~ s/,-u\<none\>//;
397 $stash[0] =~ s/^.*?-u/-u/s;
398 vprint 2, "Stash: ", join " ", split /,?-u/, $stash[0];
399 chomp $stash[0];
400 return $_stash = $stash[0];
401 }
402
403}
404
405# Check the consistency of options if -B is selected.
406# To wit, (-B|-O) ==> no -shared, no -S, no -c
407sub checkopts_byte {
408
409 _die("$0: Please choose one of either -B and -O.\n") if opt(O);
410
411 if (opt(shared)) {
412 warn "$0: Will not create a shared library for bytecode\n";
413 delete $Options->{shared};
414 }
415
416 for my $o ( qw[c S] ) {
417 if (opt($o)) {
418 warn "$0: Compiling to bytecode is a one-pass process--",
419 "-$o ignored\n";
420 delete $Options->{$o};
421 }
422 }
423
424}
425
426# Check the input and output files make sense, are read/writeable.
427sub sanity_check {
428 if ($Input eq $Output) {
429 if ($Input eq 'a.out') {
430 _die("$0: Compiling a.out is probably not what you want to do.\n");
431 # You fully deserve what you get now. No you *don't*. typos happen.
432 } else {
433 warn "$0: Will not write output on top of input file, ",
434 "compiling to a.out instead\n";
435 $Output = "a.out";
436 }
437 }
438}
439
440sub check_read {
441 my $file = shift;
442 unless (-r $file) {
443 _die("$0: Input file $file is a directory, not a file\n") if -d _;
444 unless (-e _) {
445 _die("$0: Input file $file was not found\n");
446 } else {
447 _die("$0: Cannot read input file $file: $!\n");
448 }
449 }
450 unless (-f _) {
451 # XXX: die? don't try this on /dev/tty
452 warn "$0: WARNING: input $file is not a plain file\n";
453 }
454}
455
456sub check_write {
457 my $file = shift;
458 if (-d $file) {
459 _die("$0: Cannot write on $file, is a directory\n");
460 }
461 if (-e _) {
462 _die("$0: Cannot write on $file: $!\n") unless -w _;
463 }
464 unless (-w cwd()) {
465 _die("$0: Cannot write in this directory: $!\n");
466 }
467}
468
469sub check_perl {
470 my $file = shift;
471 unless (-T $file) {
472 warn "$0: Binary `$file' sure doesn't smell like perl source!\n";
473 print "Checking file type... ";
474 system("file", $file);
475 _die("Please try a perlier file!\n");
476 }
477
478 open(my $handle, "<", $file) or _die("XXX: can't open $file: $!");
479 local $_ = <$handle>;
480 if (/^#!/ && !/perl/) {
481 _die("$0: $file is a ", /^#!\s*(\S+)/, " script, not perl\n");
482 }
483
484}
485
486# File spawning and error collecting
487sub spawnit {
488 my ($command) = shift;
489 my (@error,@output);
490 my $errname;
491 (undef, $errname) = tempfile("pccXXXXX");
492 {
493 open (S_OUT, "$command 2>$errname |")
494 or _die("$0: Couldn't spawn the compiler.\n");
495 @output = <S_OUT>;
496 }
497 open (S_ERROR, $errname) or _die("$0: Couldn't read the error file.\n");
498 @error = <S_ERROR>;
499 close S_ERROR;
500 close S_OUT;
501 unlink $errname or _die("$0: Can't unlink error file $errname");
502 return (\@output, \@error);
503}
504
505sub helpme {
506 print "perlcc compiler frontend, version $VERSION\n\n";
507 { no warnings;
508 exec "pod2usage $0";
509 exec "perldoc $0";
510 exec "pod2text $0";
511 }
512}
513
514sub relativize {
515 my ($args) = @_;
516
517 return() if ($args =~ m"^[/\\]");
518 return("./$args");
519}
520
521sub _die {
522 $logfh->print(@_) if opt('log');
523 print STDERR @_;
524 exit(); # should die eventually. However, needed so that a 'make compile'
525 # can compile all the way through to the end for standard dist.
526}
527
528sub _usage_and_die {
529 _die(<<EOU);
530$0: Usage:
531$0 [-o executable] [-r] [-O|-B|-c|-S] [-log log] [source[.pl] | -e oneliner]
532EOU
533}
534
535sub run {
536 my (@commands) = @_;
537
538 print interruptrun(@commands) if (!opt('log'));
539 $logfh->print(interruptrun(@commands)) if (opt('log'));
540}
541
542sub interruptrun
543{
544 my (@commands) = @_;
545
546 my $command = join('', @commands);
547 local(*FD);
548 my $pid = open(FD, "$command |");
549 my $text;
550
551 local($SIG{HUP}) = sub { kill 9, $pid; exit };
552 local($SIG{INT}) = sub { kill 9, $pid; exit };
553
554 my $needalarm =
555 ($ENV{PERLCC_TIMEOUT} &&
556 $Config{'osname'} ne 'MSWin32' &&
557 $command =~ m"(^|\s)perlcc\s");
558
559 eval
560 {
561 local($SIG{ALRM}) = sub { die "INFINITE LOOP"; };
562 alarm($ENV{PERLCC_TIMEOUT}) if ($needalarm);
563 $text = join('', <FD>);
564 alarm(0) if ($needalarm);
565 };
566
567 if ($@)
568 {
569 eval { kill 'HUP', $pid };
570 vprint 0, "SYSTEM TIMEOUT (infinite loop?)\n";
571 }
572
573 close(FD);
574 return($text);
575}
576
577sub is_win32() { $^O =~ m/^MSWin/ }
578sub is_msvc() { is_win32 && $Config{cc} =~ m/^cl/i }
579
580END {
581 unlink $cfile if ($cfile && !opt(S) && !opt(c));
582}
583
584__END__
585
586=head1 NAME
587
588perlcc - generate executables from Perl programs
589
590=head1 SYNOPSIS
591
592 $ perlcc hello # Compiles into executable 'a.out'
593 $ perlcc -o hello hello.pl # Compiles into executable 'hello'
594
595 $ perlcc -O file # Compiles using the optimised C backend
596 $ perlcc -B file # Compiles using the bytecode backend
597
598 $ perlcc -c file # Creates a C file, 'file.c'
599 $ perlcc -S -o hello file # Creates a C file, 'file.c',
600 # then compiles it to executable 'hello'
601 $ perlcc -c out.c file # Creates a C file, 'out.c' from 'file'
602
603 $ perlcc -e 'print q//' # Compiles a one-liner into 'a.out'
604 $ perlcc -c -e 'print q//' # Creates a C file 'a.out.c'
605
606 $ perlcc -I /foo hello # extra headers (notice the space after -I)
607 $ perlcc -L /foo hello # extra libraries (notice the space after -L)
608
609 $ perlcc -r hello # compiles 'hello' into 'a.out', runs 'a.out'.
610 $ perlcc -r hello a b c # compiles 'hello' into 'a.out', runs 'a.out'.
611 # with arguments 'a b c'
612
613 $ perlcc hello -log c # compiles 'hello' into 'a.out' logs compile
614 # log into 'c'.
615
616=head1 DESCRIPTION
617
618F<perlcc> creates standalone executables from Perl programs, using the
619code generators provided by the L<B> module. At present, you may
620either create executable Perl bytecode, using the C<-B> option, or
621generate and compile C files using the standard and 'optimised' C
622backends.
623
624The code generated in this way is not guaranteed to work. The whole
625codegen suite (C<perlcc> included) should be considered B<very>
626experimental. Use for production purposes is strongly discouraged.
627
628=head1 OPTIONS
629
630=over 4
631
632=item -LI<library directories>
633
634Adds the given directories to the library search path when C code is
635passed to your C compiler.
636
637=item -II<include directories>
638
639Adds the given directories to the include file search path when C code is
640passed to your C compiler; when using the Perl bytecode option, adds the
641given directories to Perl's include path.
642
643=item -o I<output file name>
644
645Specifies the file name for the final compiled executable.
646
647=item -c I<C file name>
648
649Create C code only; do not compile to a standalone binary.
650
651=item -e I<perl code>
652
653Compile a one-liner, much the same as C<perl -e '...'>
654
655=item -S
656
657Do not delete generated C code after compilation.
658
659=item -B
660
661Use the Perl bytecode code generator.
662
663=item -O
664
665Use the 'optimised' C code generator. This is more experimental than
666everything else put together, and the code created is not guaranteed to
667compile in finite time and memory, or indeed, at all.
668
669=item -v
670
671Increase verbosity of output; can be repeated for more verbose output.
672
673=item -r
674
675Run the resulting compiled script after compiling it.
676
677=item -log
678
679Log the output of compiling to a file rather than to stdout.
680
681=back
682
683=cut
684