2 eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
3 if $running_under_some_shell;
4 --$running_under_some_shell;
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
17 use Fcntl
qw(:DEFAULT :flock);
18 use File
::Temp
qw(tempfile);
23 $SIG{INT
} = sub { exit(); }; # exit gracefully and clean up after ourselves.
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
30 sub opt
(*); # imal quoting
32 our ($Options, $BinPerl, $Backend);
33 our ($Input => $Output);
37 # eval { main(); 1 } or die;
47 _die
("XXX: Not reached?");
50 #######################################################################
57 $Backend = 'Bytecode';
59 if (opt
(S
) && opt
(c
)) {
60 # die "$0: Do you want me to compile this or not?\n";
63 $Backend = 'CC' if opt
(O
);
69 vprint
0, "Compiling $Input";
71 $BinPerl = yclept
(); # Calling convention for perl.
76 if ($Backend eq 'Bytecode') {
82 exit(0) if (!opt
('r'));
86 vprint
0, "Running code";
91 # usage: vprint [level] msg args
96 } elsif ($_[0] =~ /^\d$/) {
99 # well, they forgot to use a number; means >0
103 $msg .= "\n" unless substr($msg, -1) eq "\n";
106 print "$0: $msg" if !opt
('log');
107 print $logfh "$0: $msg" if opt
('log');
114 # Getopt::Long::Configure("bundling"); turned off. this is silly because
115 # it doesn't allow for long switches.
116 Getopt
::Long
::Configure
("no_ignore_case");
118 # no difference in exists and defined for %ENV; also, a "0"
119 # argument or a "" would not help cc, so skip
120 unshift @ARGV, split ' ', $ENV{PERLCC_OPTS
} if $ENV{PERLCC_OPTS
};
123 Getopt
::Long
::GetOptions
( $Options,
124 'L:s', # lib directory
125 'I:s', # include directories (FOR C, NOT FOR PERL)
126 'o:s', # Output executable
127 'v:i', # Verbosity level
129 'r', # run resulting executable
130 'B', # Byte compiler backend
131 'O', # Optimised C backend
135 'r', # run the resulting executable
136 'static', # Dirty hack to enable -shared/-static
137 'shared', # Create a shared library (--shared for compat.)
138 'log:s' # where to log compilation process information
141 # This is an attempt to make perlcc's arg. handling look like cc.
142 # if ( opt('s') ) { # must quote: looks like s)foo)bar)!
143 # if (opt('s') eq 'hared') {
144 # $Options->{shared}++;
145 # } elsif (opt('s') eq 'tatic') {
146 # $Options->{static}++;
148 # warn "$0: Unknown option -s", opt('s');
154 helpme
() if opt
(h
); # And exit
156 $Output = opt
(o
) || 'a.out';
157 $Output = relativize
($Output);
158 $logfh = new FileHandle
(">> " . opt
('log')) if (opt
('log'));
161 warn "$0: using -e 'code' as input file, ignoring @ARGV\n" if @ARGV;
162 # We don't use a temporary file here; why bother?
163 # XXX: this is not bullet proof -- spaces or quotes in name!
164 $Input = "-e '".opt
(e
)."'"; # Quotes eaten by shell
166 $Input = shift @ARGV; # XXX: more files?
167 _usage_and_die
("$0: No input file specified\n") unless $Input;
168 # DWIM modules. This is bad but necessary.
169 $Options->{shared
}++ if $Input =~ /\.pm\z/;
170 warn "$0: using $Input as input file, ignoring @ARGV\n" if @ARGV;
180 return exists($Options->{$opt}) && ($Options->{$opt} || 0);
184 die "$0: Compiling to shared libraries is currently disabled\n";
189 my $stash = grab_stash
();
190 my $command = "$BinPerl -MO=Bytecode,$stash $Input";
191 # The -a option means we'd have to close the file and lose the
192 # lock, which would create the tiniest of races. Instead, append
193 # the output ourselves.
194 vprint
1, "Writing on $Output";
196 my $openflags = O_WRONLY
| O_CREAT
;
197 $openflags |= O_BINARY
if eval { O_BINARY
; 1 };
198 $openflags |= O_EXLOCK
if eval { O_EXLOCK
; 1 };
200 # these dies are not "$0: .... \n" because they "can't happen"
202 sysopen(OUT
, $Output, $openflags)
203 or die "can't write to $Output: $!";
205 # this is blocking; hold on; why are we doing this??
206 # flock OUT, LOCK_EX or die "can't lock $Output: $!"
207 # unless eval { O_EXLOCK; 1 };
210 or die "couldn't trunc $Output: $!";
214 use ByteLoader $ByteLoader::VERSION;
218 vprint
1, "Compiling...";
219 vprint
3, "Calling $command";
221 my ($output_r, $error_r) = spawnit
($command);
223 if (@
$error_r && $?
!= 0) {
224 _die
("$0: $Input did not compile, which can't happen:\n@$error_r\n");
226 my @error = grep { !/^$Input syntax OK$/o } @
$error_r;
227 warn "$0: Unexpected compiler output:\n@error" if @error;
230 # Write it and leave.
231 print OUT @
$output_r or _die
("can't write $Output: $!");
232 close OUT
or _die
("can't close $Output: $!");
234 # wait, how could it be anything but what you see next?
235 chmod 0777 & ~umask, $Output or _die
("can't chmod $Output: $!");
240 my $stash = grab_stash
();
242 # What are we going to call our output C file?
246 if (opt
(S
) || opt
(c
)) {
247 # We need to keep it.
252 # File off extension if present
253 # hold on: plx is executable; also, careful of ordering!
254 $cfile =~ s/\.(?:p(?:lx|l|h)|m)\z//i;
256 $cfile = $Output if opt
(c
) && $Output =~ /\.c\z/i;
260 # Don't need to keep it, be safe with a tempfile.
262 ($cfh, $cfile) = tempfile
("pccXXXXX", SUFFIX
=> ".c");
263 close $cfh; # See comment just below
265 vprint
1, "Writing C on $cfile";
267 my $max_line_len = '';
268 if ($^O
eq 'MSWin32' && $Config{cc
} =~ /^cl/i) {
269 $max_line_len = '-l2000,';
272 # This has to do the write itself, so we can't keep a lock. Life
274 my $command = "$BinPerl -MO=$Backend,$max_line_len$stash,-o$cfile $Input";
275 vprint
1, "Compiling...";
276 vprint
1, "Calling $command";
278 my ($output_r, $error_r) = spawnit
($command);
279 my @output = @
$output_r;
280 my @error = @
$error_r;
282 if (@error && $?
!= 0) {
283 _die
("$0: $Input did not compile, which can't happen:\n@error\n");
286 cc_harness
($cfile,$stash) unless opt
(c
);
289 vprint
2, "unlinking $cfile";
290 unlink $cfile or _die
("can't unlink $cfile: $!");
295 my ($cfile,$stash)=@_;
296 use ExtUtils
::Embed
();
297 my $command = ExtUtils
::Embed
::ccopts
." -o $Output $cfile ";
298 $command .= " -DUSEIMPORTLIB";
299 $command .= " -I".$_ for split /\s+/, opt
(I
);
300 $command .= " -L".$_ for split /\s+/, opt
(L
);
301 my @mods = split /-?u /, $stash;
302 $command .= " ".ExtUtils
::Embed
::ldopts
("-std", \
@mods,['-lperl5_6_1']);
303 vprint
3, "running $Config{cc} $command";
304 system("$Config{cc} $command");
307 # Where Perl is, and which include path to give it.
309 my $command = "$^X ";
311 # DWIM the -I to be Perl, not C, include directories.
312 if (opt
(I
) && $Backend eq "Bytecode") {
313 for (split /\s+/, opt
(I
)) {
317 warn "$0: Include directory $_ not found, skipping\n";
322 $command .= "-I$_ " for @INC;
326 # Use B::Stash to find additional modules and stuff.
331 warn "already called get_stash once" if $_stash;
333 my $command = "$BinPerl -MB::Stash -c $Input";
334 # Filename here is perfectly sanitised.
335 vprint
3, "Calling $command\n";
337 my ($stash_r, $error_r) = spawnit
($command);
338 my @stash = @
$stash_r;
339 my @error = @
$error_r;
341 if (@error && $?
!= 0) {
342 _die
("$0: $Input did not compile:\n@error\n");
345 $stash[0] =~ s/,-u\<none\>//;
346 vprint
2, "Stash: ", join " ", split /,?-u/, $stash[0];
348 return $_stash = $stash[0];
353 # Check the consistency of options if -B is selected.
354 # To wit, (-B|-O) ==> no -shared, no -S, no -c
357 _die
("$0: Please choose one of either -B and -O.\n") if opt
(O
);
360 warn "$0: Will not create a shared library for bytecode\n";
361 delete $Options->{shared
};
364 for my $o ( qw
[c S
] ) {
366 warn "$0: Compiling to bytecode is a one-pass process--",
368 delete $Options->{$o};
374 # Check the input and output files make sense, are read/writeable.
376 if ($Input eq $Output) {
377 if ($Input eq 'a.out') {
378 _die
("$0: Compiling a.out is probably not what you want to do.\n");
379 # You fully deserve what you get now. No you *don't*. typos happen.
381 warn "$0: Will not write output on top of input file, ",
382 "compiling to a.out instead\n";
391 _die
("$0: Input file $file is a directory, not a file\n") if -d _
;
393 _die
("$0: Input file $file was not found\n");
395 _die
("$0: Cannot read input file $file: $!\n");
399 # XXX: die? don't try this on /dev/tty
400 warn "$0: WARNING: input $file is not a plain file\n";
407 _die
("$0: Cannot write on $file, is a directory\n");
410 _die
("$0: Cannot write on $file: $!\n") unless -w _
;
413 _die
("$0: Cannot write in this directory: $!\n");
420 warn "$0: Binary `$file' sure doesn't smell like perl source!\n";
421 print "Checking file type... ";
422 system("file", $file);
423 _die
("Please try a perlier file!\n");
426 open(my $handle, "<", $file) or _die
("XXX: can't open $file: $!");
427 local $_ = <$handle>;
428 if (/^#!/ && !/perl/) {
429 _die
("$0: $file is a ", /^#!\s*(\S+)/, " script, not perl\n");
434 # File spawning and error collecting
436 my ($command) = shift;
439 (undef, $errname) = tempfile
("pccXXXXX");
441 open (S_OUT
, "$command 2>$errname |")
442 or _die
("$0: Couldn't spawn the compiler.\n");
445 open (S_ERROR
, $errname) or _die
("$0: Couldn't read the error file.\n");
449 unlink $errname or _die
("$0: Can't unlink error file $errname");
450 return (\
@output, \
@error);
454 print "perlcc compiler frontend, version $VERSION\n\n";
465 return() if ($args =~ m
"^[/\\]");
470 $logfh->print(@_) if opt
('log');
472 exit(); # should die eventually. However, needed so that a 'make compile'
473 # can compile all the way through to the end for standard dist.
479 $0 [-o executable] [-r] [-O|-B|-c|-S] [-log log] [source[.pl] | -e oneliner]
486 print interruptrun
(@commands) if (!opt
('log'));
487 $logfh->print(interruptrun
(@commands)) if (opt
('log'));
494 my $command = join('', @commands);
496 my $pid = open(FD
, "$command |");
499 local($SIG{HUP
}) = sub { kill 9, $pid; exit };
500 local($SIG{INT
}) = sub { kill 9, $pid; exit };
503 ($ENV{PERLCC_TIMEOUT
} &&
504 $Config{'osname'} ne 'MSWin32' &&
505 $command =~ m
"(^|\s)perlcc\s");
509 local($SIG{ALRM
}) = sub { die "INFINITE LOOP"; };
510 alarm($ENV{PERLCC_TIMEOUT
}) if ($needalarm);
511 $text = join('', <FD
>);
512 alarm(0) if ($needalarm);
517 eval { kill 'HUP', $pid };
518 vprint
0, "SYSTEM TIMEOUT (infinite loop?)\n";
526 unlink $cfile if ($cfile && !opt
(S
) && !opt
(c
));
533 perlcc - generate executables from Perl programs
537 $ perlcc hello # Compiles into executable 'a.out'
538 $ perlcc -o hello hello.pl # Compiles into executable 'hello'
540 $ perlcc -O file # Compiles using the optimised C backend
541 $ perlcc -B file # Compiles using the bytecode backend
543 $ perlcc -c file # Creates a C file, 'file.c'
544 $ perlcc -S -o hello file # Creates a C file, 'file.c',
545 # then compiles it to executable 'hello'
546 $ perlcc -c out.c file # Creates a C file, 'out.c' from 'file'
548 $ perlcc -e 'print q//' # Compiles a one-liner into 'a.out'
549 $ perlcc -c -e 'print q//' # Creates a C file 'a.out.c'
551 $ perlcc -r hello # compiles 'hello' into 'a.out', runs 'a.out'.
553 $ perlcc -r hello a b c # compiles 'hello' into 'a.out', runs 'a.out'.
554 # with arguments 'a b c'
556 $ perlcc hello -log c # compiles 'hello' into 'a.out' logs compile
561 F<perlcc> creates standalone executables from Perl programs, using the
562 code generators provided by the L<B> module. At present, you may
563 either create executable Perl bytecode, using the C<-B> option, or
564 generate and compile C files using the standard and 'optimised' C
567 The code generated in this way is not guaranteed to work. The whole
568 codegen suite (C<perlcc> included) should be considered B<very>
569 experimental. Use for production purposes is strongly discouraged.
575 =item -LI<library directories>
577 Adds the given directories to the library search path when C code is
578 passed to your C compiler.
580 =item -II<include directories>
582 Adds the given directories to the include file search path when C code is
583 passed to your C compiler; when using the Perl bytecode option, adds the
584 given directories to Perl's include path.
586 =item -o I<output file name>
588 Specifies the file name for the final compiled executable.
590 =item -c I<C file name>
592 Create C code only; do not compile to a standalone binary.
594 =item -e I<perl code>
596 Compile a one-liner, much the same as C<perl -e '...'>
600 Do not delete generated C code after compilation.
604 Use the Perl bytecode code generator.
608 Use the 'optimised' C code generator. This is more experimental than
609 everything else put together, and the code created is not guaranteed to
610 compile in finite time and memory, or indeed, at all.
614 Increase verbosity of output; can be repeated for more verbose output.
618 Run the resulting compiled script after compiling it.
622 Log the output of compiling to a file rather than to stdout.