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