perlcc.PL 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239
  1. #! perl
  2. use Config;
  3. use File::Basename qw(&basename &dirname);
  4. use File::Spec;
  5. use Cwd;
  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. # This forces PL files to create target in same directory as PL file.
  14. # This is so that make depend always knows where to find PL derivatives.
  15. $origdir = cwd;
  16. chdir dirname($0);
  17. $file = basename($0, '.PL');
  18. $file .= '.com' if $^O eq 'VMS';
  19. open OUT,">$file" or die "Can't create $file: $!";
  20. print "Extracting $file (with variable substitutions)\n";
  21. # In this section, perl variables will be expanded during extraction.
  22. # You can use $Config{...} to use Configure variables.
  23. print OUT <<"!GROK!THIS!";
  24. $Config{startperl}
  25. eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}'
  26. if \$running_under_some_shell;
  27. --\$running_under_some_shell;
  28. !GROK!THIS!
  29. # In the following, perl variables are not expanded during extraction.
  30. print OUT <<'!NO!SUBS!';
  31. # Version 2.0, Simon Cozens, Thu Mar 30 17:52:45 JST 2000
  32. # Version 2.01, Tom Christiansen, Thu Mar 30 08:25:14 MST 2000
  33. # Version 2.02, Simon Cozens, Sun Apr 16 01:53:36 JST 2000
  34. # Version 2.03, Edward Peschko, Mon Feb 26 12:04:17 PST 2001
  35. # Version 2.04, Enache Adrian, Fri, 18 Jul 2003 23:15:37 +0300
  36. # Version 2.05, Reini Urban, 2009-12-01 00:00:13
  37. # Version 2.06, Reini Urban, 2009-12-28 21:56:15
  38. # Version 2.07, Reini Urban, 2010-06-30 22:32:20
  39. # Version 2.08, Reini Urban, 2010-07-30 21:30:33
  40. # Version 2.09, Reini Urban, 2010-10-11 13:54:52
  41. # Version 2.10, Reini Urban, 2011-02-11 22:58:37
  42. # Version 2.11, Reini Urban, 2011-04-11 20:16:00
  43. # Version 2.12, Reini Urban, 2011-10-02 05:19:00
  44. # Version 2.13, Reini Urban, 2012-01-10 13:03:00
  45. # Version 2.14, Reini Urban, 2012-02-28 09:04:07
  46. # Version 2.15, Reini Urban, 2013-02-01 10:41:54
  47. # Version 2.16, Reini Urban, 2013-11-27 11:36:13
  48. # Version 2.17, Reini Urban, Thu Feb 6 14:04:29 2014 -0600
  49. # Version 2.18, Reini Urban, 2014-05-28
  50. # Version 2.19, Reini Urban, 2014-07-09
  51. # Version 2.20, Reini Urban, 2014-07-23
  52. use strict;
  53. use warnings;
  54. use 5.006_000;
  55. use FileHandle;
  56. use Config;
  57. use Fcntl qw(:DEFAULT :flock);
  58. use File::Temp qw(tempfile);
  59. use File::Basename qw(basename dirname);
  60. # use Cwd;
  61. use Pod::Usage;
  62. # Time::HiRes does not work with 5.6
  63. # use Time::HiRes qw(gettimeofday tv_interval);
  64. our $VERSION = 2.20;
  65. $| = 1;
  66. eval { require B::C::Config; };
  67. $SIG{INT} = sub { exit(); } if exists $SIG{INT}; # exit gracefully and clean up after ourselves.
  68. use subs qw{
  69. cc_harness check_read check_write checkopts_byte choose_backend
  70. compile_byte compile_cstyle compile_module generate_code
  71. grab_stash parse_argv sanity_check vprint yclept spawnit
  72. gettimeofday tv_interval vsystem
  73. };
  74. sub opt(*); # imal quoting
  75. sub is_win32();
  76. sub is_msvc();
  77. our ($Options, $BinPerl, $Backend);
  78. our ($Input => $Output);
  79. our ($logfh);
  80. our ($cfile);
  81. our (@begin_output); # output from BEGIN {}, for testsuite
  82. our ($extra_libs);
  83. # eval { main(); 1 } or die;
  84. main();
  85. sub main {
  86. parse_argv();
  87. check_write($Output);
  88. choose_backend();
  89. generate_code();
  90. run_code();
  91. _die("Not reached?");
  92. }
  93. #######################################################################
  94. sub choose_backend {
  95. # Choose the backend.
  96. $Backend = 'C';
  97. if (opt('B')) {
  98. checkopts_byte();
  99. $Backend = 'Bytecode';
  100. }
  101. if (opt('S') && opt('c')) {
  102. # die "$0: Do you want me to compile this or not?\n";
  103. delete $Options->{S};
  104. }
  105. $Backend = 'CC' if opt('O');
  106. }
  107. sub generate_code {
  108. vprint 4, "Compiling $Input";
  109. $BinPerl = yclept(); # Calling convention for perl.
  110. if (exists $Options->{m}) {
  111. compile_module();
  112. } else {
  113. if ($Backend eq 'Bytecode') {
  114. compile_byte();
  115. } else {
  116. compile_cstyle();
  117. }
  118. }
  119. exit(0) if (!opt('r'));
  120. }
  121. sub run_code {
  122. if ($Backend eq 'Bytecode') {
  123. if ($] < 5.007) {
  124. $Output = "$BinPerl -MByteLoader $Output";
  125. } else {
  126. $Output = "$BinPerl $Output";
  127. }
  128. }
  129. if (opt('staticxs') and $extra_libs) {
  130. my $path = '';
  131. my $PATHSEP = $^O eq 'MSWin32' ? ';' : ':';
  132. for (split / /, $extra_libs) {
  133. s{/[^/]+$}{};
  134. # XXX qx quote?
  135. $path .= $PATHSEP.$_ if $_;
  136. }
  137. if ($^O =~ /^MSWin32|msys|cygwin$/) {
  138. $ENV{PATH} .= $path;
  139. vprint 0, "PATH=\$PATH$path";
  140. } elsif ($^O ne 'darwin') {
  141. $ENV{LD_LIBRARY_PATH} .= $path;
  142. vprint 0, "LD_LIBRARY_PATH=\$LD_LIBRARY_PATH$path";
  143. }
  144. }
  145. vprint 0, "Running code $Output @ARGV";
  146. system(join(" ",$Output,@ARGV));
  147. exit(0);
  148. }
  149. # usage: vprint [level] msg args
  150. sub vprint {
  151. my $level;
  152. if (@_ == 1) {
  153. $level = 1;
  154. } elsif ($_[0] =~ /^-?\d$/) {
  155. $level = shift;
  156. } else {
  157. # well, they forgot to use a number; means >0
  158. $level = 0;
  159. }
  160. my $msg = "@_";
  161. $msg .= "\n" unless substr($msg, -1) eq "\n";
  162. if (opt('v') > $level)
  163. {
  164. if (opt('log')) {
  165. print $logfh "$0: $msg" ;
  166. } else {
  167. print "$0: $msg";
  168. }
  169. }
  170. }
  171. sub vsystem {
  172. if (opt('dryrun')) {
  173. print "@_\n";
  174. } else {
  175. system(@_);
  176. }
  177. }
  178. sub parse_argv {
  179. use Getopt::Long;
  180. # disallows using long arguments
  181. Getopt::Long::Configure("bundling");
  182. Getopt::Long::Configure("no_ignore_case");
  183. # no difference in exists and defined for %ENV; also, a "0"
  184. # argument or a "" would not help cc, so skip
  185. unshift @ARGV, split ' ', $ENV{PERLCC_OPTS} if $ENV{PERLCC_OPTS};
  186. $Options = {};
  187. # support single dash -Wb. GetOptions requires --Wb with bundling enabled.
  188. if (my ($wb) = grep /^-Wb=.+/, @ARGV) {
  189. $Options->{Wb} = $Options->{Wb} ? $Options->{Wb}.",".substr($wb,4) : substr($wb,4);
  190. @ARGV = grep !/^-Wb=(.+)/, @ARGV;
  191. }
  192. # -O2 i.e. -Wb=-O1 (new since 2.13)
  193. if (my ($o1) = grep /^-O(\d)$/, @ARGV) {
  194. $Options->{Wb} = $Options->{Wb} ? $Options->{Wb}.",$o1" : $o1;
  195. @ARGV = grep !/^-O\d$/, @ARGV;
  196. }
  197. if (my ($v) = grep /^-v\d$/, @ARGV) {
  198. $Options->{v} = 0+substr($v,2);
  199. @ARGV = grep !/^-v\d$/, @ARGV;
  200. }
  201. if (grep /^-stash$/, @ARGV) {
  202. $Options->{stash}++;
  203. @ARGV = grep !/^-stash$/, @ARGV;
  204. }
  205. $Options->{spawn} = 1 unless $^O eq 'MSWin32';
  206. Getopt::Long::GetOptions( $Options,
  207. 'L=s', # lib directory
  208. 'I=s', # include directories (FOR C, NOT FOR PERL)
  209. 'o=s', # Output executable
  210. 'v:i', # Verbosity level
  211. 'e=s', # One-liner
  212. 'm|sharedlib:s',# as Module [name] (new since 2.11, not yet tested)
  213. 'r', # run resulting executable
  214. 'B', # Byte compiler backend
  215. 'O', # Optimised C backend B::CC
  216. #'O1-4' # alias for -Wb=-O1 (new since 2.13)
  217. 'dryrun|n', # only print commands, do not execute
  218. 'c', # Compile to C only, no linking
  219. 'check', # pass -c to B::C and exit
  220. 'help|h', # Help me
  221. 'S', # Keep generated C file
  222. 'T', # run the backend using perl -T
  223. 't', # run the backend using perl -t
  224. 'A', # -DALLOW_PERL_OPTIONS like -D?
  225. 'u=s@', # use packages (new since 2.13)
  226. 'U=s@', # skip packages (new since 2.13)
  227. 'static', # Link to static libperl (default, new since 2.11)
  228. 'shared', # Link to shared libperl (new since 2.07)
  229. 'staticxs', # Link static XSUBs (new since 2.07)
  230. 'sharedxs', # Link shared XSUBs (default, new since 2.07))
  231. 'stash', # Detect external packages via B::Stash
  232. 'log:s', # where to log compilation process information
  233. 'Wb=s', # pass (comma-seperated) options to backend
  234. 'f=s@', # pass compiler option(s) to backend (new since 2.14)
  235. 'Wc=s', # pass (comma-seperated) options to cc (new since 2.13)
  236. 'Wl=s', # pass (comma-seperated) options to ld (new since 2.13)
  237. 'testsuite', # try to be nice to testsuite modules (STDOUT, STDERR handles)
  238. 'spawn!', # --no-spawn (new since 2.12)
  239. 'time', # print benchmark timings (new since 2.08)
  240. 'version', # (new since 2.13)
  241. );
  242. $Options->{v} += 0;
  243. if( opt('t') && opt('T') ) {
  244. warn "Can't specify both -T and -t, -t ignored";
  245. $Options->{t} = 0;
  246. }
  247. helpme() if opt('help'); # And exit
  248. if (opt('version')) {
  249. die version();
  250. }
  251. # $Options->{Wb} .= ",-O1" if opt('O1');
  252. # $Options->{Wb} .= ",-O2" if opt('O2');
  253. # $Options->{Wb} .= ",-O3" if opt('O3');
  254. # $Options->{Wb} .= ",-O4" if opt('O4');
  255. $Options->{Wc} .= " -DALLOW_PERL_OPTIONS" if opt('A');
  256. if( $Options->{time} or $Options->{spawn} ) {
  257. eval { require Time::HiRes; }; # 5.6 has no Time::HiRes
  258. if ($@) {
  259. warn "--time ignored. No Time::HiRes\n" if $Options->{time};
  260. $Options->{time} = 0;
  261. } else {
  262. *gettimeofday = *Time::HiRes::gettimeofday;
  263. Time::HiRes::gettimeofday();
  264. Time::HiRes->import('gettimeofday','tv_interval','sleep');
  265. }
  266. }
  267. $logfh = new FileHandle(">> " . opt('log')) if (opt('log'));
  268. if (opt('e')) {
  269. warn "$0: using -e 'code' as input file, ignoring @ARGV\n" if @ARGV;
  270. # We don't use a temporary file here; why bother?
  271. # XXX: this is not bullet proof -- spaces or quotes in name!
  272. $Input = is_win32() ? # Quotes eaten by shell
  273. '-e "'.opt('e').'"' :
  274. "-e '".opt('e')."'";
  275. } else {
  276. $Input = shift @ARGV; # XXX: more files?
  277. _usage_and_die("No input file specified\n") unless $Input;
  278. # DWIM modules. This is bad but necessary.
  279. $Options->{m} = '' if $Input =~ /\.pm\z/ and !opt('m');
  280. vprint 1, "$0: using $Input as input file, ignoring @ARGV\n" if @ARGV;
  281. check_read($Input);
  282. check_perl($Input);
  283. }
  284. if (opt('o')) {
  285. $Output = opt('o');
  286. } elsif (opt('B')) {
  287. if (opt('e')) {
  288. my $suffix = '.plc';
  289. $suffix = '.pmc' if exists $Options->{m};
  290. (undef, $Output) = tempfile("plcXXXXX", SUFFIX => $suffix);
  291. } else {
  292. $Output = basename($Input) . "c";
  293. }
  294. } else {
  295. $Output = opt('e') ? 'a.out' : $Input;
  296. $Output =~ s/\.(p[lm]|t)$//;
  297. if (is_win32() or $^O eq 'cygwin') {
  298. if ($Output eq 'a.out') {
  299. $Output = 'a.exe';
  300. } else {
  301. $Output .= 'exe';
  302. }
  303. }
  304. }
  305. $Output = relativize($Output) unless is_win32();
  306. sanity_check();
  307. }
  308. sub opt(*) {
  309. my $opt = shift;
  310. return exists($Options->{$opt}) && ($Options->{$opt} || 0);
  311. }
  312. sub compile_module {
  313. if ($Backend eq 'Bytecode') {
  314. compile_byte('-m'.$Options->{m});
  315. } else {
  316. compile_cstyle("-m".$Options->{m});
  317. }
  318. }
  319. sub compile_byte {
  320. vprint 3, "Writing B on $Output";
  321. my $opts = $] < 5.007 ? "" : "-H,-s,";
  322. if ($] >= 5.007 and $Input =~ /^-e/) {
  323. $opts = "-H,";
  324. }
  325. if (@_ == 1) {
  326. $opts .= $_[0].",";
  327. }
  328. my $addoptions = opt('Wb');
  329. if( $addoptions ) {
  330. $opts .= '-v,' if opt('v') > 4;
  331. $opts .= '-DM,-DG,-DA,-DComment,' if opt('v') > 5;
  332. $opts .= "$addoptions,";
  333. } elsif (opt('v') > 4) {
  334. $opts .= '-v,';
  335. $opts .= '-DM,-DG,-DA,-DComment,' if opt('v') > 5;
  336. }
  337. my $command = "$BinPerl -MO=Bytecode,$opts-o$Output $Input";
  338. $Input =~ s/^-e.*$/-e/;
  339. vprint 5, "Compiling...";
  340. vprint 0, "Calling $command";
  341. my $t0 = [gettimeofday] if opt('time');
  342. my ($output_r, $error_r, $errcode) = spawnit($command);
  343. my $elapsed = tv_interval ( $t0 ) if opt('time');
  344. vprint -1, "c time: $elapsed" if opt('time');
  345. if (@$error_r && $errcode != 0) {
  346. _die("$Input did not compile $errcode:\n@$error_r\n");
  347. } else {
  348. my @error = grep { !/^$Input syntax OK$/o } @$error_r;
  349. @error = grep { !/^No package specified for compilation, assuming main::$/o } @error;
  350. warn "$0: Unexpected compiler output\n@error" if @error and opt('v')<5;
  351. warn "@error" if @error and opt('v')>4;
  352. }
  353. unless (opt('dryrun')) {
  354. chmod 0777 & ~umask, $Output or _die("can't chmod $Output: $!\n");
  355. }
  356. }
  357. sub compile_cstyle {
  358. my $stash = opt('stash') ? grab_stash() : "";
  359. $stash .= "," if $stash; #stash can be empty
  360. $stash .= "-u$_," for @{$Options->{u}};
  361. $stash .= "-U$_," for @{$Options->{U}};
  362. #if ($ENV{PERL_CORE} and ($Config{ccflags} =~ /-m32/ or $Config{cc} =~ / -m32/)) {
  363. # die "perlcc with -m32 cross compilation is not supported\n";
  364. #}
  365. my $taint = opt('T') ? ' -T' :
  366. opt('t') ? ' -t' : '';
  367. # What are we going to call our output C file?
  368. my $lose = 0;
  369. my ($cfh);
  370. my $testsuite = '';
  371. my $addoptions = '';
  372. if (@_ == 1) {
  373. $addoptions .= $_[0].",";
  374. }
  375. $addoptions .= opt('Wb');
  376. if( $addoptions ) {
  377. $addoptions .= ',-Dfull' if opt('v') >= 6;
  378. $addoptions .= ',-Dsp,-v' if opt('v') == 5;
  379. $addoptions .= ',';
  380. } elsif (opt('v') > 4) {
  381. $addoptions = '-Dsp,-v,';
  382. $addoptions = '-Dfull,-v,' if opt('v') >= 6;
  383. }
  384. if (opt('f')) {
  385. $addoptions .= "-f$_," for @{$Options->{f}};
  386. }
  387. if (opt('check')) {
  388. $addoptions .= "-c,";
  389. }
  390. my $staticxs = opt('staticxs') ? "-staticxs," : '';
  391. warn "Warning: --staticxs on darwin is very experimental\n"
  392. if $staticxs and $^O eq 'darwin';
  393. if (opt('testsuite')) {
  394. my $bo = join '', @begin_output;
  395. $bo =~ s/\\/\\\\\\\\/gs;
  396. $bo =~ s/\n/\\n/gs;
  397. $bo =~ s/,/\\054/gs;
  398. # don't look at that: it hurts
  399. $testsuite = q{-fuse-script-name,-fsave-data,-fsave-sig-hash,}.
  400. qq[-e"print q{$bo}",] .
  401. q{-e"open(Test::Builder::TESTOUT\054 '>&STDOUT') or die $!",} .
  402. q{-e"open(Test::Builder::TESTERR\054 '>&STDERR') or die $!",};
  403. }
  404. if (opt('check')) {
  405. $cfile = "";
  406. $staticxs = "";
  407. } elsif (opt('o')) {
  408. $cfile = opt('o').".c";
  409. if ((is_win32() or $^O eq 'cygwin') and $Output =~ /\.exe.c$/) {
  410. $cfile =~ s/\.exe\.c$/.c/,
  411. }
  412. } elsif (opt('S') || opt('c')) { # We need to keep it
  413. if (opt('e')) {
  414. $cfile = $Output;
  415. if ((is_win32() or $^O eq 'cygwin') and $Output =~ /\.exe$/) {
  416. $cfile =~ s/\.exe$//,
  417. }
  418. $cfile .= '.c';
  419. } else {
  420. $cfile = basename($Input);
  421. # File off extension if present
  422. # hold on: plx is executable; also, careful of ordering!
  423. $cfile =~ s/\.(?:p(?:lx|l|h)|m)\z//i;
  424. $cfile .= ".c";
  425. $cfile = $Output if opt('c') && $Output =~ /\.c\z/i;
  426. }
  427. check_write($cfile);
  428. } else { # Do not keep tempfiles (no -S nor -c nor -o)
  429. $lose = 1;
  430. ($cfh, $cfile) = tempfile("pccXXXXX", SUFFIX => ".c");
  431. close $cfh; # See comment just below
  432. }
  433. vprint 3, "Writing C on $cfile" unless opt('check');
  434. my $max_line_len = '';
  435. if ($^O eq 'MSWin32' && $Config{cc} =~ /^cl/i) {
  436. $max_line_len = '-l2000,';
  437. }
  438. my $options = "$addoptions$testsuite$max_line_len$staticxs$stash";
  439. $options .= "-o$cfile" unless opt('check');
  440. $options = substr($options,0,-1) if substr($options,-1,1) eq ",";
  441. # This has to do the write itself, so we can't keep a lock. Life
  442. # sucks.
  443. my $command = "$BinPerl$taint -MO=$Backend,$options $Input";
  444. vprint 5, "Compiling...";
  445. vprint 0, "Calling $command";
  446. my $t0 = [gettimeofday] if opt('time');
  447. my ($output_r, $error_r, $errcode) = spawnit($command);
  448. my $elapsed = tv_interval ( $t0 ) if opt('time');
  449. my @output = @$output_r;
  450. my @error = @$error_r;
  451. if (@error && $errcode != 0) {
  452. _die("$Input did not compile, which can't happen $errcode:\n@error\n");
  453. } else {
  454. my $i = substr($Input,0,2) eq '-e' ? '-e' : $Input;
  455. @error = grep { !/^$i syntax OK$/o } @error;
  456. if (opt('check')) {
  457. print "@error" if @error;
  458. } else {
  459. warn "$0: Unexpected compiler output\n@error" if @error and opt('v')<5;
  460. warn "@error" if @error and opt('v')>4;
  461. }
  462. }
  463. vprint -1, "c time: $elapsed" if opt('time');
  464. $extra_libs = '';
  465. my %rpath;
  466. if ($staticxs and open(XS, "<", $cfile.".lst")) {
  467. while (<XS>) {
  468. my ($s, $l) = m/^([^\t]+)(.*)$/;
  469. next if grep { $s eq $_ } @{$Options->{U}};
  470. $stash .= ",-u$s";
  471. if ($l) {
  472. $l = substr($l,1);
  473. if ($^O eq 'darwin' and $l =~/\.bundle$/) {
  474. my $ofile = $l;
  475. $ofile =~ s/\.bundle$/.o/;
  476. $ofile =~ s{^.*/auto/}{};
  477. $ofile =~ s{(.*)/[^/]+\.o}{$1.o};
  478. $ofile =~ s{/}{_}g;
  479. $ofile = 'pcc'.$ofile;
  480. if (-e $ofile) {
  481. vprint 3, "Using ".$ofile;
  482. } else {
  483. vprint 3, "Creating ".$ofile;
  484. # This fails sometimes
  485. my $cmd = "otool -tv $l | \"$^X\" -pe "
  486. . q{'s{^/}{# .file /};s/^00[0-9a-f]+\s/\t/;s/^\(__(\w+)(,__.*?)?\) section/q(.).lc($1)/e'}
  487. . " | as -o \"$ofile\"";
  488. vprint 3, $cmd;
  489. vsystem($cmd);
  490. }
  491. $extra_libs .= " ".$l if -e $ofile;
  492. } else {
  493. $extra_libs .= " ".$l;
  494. $rpath{dirname($l)}++;
  495. }
  496. }
  497. }
  498. close XS;
  499. my ($rpath) = $Config{ccdlflags} =~ /^(.+rpath,)/;
  500. ($rpath) = $Config{ccdlflags} =~ m{^(.+-R,)/} unless $rpath;
  501. if (!$rpath and $Config{gccversion}) {
  502. $rpath = '-Wl,-rpath,';
  503. }
  504. $rpath =~ s/^-Wl,-E// if $rpath; # already done via ccdlflags
  505. # $extra_libs .= " $rpath".join(" ".$rpath,keys %rpath) if $rpath and %rpath;
  506. vprint 4, "staticxs: $stash $extra_libs";
  507. }
  508. exit if opt('check');
  509. $t0 = [gettimeofday] if opt('time');
  510. is_msvc ?
  511. cc_harness_msvc($cfile, $stash, $extra_libs) :
  512. cc_harness($cfile, $stash, $extra_libs) unless opt('c');
  513. $elapsed = tv_interval ( $t0 ) if opt('time');
  514. vprint -1, "cc time: $elapsed" if opt('time');
  515. if ($lose and -s $Output) {
  516. vprint 3, "Unlinking $cfile";
  517. unlink $cfile or _die("can't unlink $cfile: $!\n");
  518. }
  519. }
  520. sub cc_harness_msvc {
  521. my ($cfile, $stash, $extra_libs) = @_;
  522. use ExtUtils::Embed ();
  523. my $obj = "${Output}.obj";
  524. my $compile = ExtUtils::Embed::ccopts." -c -Fo$obj $cfile ";
  525. my $link = "-out:$Output $obj";
  526. $compile .= " -DHAVE_INDEPENDENT_COMALLOC" if $B::C::Config::have_independent_comalloc;
  527. $compile .= $B::C::Config::extra_cflags;
  528. $compile .= " -I".$_ for split /\s+/, opt('I');
  529. $compile .= " -DSTATICXS" if opt('staticxs');
  530. $compile .= " ".opt('Wc') if opt('Wc');
  531. $link .= " -libpath:".$_ for split /\s+/, opt('L');
  532. # TODO: -shared,-static,-sharedxs
  533. if ($stash) {
  534. my @mods = split /,?-?u/, $stash; # XXX -U stashes
  535. $link .= " ".ExtUtils::Embed::ldopts("-std", \@mods);
  536. # XXX staticxs need to check if the last mods for staticxs found a static lib.
  537. # XXX only if not use the extra_libs
  538. } else {
  539. $link .= " ".ExtUtils::Embed::ldopts("-std");
  540. }
  541. if ($Config{ccversion} eq '12.0.8804') {
  542. $link =~ s/ -opt:ref,icf//;
  543. }
  544. $link .= " ".opt('Wl') if opt('Wl');
  545. if (opt('staticxs')) { # TODO: can msvc link to dll's directly? otherwise use dlltool
  546. $extra_libs =~ s/^\s+|\s+$//g; # code by stengcode@gmail.com
  547. foreach (split /\.dll(?:\s+|$)/, $extra_libs) {
  548. $_ .= '.lib';
  549. if (!-e $_) {
  550. die "--staticxs requires $_, you should copy it from build area";
  551. }
  552. else {
  553. $link .= ' ' . $_;
  554. }
  555. }
  556. } else {
  557. $link .= $extra_libs;
  558. }
  559. $link .= " perl5$Config{PERL_VERSION}.lib kernel32.lib msvcrt.lib";
  560. $link .= $B::C::Config::extra_libs;
  561. vprint 3, "Calling $Config{cc} $compile";
  562. vsystem("$Config{cc} $compile");
  563. vprint 3, "Calling $Config{ld} $link";
  564. vsystem("$Config{ld} $link");
  565. }
  566. sub cc_harness {
  567. my ($cfile, $stash, $extra_libs) = @_;
  568. use ExtUtils::Embed ();
  569. my $command = ExtUtils::Embed::ccopts." -o $Output $cfile ";
  570. if ($ENV{PERL_CORE}) {
  571. $command = "$Config{ccflags} -I../.. -L../.. -o $Output $cfile ";
  572. }
  573. $command .= " -DHAVE_INDEPENDENT_COMALLOC" if $B::C::Config::have_independent_comalloc;
  574. $command .= $B::C::Config::extra_cflags if $B::C::Config::extra_cflags;
  575. $command .= " -I".$_ for split /\s+/, opt('I');
  576. $command .= " -L".$_ for split /\s+/, opt('L');
  577. $command .= " -DSTATICXS" if opt('staticxs');
  578. $command .= " ".opt('Wc') if opt('Wc');
  579. my $ccflags = $command;
  580. my $useshrplib = $Config{useshrplib};
  581. _die("--sharedxs with useshrplib=false\n") if !$useshrplib and opt('sharedxs');
  582. my $ldopts;
  583. if ($stash) {
  584. my @mods = split /,?-?u/, $stash; # XXX -U stashes
  585. $ldopts = ExtUtils::Embed::ldopts("-std", \@mods);
  586. } else {
  587. $ldopts = ExtUtils::Embed::ldopts("-std");
  588. }
  589. $ldopts .= " ".opt('Wl') if opt('Wl');
  590. # gcc crashes with this duplicate -fstack-protector arg
  591. my $ldflags = $Config{ldflags};
  592. if ($^O eq 'cygwin' and $ccflags =~ /-fstack-protector\b/
  593. and $ldopts =~ /-fstack-protector\b/)
  594. {
  595. $ldopts =~ s/-fstack-protector\b//;
  596. $ldflags =~ s/-fstack-protector\b// if $extra_libs;
  597. }
  598. my ($libperl, $libdir, $coredir) = ($Config{libperl});
  599. if ($ENV{PERL_CORE}) {
  600. $libdir = $coredir = "../..";
  601. } else {
  602. $libdir = $Config{prefix} . "/lib";
  603. $coredir = $ENV{PERL_SRC} || $Config{archlib}."/CORE";
  604. }
  605. if ($extra_libs) {
  606. # splice extra_libs after $Config{ldopts} before @archives
  607. my $i_ldopts = index($ldopts, $ldflags);
  608. if ($ldflags and $i_ldopts >= 0) {
  609. my $l = $i_ldopts + length($ldflags);
  610. $ldopts = substr($ldopts,0,$l).$extra_libs." ".substr($ldopts,$l);
  611. } else {
  612. $ldopts = $extra_libs." ".$ldopts;
  613. }
  614. }
  615. if (opt('shared')) {
  616. warn "--shared with useshrplib=false might not work\n" unless $useshrplib;
  617. my @plibs = ($libperl, "$coredir/$libperl", "$libdir/$libperl");
  618. if ($libperl !~ /$Config{dlext}$/) {
  619. $libperl = "libperl.".$Config{dlext};
  620. @plibs = ($libperl, "$coredir/$libperl", "$libdir/$libperl");
  621. push @plibs, glob "$coredir/*perl5*".$Config{dlext};
  622. push @plibs, glob "$coredir/*perl.".$Config{dlext};
  623. push @plibs, glob $libdir."/*perl5*.".$Config{dlext};
  624. push @plibs, glob $libdir."/*perl.".$Config{dlext};
  625. push @plibs, glob $Config{bin}."/perl*.".$Config{dlext};
  626. }
  627. for my $lib (@plibs) {
  628. if (-e $lib) {
  629. $ldopts =~ s|-lperl |$lib |;
  630. $ldopts =~ s|\s+\S+libperl\w+\.a | $lib |;
  631. $ldopts = "$coredir/DynaLoader.o $ldopts" if -e "$coredir/DynaLoader.o";
  632. last;
  633. }
  634. }
  635. } elsif (opt('static')) {
  636. for my $lib ($libperl, "$coredir/$libperl", "$coredir/$libperl",
  637. "$coredir/libperl.a", "$libdir/libperl.a") {
  638. if (-e $lib) {
  639. $ldopts =~ s|-lperl |$lib |;
  640. $ldopts = "$coredir/DynaLoader.o $ldopts" if -e "$coredir/DynaLoader.o";
  641. last;
  642. }
  643. }
  644. } else {
  645. if ( $useshrplib and -e $libdir."/".$Config{libperl}) {
  646. # debian: only /usr/lib/libperl.so.5.10.1 and broken ExtUtils::Embed::ldopts
  647. $ldopts =~ s|-lperl |$libdir/$Config{libperl} |;
  648. }
  649. if ( $useshrplib and -e $coredir."/".$Config{libperl}) {
  650. # help cygwin debugging, and workaround wrong debian linker prefs (/usr/lib before given -L)
  651. $ldopts =~ s|-lperl |$coredir/$Config{libperl} |;
  652. }
  653. }
  654. unless ( $command =~ m{( -lperl|/CORE\/libperl)} ) {
  655. $ldopts .= " -lperl";
  656. $ldopts .= " $Config{libs}" if $ENV{PERL_CORE}; # no -L found at all
  657. }
  658. $command .= " ".$ldopts;
  659. $command .= $B::C::Config::extra_libs if $B::C::Config::extra_libs;
  660. vprint 3, "Calling $Config{cc} $command";
  661. vsystem("$Config{cc} $command");
  662. }
  663. # Where Perl is, and which include path to give it.
  664. sub yclept {
  665. my $command = $^X =~ m/\s/ ? qq{"$^X"} : $^X;
  666. # DWIM the -I to be Perl, not C, include directories.
  667. if (opt('I') && $Backend eq "Bytecode") {
  668. for (split /\s+/, opt('I')) {
  669. if (-d $_) {
  670. push @INC, $_;
  671. } else {
  672. warn "$0: Include directory $_ not found, skipping\n";
  673. }
  674. }
  675. }
  676. my %OINC;
  677. $OINC{$Config{$_}}++ for (qw(privlib archlib sitelib sitearch vendorlib vendorarch));
  678. $OINC{'.'}++ unless ${^TAINT};
  679. $OINC{$_}++ for split ':', $Config{otherlibdirs};
  680. if (my $incver = $Config{inc_version_list}) {
  681. my $incpre = dirname($Config{sitelib});
  682. $OINC{$_}++ for map { File::Spec->catdir($incpre,$_) } split(' ',$incver);
  683. $OINC{$incpre}++;
  684. }
  685. for my $i (@INC) {
  686. my $inc = $i =~ m/\s/ ? qq{"$i"} : $i;
  687. $command .= " -I$inc" unless $OINC{$i}; # omit internal @INC dirs
  688. }
  689. return $command;
  690. }
  691. # Use B::Stash to find additional modules and stuff.
  692. {
  693. my $_stash;
  694. sub grab_stash {
  695. warn "already called grab_stash once" if $_stash;
  696. my $taint = opt('T') ? ' -T' :
  697. opt('t') ? ' -t' : '';
  698. my $command = "$BinPerl$taint -MB::Stash -c $Input";
  699. # Filename here is perfectly sanitised.
  700. vprint 3, "Calling $command\n";
  701. my ($stash_r, $error_r, $errcode) = spawnit($command);
  702. my @stash = @$stash_r;
  703. my @error = @$error_r;
  704. if (@error && $errcode != 0) {
  705. _die("$Input did not compile $errcode:\n@error\n");
  706. }
  707. # band-aid for modules with noisy BEGIN {}
  708. foreach my $i ( @stash ) {
  709. $i =~ m/-[ux](?:[\w:]+|\<none\>)$/ and $stash[0] = $i and next;
  710. push @begin_output, $i;
  711. }
  712. chomp $stash[0];
  713. $stash[0] =~ s/,-[ux]\<none\>//;
  714. $stash[0] =~ s/^.*?-([ux])/-$1/s;
  715. vprint 2, "Stash: ", join " ", split /,?-[ux]/, $stash[0];
  716. chomp $stash[0];
  717. return $_stash = $stash[0];
  718. }
  719. }
  720. # Check the consistency of options if -B is selected.
  721. # To wit, (-B|-O) ==> no -shared, no -S, no -c
  722. sub checkopts_byte {
  723. _die("Please choose one of either -B and -O.\n") if opt('O');
  724. for my $o ( qw[shared sharedxs static staticxs] ) {
  725. if (exists($Options->{$o}) && $Options->{$o}) {
  726. warn "$0: --$o incompatible with -B\n";
  727. delete $Options->{$o};
  728. }
  729. }
  730. # TODO make -S produce an .asm also?
  731. for my $o ( qw[c S] ) {
  732. if (exists($Options->{$o}) && $Options->{$o}) {
  733. warn "$0: Compiling to bytecode is a one-pass process. ",
  734. "-$o ignored\n";
  735. delete $Options->{$o};
  736. }
  737. }
  738. }
  739. # Check the input and output files make sense, are read/writeable.
  740. sub sanity_check {
  741. if ($Input eq $Output) {
  742. if ($Input eq 'a.out') {
  743. _die("Compiling a.out is probably not what you want to do.\n");
  744. # You fully deserve what you get now. No you *don't*. typos happen.
  745. } else {
  746. my $suffix = (is_win32() or $^O eq 'cygwin') ? '.exe' : '';
  747. (undef, $Output) = tempfile("plcXXXXX", SUFFIX => $suffix);
  748. warn "$0: Will not write output on top of input file, ",
  749. "compiling to $Output instead\n";
  750. }
  751. }
  752. }
  753. sub check_read {
  754. my $file = shift;
  755. unless (-r $file) {
  756. _die("Input file $file is a directory, not a file\n") if -d _;
  757. unless (-e _) {
  758. _die("Input file $file was not found\n");
  759. } else {
  760. _die("Cannot read input file $file: $!\n");
  761. }
  762. }
  763. unless (-f _) {
  764. # XXX: die? don't try this on /dev/tty
  765. warn "$0: WARNING: input $file is not a plain file\n";
  766. }
  767. }
  768. sub check_write {
  769. my $file = shift;
  770. if (-d $file) {
  771. _die("Cannot write on $file, is a directory\n");
  772. }
  773. if (-e _) {
  774. _die("Cannot write on $file: $!\n") unless -w _;
  775. }
  776. unless (-w '.') {
  777. _die("Cannot write in this directory: $!\n");
  778. }
  779. }
  780. sub check_perl {
  781. my $file = shift;
  782. unless (-T $file) {
  783. warn "$0: Binary `$file' sure doesn't smell like perl source!\n";
  784. print "Checking file type... ";
  785. vsystem("file", $file);
  786. _die("Please try a perlier file!\n");
  787. }
  788. open(my $handle, "<", $file) or _die("Can't open $file: $!\n");
  789. local $_ = <$handle>;
  790. if (/^#!/ && !/perl/) {
  791. _die("$file is a ", /^#!\s*(\S+)/, " script, not perl\n");
  792. }
  793. }
  794. # File spawning and error collecting
  795. sub spawnit {
  796. my $command = shift;
  797. my (@error,@output,$errname,$errcode);
  798. if (opt('dryrun')) {
  799. print "$command\n";;
  800. }
  801. elsif ($Options->{spawn}) {
  802. (undef, $errname) = tempfile("pccXXXXX");
  803. {
  804. my $pid = open (S_OUT, "$command 2>$errname |")
  805. or _die("Couldn't spawn the compiler.\n");
  806. $errcode = $?;
  807. my $kid;
  808. do {
  809. $kid = waitpid($pid, 0);
  810. } while $kid > 0;
  811. @output = <S_OUT>;
  812. }
  813. open (S_ERROR, $errname) or _die("Couldn't read the error file.\n");
  814. @error = <S_ERROR>;
  815. close S_ERROR;
  816. close S_OUT;
  817. unlink $errname or _die("Can't unlink error file $errname\n");
  818. } else {
  819. @output = split /\n/, `$command`;
  820. }
  821. return (\@output, \@error, $errcode);
  822. }
  823. sub version {
  824. require B::C::Config;
  825. no warnings 'once';
  826. my $BC_VERSION = $B::C::Config::VERSION . $B::C::REVISION;
  827. return "perlcc $VERSION, B-C-${BC_VERSION} built for $Config{perlpath} $Config{archname}\n";
  828. }
  829. sub helpme {
  830. print version(),"\n";
  831. if (opt('v')) {
  832. pod2usage( -verbose => opt('v') );
  833. } else {
  834. pod2usage( -verbose => 0 );
  835. }
  836. }
  837. sub relativize {
  838. my ($args) = @_;
  839. return("./".basename($args)) if ($args =~ m"^[/\\]");
  840. return("./$args");
  841. }
  842. sub _die {
  843. my @args = ("$0: ", @_);
  844. $logfh->print(@args) if opt('log');
  845. print STDERR @args;
  846. exit(); # should die eventually. However, needed so that a 'make compile'
  847. # can compile all the way through to the end for standard dist.
  848. }
  849. sub _usage_and_die {
  850. _die(<<EOU);
  851. Usage:
  852. $0 [-o executable] [-h][-r] [-O|-B|-c|-S] [-I /foo] [-L /foo] [--log log] [source[.pl] | -e code]
  853. More options (see perldoc perlcc)
  854. -v[1-4]
  855. --stash --staticxs --shared --static
  856. --testsuite --time
  857. EOU
  858. }
  859. sub run {
  860. my (@commands) = @_;
  861. my $t0 = [gettimeofday] if opt('time');
  862. if (!opt('log')) {
  863. print interruptrun(@commands);
  864. } else {
  865. $logfh->print(interruptrun(@commands));
  866. }
  867. my $elapsed = tv_interval ( $t0 ) if opt('time');
  868. vprint -1, "r time: $elapsed" if opt('time');
  869. }
  870. sub interruptrun {
  871. my (@commands) = @_;
  872. my $command = join('', @commands);
  873. local(*FD);
  874. my $pid = open(FD, "$command |");
  875. my $text;
  876. local($SIG{HUP}, $SIG{INT}) if exists $SIG{HUP};
  877. $SIG{HUP} = $SIG{INT} = sub { kill 9, $pid; exit } if exists $SIG{HUP};
  878. my $needalarm =
  879. ($ENV{PERLCC_TIMEOUT} &&
  880. exists $SIG{ALRM} &&
  881. $Config{'osname'} ne 'MSWin32' &&
  882. $command =~ m"(^|\s)perlcc\s");
  883. eval {
  884. local($SIG{ALRM}) = sub { die "INFINITE LOOP"; } if exists $SIG{ALRM};
  885. alarm($ENV{PERLCC_TIMEOUT}) if $needalarm;
  886. $text = join('', <FD>);
  887. alarm(0) if $needalarm;
  888. };
  889. if ($@) {
  890. eval { kill 'HUP', $pid };
  891. vprint 0, "SYSTEM TIMEOUT (infinite loop?)\n";
  892. }
  893. close(FD);
  894. return($text);
  895. }
  896. sub is_win32() { $^O =~ m/^(MSWin32|msys)/ }
  897. sub is_msvc() { is_win32 && $Config{cc} =~ m/^cl/i }
  898. END {
  899. if ($cfile && !opt('S') && !opt('c') && -e $cfile) {
  900. vprint 4, "Unlinking $cfile";
  901. unlink $cfile;
  902. }
  903. if (opt('staticxs') and !opt('S')) {
  904. vprint 4, "Unlinking $cfile.lst";
  905. unlink "$cfile.lst";
  906. }
  907. }
  908. __END__
  909. =head1 NAME
  910. perlcc - generate executables from Perl programs
  911. =head1 SYNOPSIS
  912. perlcc hello.pl # Compiles into executable 'a.out'
  913. perlcc -o hello hello.pl # Compiles into executable 'hello'
  914. perlcc -O file.pl # Compiles using the optimised CC backend
  915. perlcc -O3 file.pl # Compiles with C, using -O3 optimizations
  916. perlcc -B file.pl # Compiles using the bytecode backend
  917. perlcc -B -m file.pm # Compiles a module to file.pmc
  918. perlcc -c file.pl # Creates a C file, 'file.c'
  919. perlcc -S -o hello file.pl # Keep C file
  920. perlcc -c out.c file.pl # Creates a C file, 'out.c' from 'file'
  921. perlcc --staticxs -r -o hello hello.pl # Compiles,links and runs with
  922. # XS modules static/dynaloaded
  923. perlcc -e 'print q//' # Compiles a one-liner into 'a.out'
  924. perlcc -c -e 'print q//' # Creates a C file 'a.out.c'
  925. perlcc -I /foo hello # extra headers for C
  926. perlcc -L /foo hello # extra libraries for C
  927. perlcc --Wb=-Dsp # extra perl compiler options
  928. perlcc -fno-delete-pkg # extra perl compiler options
  929. perlcc --Wc=-fno-openmp # extra C compiler options
  930. perlcc --Wl=-s # extra C linker options
  931. perlcc -uIO::Socket # force saving IO::Socket
  932. perlcc -UB # "unuse" B, compile without any B symbols
  933. perlcc -r hello # compiles 'hello' into 'a.out', runs 'a.out'
  934. perlcc -r hello a b c # compiles 'hello' into 'a.out', runs 'a.out'
  935. # with arguments 'a b c'
  936. perlcc hello -log c.log # compiles 'hello' into 'a.out', log into 'c.log'
  937. perlcc -h # help, only SYNOPSIS
  938. perlcc -v2 -h # verbose help, also DESCRIPTION and OPTIONS
  939. perlcc --version # prints internal perlcc and the B-C release version
  940. =head1 DESCRIPTION
  941. F<perlcc> creates standalone executables from Perl programs, using the
  942. code generators provided by the L<B> module. At present, you may
  943. either create executable Perl bytecode, using the C<-B> option, or
  944. generate and compile C files using the standard and 'optimised' C
  945. backends.
  946. The code generated in this way is not guaranteed to work. The whole
  947. codegen suite (C<perlcc> included) should be considered B<very>
  948. experimental. Use for production purposes is strongly discouraged.
  949. =head1 OPTIONS
  950. =over 4
  951. =item -LI<C library directories>
  952. Adds the given directories to the library search path when C code is
  953. passed to your C compiler.
  954. =item -II<C include directories>
  955. Adds the given directories to the include file search path when C code is
  956. passed to your C compiler; when using the Perl bytecode option, adds the
  957. given directories to Perl's include path.
  958. =item -o I<output file name>
  959. Specifies the file name for the final compiled executable.
  960. Without given output file name we use the base of the input file,
  961. or with C<-e> F<a.out> resp. F<a.exe> and a randomized intermediate
  962. C filename.
  963. If the input file is an absolute path on a non-windows system use
  964. the basename.
  965. =item -c I<C file name>
  966. Create C file only; do not compile and link to a standalone binary.
  967. =item -e I<perl code>
  968. Compile a one-liner, much the same as C<perl -e '...'>
  969. =item --check
  970. Pass -c flag to the backend, prints all backend warnings to STDOUT
  971. and exits before generating and compiling code. Similar to perl -c.
  972. =item -S
  973. "Keep source".
  974. Do not delete generated C code after compilation.
  975. =item -B
  976. Use the Perl bytecode code generator.
  977. =item -O
  978. Use the 'optimised' C code generator B::CC. This is more experimental than
  979. everything else put together, and the code created is not guaranteed to
  980. compile in finite time and memory, or indeed, at all.
  981. =item -OI<1-4>
  982. Pass the numeric optimisation option to the compiler backend.
  983. Shortcut for C<-Wb=-On>.
  984. This does not enforce B::CC.
  985. =item -v I<0-6>
  986. Set verbosity of output from 0 to max. 6.
  987. =item -r
  988. Run the resulting compiled script after compiling it.
  989. =item --log I<logfile>
  990. Log the output of compiling to a file rather than to stdout.
  991. =item -f<option> or --f=<option>
  992. Pass the options to the compiler backend, such as
  993. C<-fstash> or C<-fno-delete-pkg>.
  994. =item --Wb=I<options>
  995. Pass the options to the compiler backend, such as C<--Wb=-O2,-v>
  996. =item --Wc=I<options>
  997. Pass comma-seperated options to cc.
  998. =item --Wl=I<options>
  999. Pass comma-seperated options to ld.
  1000. =item -T or -t
  1001. run the backend using perl -T or -t
  1002. =item -A
  1003. Allow perl options to be passed to the executable first,
  1004. like -D...
  1005. Adds C<-DALLOW_PERL_OPTIONS> which omits C<--> from being added
  1006. to the options handler.
  1007. =item -u package
  1008. Add package(s) to compiler and force linking to it.
  1009. =item -U package
  1010. Skip package(s). Do not compile and link the package and its sole dependencies.
  1011. =item --stash
  1012. Detect external packages automatically via B::Stash
  1013. =item --static
  1014. Link to static libperl.a
  1015. =item --staticxs
  1016. Link to static XS if available.
  1017. If the XS libs are only available as shared libs link to those ("prelink").
  1018. Systems without rpath (windows, cygwin) must be extend LD_LIBRARY_PATH/PATH at run-time.
  1019. Together with -static, purely static modules and no run-time eval or
  1020. require this will gain no external dependencies.
  1021. =item --shared
  1022. Link to shared libperl
  1023. =item --sharedxs
  1024. Link shared XSUBs if the linker supports it. No DynaLoader needed.
  1025. This will still require the shared XSUB libraries to be installed
  1026. at the client, modification of @INC in the source is probably required.
  1027. (Not yet implemented)
  1028. =item -m|--sharedlib [Modulename]
  1029. Create a module, resp. a shared library.
  1030. Currently only enabled for Bytecode and CC. I<(not yet tested)>
  1031. =item --testsuite
  1032. Tries be nice to Test:: modules, like preallocating the file
  1033. handles 4 and 5, and munge the output of BEGIN.
  1034. perlcc -r --testsuite t/harness
  1035. =item --time
  1036. Benchmark the different phases B<c> I<(B::* compilation)>,
  1037. B<cc> I<(cc compile + link)>, and B<r> (runtime).
  1038. =item --no-spawn
  1039. Do not spawn subprocesses for compilation, because broken
  1040. shells might not be able to kill its children.
  1041. =back
  1042. =cut
  1043. # Local Variables:
  1044. # mode: cperl
  1045. # cperl-indent-level: 4
  1046. # fill-column: 100
  1047. # End:
  1048. # vim: expandtab shiftwidth=4:
  1049. !NO!SUBS!
  1050. close OUT or die "Can't close $file: $!";
  1051. chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
  1052. exec("$Config{'eunicefix'} $file") if $Config{'eunicefix'} ne ':';
  1053. chdir $origdir;