ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/App-Staticperl/mkbundle
(Generate patch)

Comparing cvsroot/App-Staticperl/mkbundle (file contents):
Revision 1.11 by root, Fri Dec 10 02:35:54 2010 UTC vs.
Revision 1.39 by root, Thu Aug 3 02:48:48 2023 UTC

1#!/opt/bin/perl 1#!/opt/bin/perl
2 2
3############################################################################# 3#############################################################################
4# cannot load modules till after the tracer BEGIN block 4# cannot load modules till after the tracer BEGIN block
5 5
6our $VERBOSE = 1; 6our $VERBOSE = 1;
7our $STRIP = "pod"; # none, pod or ppi 7our $STRIP = "pod"; # none, pod or ppi
8our $UNISTRIP = 1; # always on, try to strip unicore swash data 8our $UNISTRIP = 1; # always on, try to strip unicore swash data
9our $PERL = 0; 9our $PERL = 0;
10our $APP; 10our $APP;
11our $VERIFY = 0; 11our $VERIFY = 0;
12our $STATIC = 0; 12our $STATIC = 0;
13our $PACKLIST = 0;
14our $IGNORE_ENV = 0;
15our $ALLOW_DYNAMIC = 0;
16our $HAVE_DYNAMIC; # maybe useful?
17our $EXTRA_CFLAGS = "";
18our $EXTRA_LDFLAGS = "";
19our $EXTRA_LIBS = "";
13 20
14our $OPTIMISE_SIZE = 0; # optimise for raw file size instead of for compression? 21our $OPTIMISE_SIZE = 0; # optimise for raw file size instead of for compression?
15 22
16our $CACHE; 23our $CACHE;
17our $CACHEVER = 1; # do not change unless you know what you are doing 24our $CACHEVER = 2; # do not change unless you know what you are doing
18 25
19my $PREFIX = "bundle"; 26my $PREFIX = "bundle";
20my $PACKAGE = "static"; 27my $PACKAGE = "static";
21 28
22my %pm; 29my %pm;
35 42
36$|=1; 43$|=1;
37 44
38our ($TRACER_W, $TRACER_R); 45our ($TRACER_W, $TRACER_R);
39 46
40sub find_inc($) { 47sub find_incdir($) {
41 for (@INC) { 48 for (@INC) {
42 next if ref; 49 next if ref;
43 return $_ if -e "$_/$_[0]"; 50 return $_ if -e "$_/$_[0]";
44 } 51 }
45 52
46 undef 53 undef
47} 54}
48 55
56sub find_inc($) {
57 my $dir = find_incdir $_[0];
58
59 return "$dir/$_[0]"
60 if defined $dir;
61
62 undef
63}
64
49BEGIN { 65BEGIN {
50 # create a loader process to detect @INC requests before we load any modules 66 # create a loader process to detect @INC requests before we load any modules
51 my ($W_TRACER, $R_TRACER); # used by tracer 67 my ($W_TRACER, $R_TRACER); # used by tracer
52 68
53 pipe $R_TRACER, $TRACER_W or die "pipe: $!"; 69 pipe $R_TRACER, $TRACER_W or die "pipe: $!";
55 71
56 unless (fork) { 72 unless (fork) {
57 close $TRACER_R; 73 close $TRACER_R;
58 close $TRACER_W; 74 close $TRACER_W;
59 75
76 my $pkg = "pkg000000";
77
60 unshift @INC, sub { 78 unshift @INC, sub {
61 my $dir = find_inc $_[1] 79 my $dir = find_incdir $_[1]
62 or return; 80 or return;
63 81
64 syswrite $W_TRACER, "-\n$dir\n$_[1]\n"; 82 syswrite $W_TRACER, "-\n$dir\n$_[1]\n";
65 83
66 open my $fh, "<:perlio", "$dir/$_[1]" 84 open my $fh, "<:raw:perlio", "$dir/$_[1]"
67 or warn "ERROR: $dir/$_[1]: $!\n"; 85 or warn "ERROR: $dir/$_[1]: $!\n";
68 86
69 $fh 87 $fh
70 }; 88 };
71 89
72 while (<$R_TRACER>) { 90 while (<$R_TRACER>) {
73 if (/use (.*)$/) { 91 if (/use (.*)$/) {
74 my $mod = $1; 92 my $mod = $1;
93 my $eval;
94
95 if ($mod =~ /^'.*'$/ or $mod =~ /^".*"$/) {
75 eval "require $mod"; 96 $eval = "require $mod";
97 } elsif ($mod =~ y%/.%%) {
98 $eval = "require q\x00$mod\x00";
99 } else {
100 my $pkg = ++$pkg;
101 $eval = "{ package $pkg; use $mod; }";
102 }
103
104 eval $eval;
76 warn "ERROR: $@ (while loading '$mod')\n" 105 warn "ERROR: $@ (while loading '$mod')\n"
77 if $@; 106 if $@;
78 syswrite $W_TRACER, "\n";
79 } elsif (/eval (.*)$/) { 107 } elsif (/eval (.*)$/) {
80 my $eval = $1; 108 my $eval = $1;
81 eval $eval; 109 eval $eval;
82 warn "ERROR: $@ (in '$eval')\n" 110 warn "ERROR: $@ (in '$eval')\n"
83 if $@; 111 if $@;
84 } 112 }
113
114 syswrite $W_TRACER, "\n";
85 } 115 }
86 116
87 exit 0; 117 exit 0;
88 } 118 }
89} 119}
90 120
91# module loading is now safe 121# module loading is now safe
92 122
93sub trace_module { 123sub trace_parse {
94 syswrite $TRACER_W, "use $_[0]\n";
95
96 for (;;) { 124 for (;;) {
97 <$TRACER_R> =~ /^-$/ or last; 125 <$TRACER_R> =~ /^-$/ or last;
98 my $dir = <$TRACER_R>; chomp $dir; 126 my $dir = <$TRACER_R>; chomp $dir;
99 my $name = <$TRACER_R>; chomp $name; 127 my $name = <$TRACER_R>; chomp $name;
100 128
101 $pm{$name} = "$dir/$name"; 129 $pm{$name} = "$dir/$name";
130
131 print "+ found potential dependency $name\n"
132 if $VERBOSE >= 3;
102 } 133 }
134}
135
136sub trace_module {
137 print "tracing module $_[0]\n"
138 if $VERBOSE >= 2;
139
140 syswrite $TRACER_W, "use $_[0]\n";
141 trace_parse;
103} 142}
104 143
105sub trace_eval { 144sub trace_eval {
145 print "tracing eval $_[0]\n"
146 if $VERBOSE >= 2;
147
106 syswrite $TRACER_W, "eval $_[0]\n"; 148 syswrite $TRACER_W, "eval $_[0]\n";
149 trace_parse;
107} 150}
108 151
109sub trace_finish { 152sub trace_finish {
110 close $TRACER_W; 153 close $TRACER_W;
111 close $TRACER_R; 154 close $TRACER_R;
119use Digest::MD5; 162use Digest::MD5;
120 163
121sub cache($$$) { 164sub cache($$$) {
122 my ($variant, $src, $filter) = @_; 165 my ($variant, $src, $filter) = @_;
123 166
124 if (length $CACHE and 2048 <= length $src) { 167 if (length $CACHE and 2048 <= length $src and defined $variant) {
125 my $file = "$CACHE/" . Digest::MD5::md5_hex "$CACHEVER\x00$variant\x00$src"; 168 my $file = "$CACHE/" . Digest::MD5::md5_hex "$CACHEVER\x00$variant\x00$src";
126 169
127 if (open my $fh, "<:perlio", $file) { 170 if (open my $fh, "<:raw:perlio", $file) {
171 print "using cache for $file\n"
172 if $VERBOSE >= 7;
173
128 local $/; 174 local $/;
129 return <$fh>; 175 return <$fh>;
130 } 176 }
131 177
132 $src = $filter->($src); 178 $src = $filter->($src);
133 179
180 print "creating cache entry $file\n"
181 if $VERBOSE >= 8;
182
134 if (open my $fh, ">:perlio", "$file~") { 183 if (open my $fh, ">:raw:perlio", "$file~") {
135 if ((syswrite $fh, $src) == length $src) { 184 if ((syswrite $fh, $src) == length $src) {
136 close $fh; 185 close $fh;
137 rename "$file~", $file; 186 rename "$file~", $file;
138 } 187 }
139 } 188 }
146 195
147sub dump_string { 196sub dump_string {
148 my ($fh, $data) = @_; 197 my ($fh, $data) = @_;
149 198
150 if (length $data) { 199 if (length $data) {
200 if ($^O eq "MSWin32") {
201 # 16 bit system, strings can't be longer than 64k. seriously.
202 print $fh "{\n";
151 for ( 203 for (
152 my $ofs = 0; 204 my $ofs = 0;
205 length (my $substr = substr $data, $ofs, 20);
206 $ofs += 20
207 ) {
208 $substr = join ",", map ord, split //, $substr;
209 print $fh " $substr,\n";
210 }
211 print $fh " 0 }\n";
212 } else {
213 for (
214 my $ofs = 0;
153 length (my $substr = substr $data, $ofs, 80); 215 length (my $substr = substr $data, $ofs, 80);
154 $ofs += 80 216 $ofs += 80
155 ) { 217 ) {
156 $substr =~ s/([^\x20-\x21\x23-\x5b\x5d-\x7e])/sprintf "\\%03o", ord $1/ge; 218 $substr =~ s/([^\x20-\x21\x23-\x5b\x5d-\x7e])/sprintf "\\%03o", ord $1/ge;
157 $substr =~ s/\?/\\?/g; # trigraphs... 219 $substr =~ s/\?/\\?/g; # trigraphs...
158 print $fh " \"$substr\"\n"; 220 print $fh " \"$substr\"\n";
221 }
159 } 222 }
160 } else { 223 } else {
161 print $fh " \"\"\n"; 224 print $fh " \"\"\n";
162 } 225 }
163} 226}
200 my $path = "$_[0]/$_"; 263 my $path = "$_[0]/$_";
201 264
202 if (-d "$path/.") { 265 if (-d "$path/.") {
203 $scan->($path); 266 $scan->($path);
204 } else { 267 } else {
205 next unless /\.(?:pm|pl)$/;
206
207 $path = substr $path, $skip; 268 $path = substr $path, $skip;
208 push @tree, $path 269 push @tree, $path
209 unless exists $INCSKIP{$path}; 270 unless exists $INCSKIP{$path};
210 } 271 }
211 } 272 }
232} 293}
233 294
234############################################################################# 295#############################################################################
235 296
236sub cmd_boot { 297sub cmd_boot {
237 $pm{"//boot"} = $_[0]; 298 $pm{"!boot"} = $_[0];
238} 299}
239 300
240sub cmd_add { 301sub cmd_add {
241 $_[0] =~ /^(.*)(?:\s+(\S+))$/ 302 $_[0] =~ /^(.*?)(?:\s+(\S+))?$/
242 or die "$_[0]: cannot parse"; 303 or die "$_[0]: cannot parse";
243 304
244 my $file = $1; 305 my $file = $1;
245 my $as = defined $2 ? $2 : "/$1"; 306 my $as = defined $2 ? $2 : $1;
246 307
247 $pm{$as} = $file; 308 $pm{$as} = $file;
248 $pmbin{$as} = 1 if $_[1]; 309 $pmbin{$as} = 1 if $_[1];
249} 310}
250 311
264 325
265 for (get_inctrees) { 326 for (get_inctrees) {
266 my ($dir, $files) = @$_; 327 my ($dir, $files) = @$_;
267 328
268 $pm{$_} = "$dir/$_" 329 $pm{$_} = "$dir/$_"
269 for grep /$pattern/, @$files; 330 for grep /$pattern/ && /\.(pl|pm)$/, @$files;
270 } 331 }
271} 332}
333
334sub parse_argv;
272 335
273sub cmd_file { 336sub cmd_file {
274 open my $fh, "<", $_[0] 337 open my $fh, "<", $_[0]
275 or die "$_[0]: $!\n"; 338 or die "$_[0]: $!\n";
276 339
340 local @ARGV;
341
277 while (<$fh>) { 342 while (<$fh>) {
278 chomp; 343 chomp;
344 next unless /\S/;
345 next if /^\s*#/;
346
347 s/^\s*-*/--/;
279 my ($cmd, $args) = split / /, $_, 2; 348 my ($cmd, $args) = split / /, $_, 2;
280 $cmd =~ s/^-+//;
281 349
282 if ($cmd eq "strip") { 350 push @ARGV, $cmd;
283 $STRIP = $args; 351 push @ARGV, $args if defined $args;
284 } elsif ($cmd eq "perl") {
285 $PERL = 1;
286 } elsif ($cmd eq "app") {
287 $APP = $args;
288 } elsif ($cmd eq "eval") {
289 trace_eval $_;
290 } elsif ($cmd eq "use") {
291 trace_module $_
292 for split / /, $args;
293 } elsif ($cmd eq "staticlib") {
294 cmd_staticlib $args;
295 } elsif ($cmd eq "boot") {
296 cmd_boot $args;
297 } elsif ($cmd eq "static") {
298 $STATIC = 1;
299 } elsif ($cmd eq "add") {
300 cmd_add $args, 0;
301 } elsif ($cmd eq "addbin") {
302 cmd_add $args, 1;
303 } elsif ($cmd eq "incglob") {
304 cmd_incglob $args;
305 } elsif ($cmd eq "include") {
306 cmd_include $args, 1;
307 } elsif ($cmd eq "exclude") {
308 cmd_include $args, 0;
309 } elsif (/^\s*#/) {
310 # comment
311 } elsif (/\S/) {
312 die "$_: unsupported directive\n";
313 }
314 } 352 }
353
354 parse_argv;
315} 355}
316 356
317use Getopt::Long; 357use Getopt::Long;
318 358
359sub parse_argv {
360 GetOptions
361 "perl" => \$PERL,
362 "app=s" => \$APP,
363
364 "verbose|v" => sub { ++$VERBOSE },
365 "quiet|q" => sub { --$VERBOSE },
366
367 "strip=s" => \$STRIP,
368 "cache=s" => \$CACHE, # internal option
369 "eval|e=s" => sub { trace_eval $_[1] },
370 "use|M=s" => sub { trace_module $_[1] },
371 "boot=s" => sub { cmd_boot $_[1] },
372 "add=s" => sub { cmd_add $_[1], 0 },
373 "addbin=s" => sub { cmd_add $_[1], 1 },
374 "incglob=s" => sub { cmd_incglob $_[1] },
375 "include|i=s" => sub { cmd_include $_[1], 1 },
376 "exclude|x=s" => sub { cmd_include $_[1], 0 },
377 "usepacklists!" => \$PACKLIST,
378
379 "static!" => \$STATIC,
380 "staticlib=s" => sub { cmd_staticlib $_[1] },
381 "allow-dynamic!" => \$ALLOW_DYNAMIC,
382 "ignore-env" => \$IGNORE_ENV,
383
384 "extra-cflags=s" => \$EXTRA_CFLAGS,
385 "extra-ldflags=s" => \$EXTRA_LDFLAGS,
386 "extra-libs=s" => \$EXTRA_LIBS,
387
388 "<>" => sub { cmd_file $_[0] },
389 or exit 1;
390}
391
319Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case"); 392Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case");
320 393
321GetOptions 394parse_argv;
322 "strip=s" => \$STRIP,
323 "cache=s" => \$CACHE, # internal option
324 "verbose|v" => sub { ++$VERBOSE },
325 "quiet|q" => sub { --$VERBOSE },
326 "perl" => \$PERL,
327 "app=s" => \$APP,
328 "eval|e=s" => sub { trace_eval $_[1] },
329 "use|M=s" => sub { trace_module $_[1] },
330 "boot=s" => sub { cmd_boot $_[1] },
331 "add=s" => sub { cmd_add $_[1], 0 },
332 "addbin=s" => sub { cmd_add $_[1], 1 },
333 "incglob=s" => sub { cmd_incglob $_[1] },
334 "include|i=s" => sub { cmd_include $_[1], 1 },
335 "exclude|x=s" => sub { cmd_include $_[1], 0 },
336 "static" => sub { $STATIC = 1 },
337 "staticlib=s" => sub { cmd_staticlib $_[1] },
338 "<>" => sub { cmd_file $_[0] },
339 or exit 1;
340 395
341die "cannot specify both --app and --perl\n" 396die "cannot specify both --app and --perl\n"
342 if $PERL and defined $APP; 397 if $PERL and defined $APP;
343 398
344# required for @INC loading, unfortunately 399# required for @INC loading, unfortunately
345trace_module "PerlIO::scalar"; 400trace_module "PerlIO::scalar";
346 401
347############################################################################# 402#############################################################################
348# include/exclude apply 403# apply include/exclude
349 404
350{ 405{
351 my %pmi; 406 my %pmi;
352 407
353 for (@incext) { 408 for (@incext) {
356 my @match = grep /$glob/, keys %pm; 411 my @match = grep /$glob/, keys %pm;
357 412
358 if ($inc) { 413 if ($inc) {
359 # include 414 # include
360 @pmi{@match} = delete @pm{@match}; 415 @pmi{@match} = delete @pm{@match};
416
417 print "applying include $glob - protected ", (scalar @match), " files.\n"
418 if $VERBOSE >= 5;
361 } else { 419 } else {
362 # exclude 420 # exclude
363 delete @pm{@match}; 421 delete @pm{@match};
422
423 print "applying exclude $glob - removed ", (scalar @match), " files.\n"
424 if $VERBOSE >= 5;
364 } 425 }
365 } 426 }
366 427
367 my @pmi = keys %pmi; 428 my @pmi = keys %pmi;
368 @pm{@pmi} = delete @pmi{@pmi}; 429 @pm{@pmi} = delete @pmi{@pmi};
369} 430}
370 431
371############################################################################# 432#############################################################################
372# scan for AutoLoader and static archives 433# scan for AutoLoader, static archives and other dependencies
373 434
374sub scan_al { 435sub scan_al {
375 my ($auto, $autodir) = @_; 436 my ($auto, $autodir) = @_;
376 437
377 my $ix = "$autodir/autosplit.ix"; 438 my $ix = "$autodir/autosplit.ix";
439
440 print "processing autoload index for '$auto'\n"
441 if $VERBOSE >= 6;
378 442
379 $pm{"$auto/autosplit.ix"} = $ix; 443 $pm{"$auto/autosplit.ix"} = $ix;
380 444
381 open my $fh, "<:perlio", $ix 445 open my $fh, "<:perlio", $ix
382 or die "$ix: $!"; 446 or die "$ix: $!";
388 my $al = "auto/$package/$1.al"; 452 my $al = "auto/$package/$1.al";
389 my $inc = find_inc $al; 453 my $inc = find_inc $al;
390 454
391 defined $inc or die "$al: autoload file not found, but should be there.\n"; 455 defined $inc or die "$al: autoload file not found, but should be there.\n";
392 456
393 $pm{$al} = "$inc/$al"; 457 $pm{$al} = $inc;
458 print "found autoload function '$al'\n"
459 if $VERBOSE >= 6;
394 460
395 } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) { 461 } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) {
396 ($package = $1) =~ s/::/\//g; 462 ($package = $1) =~ s/::/\//g;
397 } elsif (/^\s*(?:#|1?\s*;?\s*$)/) { 463 } elsif (/^\s*(?:#|1?\s*;?\s*$)/) {
398 # nop 464 # nop
399 } else { 465 } else {
400 warn "$ix: unparsable line, please report: $_"; 466 warn "WARNING: $ix: unparsable line, please report: $_";
401 } 467 }
402 } 468 }
403} 469}
404 470
405for my $pm (keys %pm) { 471for my $pm (keys %pm) {
406 if ($pm =~ /^(.*)\.pm$/) { 472 if ($pm =~ /^(.*)\.pm$/) {
407 my $auto = "auto/$1"; 473 my $auto = "auto/$1";
408 my $autodir = find_inc $auto; 474 my $autodir = find_inc $auto;
409 475
410 if (defined $autodir && -d "$autodir/$auto") { 476 if (defined $autodir && -d $autodir) {
411 $autodir = "$autodir/$auto";
412
413 # AutoLoader 477 # AutoLoader
414 scan_al $auto, $autodir 478 scan_al $auto, $autodir
415 if -f "$autodir/autosplit.ix"; 479 if -f "$autodir/autosplit.ix";
416 480
417 # extralibs.ld 481 # extralibs.ld
418 if (open my $fh, "<:perlio", "$autodir/extralibs.ld") { 482 if (open my $fh, "<:perlio", "$autodir/extralibs.ld") {
483 print "found extralibs for $pm\n"
484 if $VERBOSE >= 6;
485
419 local $/; 486 local $/;
420 $extralibs .= " " . <$fh>; 487 $extralibs .= " " . <$fh>;
421 } 488 }
422 489
423 $pm =~ /([^\/]+).pm$/ or die "$pm: unable to match last component"; 490 $pm =~ /([^\/]+).pm$/ or die "$pm: unable to match last component";
424 491
425 my $base = $1; 492 my $base = $1;
426 493
427 # static ext 494 # static ext
428 if (-f "$autodir/$base$Config{_a}") { 495 if (-f "$autodir/$base$Config{_a}") {
496 print "found static archive for $pm\n"
497 if $VERBOSE >= 3;
498
429 push @libs, "$autodir/$base$Config{_a}"; 499 push @libs, "$autodir/$base$Config{_a}";
430 push @static_ext, $pm; 500 push @static_ext, $pm;
431 } 501 }
432 502
433 # dynamic object 503 # dynamic object
434 die "ERROR: found shared object - can't link statically ($_)\n"
435 if -f "$autodir/$base.$Config{dlext}"; 504 if (-f "$autodir/$base.$Config{dlext}") {
505 if ($ALLOW_DYNAMIC) {
506 my $as = "!$auto/$base.$Config{dlext}";
507 $pm{$as} = "$autodir/$base.$Config{dlext}";
508 $pmbin{$as} = 1;
509
510 $HAVE_DYNAMIC = 1;
511
512 print "+ added dynamic object $as\n"
513 if $VERBOSE >= 3;
514 } else {
515 die "ERROR: found shared object '$autodir/$base.$Config{dlext}' but --allow-dynamic not given, aborting.\n"
516 }
517 }
518
519 if ($PACKLIST && open my $fh, "<:perlio", "$autodir/.packlist") {
520 print "found .packlist for $pm\n"
521 if $VERBOSE >= 3;
522
523 while (<$fh>) {
524 chomp;
525 s/ .*$//; # newer-style .packlists might contain key=value pairs
526
527 # only include certain files (.al, .ix, .pm, .pl)
528 if (/\.(pm|pl|al|ix)$/) {
529 for my $inc (@INC) {
530 # in addition, we only add files that are below some @INC path
531 $inc =~ s/\/*$/\//;
532
533 if ($inc eq substr $_, 0, length $inc) {
534 my $base = substr $_, length $inc;
535 $pm{$base} = $_;
536
537 print "+ added .packlist dependency $base\n"
538 if $VERBOSE >= 3;
539 }
540
541 last;
542 }
543 }
544 }
545 }
436 } 546 }
437 } 547 }
438} 548}
439 549
440############################################################################# 550#############################################################################
551
552print "processing bundle files (try more -v power if you get bored waiting here)...\n"
553 if $VERBOSE >= 1;
441 554
442my $data; 555my $data;
443my @index; 556my @index;
444my @order = sort { 557my @order = sort {
445 length $a <=> length $b 558 length $a <=> length $b
457 or die "ERROR: $pm: path too long (only 128 octets supported)\n"; 570 or die "ERROR: $pm: path too long (only 128 octets supported)\n";
458 571
459 my $src = ref $path 572 my $src = ref $path
460 ? $$path 573 ? $$path
461 : do { 574 : do {
462 open my $pm, "<", $path 575 open my $pm, "<:raw:perlio", $path
463 or die "$path: $!"; 576 or die "$path: $!";
464 577
465 local $/; 578 local $/;
466 579
467 <$pm> 580 <$pm>
470 my $size = length $src; 583 my $size = length $src;
471 584
472 unless ($pmbin{$pm}) { # only do this unless the file is binary 585 unless ($pmbin{$pm}) { # only do this unless the file is binary
473 if ($pm =~ /^auto\/POSIX\/[^\/]+\.al$/) { 586 if ($pm =~ /^auto\/POSIX\/[^\/]+\.al$/) {
474 if ($src =~ /^ unimpl \"/m) { 587 if ($src =~ /^ unimpl \"/m) {
475 warn "$pm: skipping (not implemented anyways).\n" 588 print "$pm: skipping (raises runtime error only).\n"
476 if $VERBOSE >= 2; 589 if $VERBOSE >= 3;
477 next; 590 next;
478 } 591 }
479 } 592 }
480 593
481 $src = cache "$UNISTRIP,$OPTIMISE_SIZE,$STRIP", $src, sub { 594 $src = cache +($STRIP eq "ppi" ? "$UNISTRIP,$OPTIMISE_SIZE" : undef), $src, sub {
482 if ($UNISTRIP && $pm =~ /^unicore\/.*\.pl$/) { 595 if ($UNISTRIP && $pm =~ /^unicore\/.*\.pl$/) {
596 print "applying unicore stripping $pm\n"
597 if $VERBOSE >= 6;
598
483 # special stripping for unicore swashes and properties 599 # special stripping for unicore swashes and properties
484 # much more could be done by going binary 600 # much more could be done by going binary
485 $src =~ s{ 601 $src =~ s{
486 (^return\ <<'END';\n) (.*?\n) (END(?:\n|\Z)) 602 (^return\ <<'END';\n) (.*?\n) (END(?:\n|\Z))
487 }{ 603 }{
539 my $next = $ws->next_token; 655 my $next = $ws->next_token;
540 656
541 if (!$prev || !$next) { 657 if (!$prev || !$next) {
542 $ws->delete; 658 $ws->delete;
543 } else { 659 } else {
660 while ($next->isa (PPI::Token::Whitespace::)) {
661 $next->delete;
662 $next = $ws->next_token;
663 }
664
544 if ( 665 if (
545 $next->isa (PPI::Token::Operator::) && $next->{content} =~ /^(?:,|=|!|!=|==|=>)$/ # no ., because of digits. == float 666 $next->isa (PPI::Token::Operator::) && $next->{content} =~ /^(?:,|=|!|!=|==|=>)$/ # no ., because of digits. == float
546 or $prev->isa (PPI::Token::Operator::) && $prev->{content} =~ /^(?:,|=|\.|!|!=|==|=>)$/ 667 or $prev->isa (PPI::Token::Operator::) && $prev->{content} =~ /^(?:,|=|\.|!|!=|==|=>)$/
547 or $prev->isa (PPI::Token::Structure::) 668 or $prev->isa (PPI::Token::Structure::)
548 or ($OPTIMISE_SIZE && 669 or ($OPTIMISE_SIZE &&
551 || $next->isa (PPI::Structure::Block::) 672 || $next->isa (PPI::Structure::Block::)
552 || $next->isa (PPI::Structure::List::) 673 || $next->isa (PPI::Structure::List::)
553 || $next->isa (PPI::Structure::Condition::))) 674 || $next->isa (PPI::Structure::Condition::)))
554 ) 675 )
555 ) { 676 ) {
677 # perl has some idiotic warnigns about nonexisting operators
678 if ($prev->isa (PPI::Token::Operator::) && $prev->{content} eq "="
679 && $next->isa (PPI::Token::Operator::) && $next->{content} =~ /[+\-]/
680 ) {
681 # avoid "Reverse %s operator" diagnostic
682 } else {
556 $ws->delete; 683 $ws->delete;
557 } elsif ($prev->isa (PPI::Token::Whitespace::)) {
558 $ws->{content} = ' ';
559 $prev->delete; 684 }
560 } else { 685 } else {
561 $ws->{content} = ' '; 686 $ws->{content} = ' ';
562 } 687 }
563 } 688 }
564 } 689 }
600 725
601 $src = $ppi->serialize; 726 $src = $ppi->serialize;
602 } else { 727 } else {
603 warn "WARNING: $pm{$pm}: PPI failed to parse this file\n"; 728 warn "WARNING: $pm{$pm}: PPI failed to parse this file\n";
604 } 729 }
605 } elsif ($STRIP =~ /pod/i && $pm ne "Opcode.pm") { # opcode parses it's own pod 730 } elsif ($STRIP =~ /pod/i && $pm ne "Opcode.pm") { # opcode parses its own pod
606 require Pod::Strip; 731 require Pod::Strip;
607 732
608 my $stripper = Pod::Strip->new; 733 my $stripper = Pod::Strip->new;
609 734
610 my $out; 735 my $out;
630# open my $fh, ">x" or die; print $fh $src;#d# 755# open my $fh, ">x" or die; print $fh $src;#d#
631# exit 1; 756# exit 1;
632# } 757# }
633 } 758 }
634 759
635 print "adding $pm{$pm} (original size $size, stored size ", length $src, ")\n" 760 print "adding $pm (original size $size, stored size ", length $src, ")\n"
636 if $VERBOSE >= 2; 761 if $VERBOSE >= 2;
637 762
638 push @index, ((length $pm) << 25) | length $data; 763 push @index, ((length $pm) << 25) | length $data;
639 $data .= $pm . $src; 764 $data .= $pm . $src;
640} 765}
641 766
642length $data < 2**25 767length $data < 2**25
643 or die "bundle too large (only 32MB supported)\n"; 768 or die "ERROR: bundle too large (only 32MB supported)\n";
644 769
645my $varpfx = "bundle_" . substr +(Digest::MD5::md5_hex $data), 0, 16; 770my $varpfx = "bundle";
646 771
647############################################################################# 772#############################################################################
648# output 773# output
649 774
650print "generating $PREFIX.h... "; 775print "generating $PREFIX.h... "
776 if $VERBOSE >= 1;
651 777
652{ 778{
653 open my $fh, ">", "$PREFIX.h" 779 open my $fh, ">", "$PREFIX.h"
654 or die "$PREFIX.h: $!\n"; 780 or die "$PREFIX.h: $!\n";
655 781
656 print $fh <<EOF; 782 print $fh <<EOF;
657/* do not edit, automatically created by mkstaticbundle */ 783/* do not edit, automatically created by staticperl */
658 784
659#include <EXTERN.h> 785#include <EXTERN.h>
660#include <perl.h> 786#include <perl.h>
661#include <XSUB.h> 787#include <XSUB.h>
662 788
663/* public API */ 789/* public API */
664EXTERN_C PerlInterpreter *staticperl; 790EXTERN_C PerlInterpreter *staticperl;
665EXTERN_C void staticperl_xs_init (pTHX); 791EXTERN_C void staticperl_xs_init (pTHX);
666EXTERN_C void staticperl_init (void); 792EXTERN_C void staticperl_init (XSINIT_t xs_init); /* argument can be 0 */
667EXTERN_C void staticperl_cleanup (void); 793EXTERN_C void staticperl_cleanup (void);
668 794
669EOF 795EOF
670} 796}
671 797
672print "\n"; 798print "\n"
799 if $VERBOSE >= 1;
673 800
674############################################################################# 801#############################################################################
675# output 802# output
676 803
677print "generating $PREFIX.c... "; 804print "generating $PREFIX.c... "
805 if $VERBOSE >= 1;
678 806
679open my $fh, ">", "$PREFIX.c" 807open my $fh, ">", "$PREFIX.c"
680 or die "$PREFIX.c: $!\n"; 808 or die "$PREFIX.c: $!\n";
681 809
682print $fh <<EOF; 810print $fh <<EOF;
683/* do not edit, automatically created by mkstaticbundle */ 811/* do not edit, automatically created by staticperl */
684 812
685#include "bundle.h" 813#include "bundle.h"
686 814
687/* public API */ 815/* public API */
688PerlInterpreter *staticperl; 816PerlInterpreter *staticperl;
712printf $fh "0x%08x\n};\n", (length $data); 840printf $fh "0x%08x\n};\n", (length $data);
713 841
714print $fh "static const char $varpfx\_data [] =\n"; 842print $fh "static const char $varpfx\_data [] =\n";
715dump_string $fh, $data; 843dump_string $fh, $data;
716 844
717print $fh ";\n\n";; 845print $fh ";\n\n";
718 846
719############################################################################# 847#############################################################################
720# bootstrap 848# bootstrap
721 849
722# boot file for staticperl 850# boot file for staticperl
723# this file will be eval'ed at initialisation time 851# this file will be eval'ed at initialisation time
724 852
853# lines marked with "^D" are only used when $HAVE_DYNAMIC
725my $bootstrap = ' 854my $bootstrap = '
726BEGIN { 855BEGIN {
727 package ' . $PACKAGE . '; 856 package ' . $PACKAGE . ';
728 857
729 PerlIO::scalar->bootstrap; 858 # the path prefix to use when putting files into %INC
859 our $inc_prefix;
730 860
731 @INC = sub { 861 # the @INC hook to use when we have PerlIO::scalar available
862 my $perlio_inc = sub {
732 my $data = find "$_[1]" 863 my $data = find "$_[1]"
733 or return; 864 or return;
734 865
735 $INC{$_[1]} = $_[1]; 866 $INC{$_[1]} = "$inc_prefix$_[1]";
736 867
737 open my $fh, "<", \$data; 868 open my $fh, "<", \$data;
738 $fh 869 $fh
739 }; 870 };
871
872D if (defined &PerlIO::scalar::bootstrap) {
873 # PerlIO::scalar statically compiled in
874 PerlIO::scalar->bootstrap;
875 @INC = $perlio_inc;
876D } else {
877D # PerlIO::scalar not available, use slower method
878D @INC = sub {
879D # always check if PerlIO::scalar might now be available
880D if (defined &PerlIO::scalar::bootstrap) {
881D # switch to the faster perlio_inc hook
882D @INC = map { $_ == $_[0] ? $perlio_inc : $_ } @INC;
883D goto &$perlio_inc;
884D }
885D
886D my $data = find "$_[1]"
887D or return;
888D
889D $INC{$_[1]} = "$inc_prefix$_[1]";
890D
891D sub {
892D $data =~ /\G([^\n]*\n?)/g
893D or return;
894D
895D $_ = $1;
896D 1
897D }
898D };
899D }
740} 900}
741'; 901';
742 902
743$bootstrap .= "require '//boot';" 903$bootstrap .= "require '!boot';"
744 if exists $pm{"//boot"}; 904 if exists $pm{"!boot"};
745 905
906if ($HAVE_DYNAMIC) {
907 $bootstrap =~ s/^D/ /mg;
908} else {
909 $bootstrap =~ s/^D.*$//mg;
910}
911
912$bootstrap =~ s/#.*$//mg;
746$bootstrap =~ s/\s+/ /g; 913$bootstrap =~ s/\s+/ /g;
747$bootstrap =~ s/(\W) /$1/g; 914$bootstrap =~ s/(\W) /$1/g;
748$bootstrap =~ s/ (\W)/$1/g; 915$bootstrap =~ s/ (\W)/$1/g;
749 916
750print $fh "const char bootstrap [] = "; 917print $fh "const char bootstrap [] = ";
796 } 963 }
797 964
798 XSRETURN (0); 965 XSRETURN (0);
799 966
800 found: 967 found:
801 ST (0) = res; 968 ST (0) = sv_2mortal (res);
802 sv_2mortal (ST (0));
803 } 969 }
804 970
805 XSRETURN (1); 971 XSRETURN (1);
806} 972}
807 973
820 986
821 for (i = 0; i < $varpfx\_count; ++i) 987 for (i = 0; i < $varpfx\_count; ++i)
822 { 988 {
823 U32 idx = $varpfx\_index [i]; 989 U32 idx = $varpfx\_index [i];
824 990
825 PUSHs (newSVpvn ($varpfx\_data + (idx & 0x1FFFFFFU), idx >> 25)); 991 PUSHs (sv_2mortal (newSVpvn ($varpfx\_data + (idx & 0x1FFFFFFU), idx >> 25)));
826 } 992 }
827 } 993 }
828 994
829 XSRETURN ($varpfx\_count); 995 XSRETURN ($varpfx\_count);
830} 996}
997
998#ifdef STATICPERL_BUNDLE_INCLUDE
999#include STATICPERL_BUNDLE_INCLUDE
1000#endif
831 1001
832EOF 1002EOF
833 1003
834############################################################################# 1004#############################################################################
835# xs_init 1005# xs_init
838void 1008void
839staticperl_xs_init (pTHX) 1009staticperl_xs_init (pTHX)
840{ 1010{
841EOF 1011EOF
842 1012
843@static_ext = ("DynaLoader", sort @static_ext); 1013@static_ext = sort @static_ext;
844 1014
845# prototypes 1015# prototypes
846for (@static_ext) { 1016for (@static_ext) {
847 s/\.pm$//; 1017 s/\.pm$//;
848 (my $cname = $_) =~ s/\//__/g; 1018 (my $cname = $_) =~ s/\//__/g;
853 char *file = __FILE__; 1023 char *file = __FILE__;
854 dXSUB_SYS; 1024 dXSUB_SYS;
855 1025
856 newXSproto ("$PACKAGE\::find", find, file, "\$"); 1026 newXSproto ("$PACKAGE\::find", find, file, "\$");
857 newXSproto ("$PACKAGE\::list", list, file, ""); 1027 newXSproto ("$PACKAGE\::list", list, file, "");
1028
1029 #ifdef STATICPERL_BUNDLE_XS_INIT
1030 STATICPERL_BUNDLE_XS_INIT;
1031 #endif
858EOF 1032EOF
859 1033
860# calls 1034# calls
861for (@static_ext) { 1035for (@static_ext) {
862 s/\.pm$//; 1036 s/\.pm$//;
863 1037
864 (my $cname = $_) =~ s/\//__/g; 1038 (my $cname = $_) =~ s/\//__/g;
865 (my $pname = $_) =~ s/\//::/g; 1039 (my $pname = $_) =~ s/\//::/g;
866 1040
867 my $bootstrap = $pname eq "DynaLoader" ? "boot" : "bootstrap"; 1041 my $bootstrap = $pname eq "DynaLoader" ? "boot_DynaLoader" : "bootstrap";
868 1042
869 print $fh " newXS (\"$pname\::$bootstrap\", boot_$cname, file);\n"; 1043 print $fh " newXS (\"$pname\::$bootstrap\", boot_$cname, file);\n";
870} 1044}
871 1045
872print $fh <<EOF; 1046print $fh <<EOF;
1047 Safefree (PL_origfilename);
1048 PL_origfilename = savepv (PL_origargv [0]);
1049 sv_setpv (GvSV (gv_fetchpvs ("0", GV_ADD|GV_NOTQUAL, SVt_PV)), PL_origfilename);
1050
1051 #ifdef _WIN32
1052 /* windows perls usually trail behind unix perls 8-10 years in exporting symbols */
1053
1054 if (!PL_preambleav)
1055 PL_preambleav = newAV ();
1056
1057 av_unshift (PL_preambleav, 1);
1058 av_store (PL_preambleav, 0, newSVpv (bootstrap, sizeof (bootstrap) - 1));
1059 #else
873 Perl_av_create_and_unshift_one (&PL_preambleav, newSVpv (bootstrap, sizeof (bootstrap) - 1)); 1060 Perl_av_create_and_unshift_one (&PL_preambleav, newSVpv (bootstrap, sizeof (bootstrap) - 1));
1061 #endif
1062
1063 if (PL_oldname)
1064 ((XSINIT_t)PL_oldname)(aTHX);
874} 1065}
875EOF 1066EOF
876 1067
877############################################################################# 1068#############################################################################
878# optional perl_init/perl_destroy 1069# optional perl_init/perl_destroy
879 1070
1071if ($IGNORE_ENV) {
1072 $IGNORE_ENV = <<EOF;
1073 unsetenv ("PERL_UNICODE");
1074 unsetenv ("PERL_HASH_SEED_DEBUG");
1075 unsetenv ("PERL_DESTRUCT_LEVEL");
1076 unsetenv ("PERL_SIGNALS");
1077 unsetenv ("PERL_DEBUG_MSTATS");
1078 unsetenv ("PERL5OPT");
1079 unsetenv ("PERLIO_DEBUG");
1080 unsetenv ("PERLIO");
1081 unsetenv ("PERL_HASH_SEED");
1082EOF
1083} else {
1084 $IGNORE_ENV = "";
1085}
1086
880if ($APP) { 1087if ($APP) {
1088 print $fh <<EOF;
1089
1090int
1091main (int argc, char *argv [])
1092{
1093 extern char **environ;
1094 int i, exitstatus;
1095 char **args = malloc ((argc + 3) * sizeof (const char *));
1096
1097 args [0] = argv [0];
1098 args [1] = "-e";
1099 args [2] = "0";
1100 args [3] = "--";
1101
1102 for (i = 1; i < argc; ++i)
1103 args [i + 3] = argv [i];
1104
1105$IGNORE_ENV
1106 PERL_SYS_INIT3 (&argc, &argv, &environ);
1107 staticperl = perl_alloc ();
1108 perl_construct (staticperl);
1109
1110 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1111
1112 exitstatus = perl_parse (staticperl, staticperl_xs_init, argc + 3, args, environ);
1113 if (!exitstatus)
1114 perl_run (staticperl);
1115
1116 exitstatus = perl_destruct (staticperl);
1117 perl_free (staticperl);
1118 PERL_SYS_TERM ();
1119 /*free (args); no point doing it this late */
1120
1121 return exitstatus;
1122}
1123EOF
1124} elsif ($PERL) {
881 print $fh <<EOF; 1125 print $fh <<EOF;
882 1126
883int 1127int
884main (int argc, char *argv []) 1128main (int argc, char *argv [])
885{ 1129{
886 extern char **environ; 1130 extern char **environ;
887 int exitstatus; 1131 int exitstatus;
888 1132
1133$IGNORE_ENV
1134 PERL_SYS_INIT3 (&argc, &argv, &environ);
1135 staticperl = perl_alloc ();
1136 perl_construct (staticperl);
1137
1138 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1139
1140 exitstatus = perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
1141 if (!exitstatus)
1142 perl_run (staticperl);
1143
1144 exitstatus = perl_destruct (staticperl);
1145 perl_free (staticperl);
1146 PERL_SYS_TERM ();
1147
1148 return exitstatus;
1149}
1150EOF
1151} else {
1152 print $fh <<EOF;
1153
1154EXTERN_C void
1155staticperl_init (XSINIT_t xs_init)
1156{
889 static char *args[] = { 1157 static char *args[] = {
890 "staticperl", 1158 "staticperl",
891 "-e", 1159 "-e",
892 "0" 1160 "0"
893 }; 1161 };
894 1162
895 PERL_SYS_INIT3 (&argc, &argv, &environ);
896 staticperl = perl_alloc ();
897 perl_construct (staticperl);
898
899 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
900
901 exitstatus = perl_parse (staticperl, staticperl_xs_init, sizeof (args) / sizeof (*args), args, environ);
902 if (!exitstatus)
903 perl_run (staticperl);
904
905 exitstatus = perl_destruct (staticperl);
906 perl_free (staticperl);
907 PERL_SYS_TERM ();
908
909 return exitstatus;
910}
911EOF
912} elsif ($PERL) {
913 print $fh <<EOF;
914
915int
916main (int argc, char *argv [])
917{
918 extern char **environ;
919 int exitstatus;
920
921 PERL_SYS_INIT3 (&argc, &argv, &environ);
922 staticperl = perl_alloc ();
923 perl_construct (staticperl);
924
925 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
926
927 exitstatus = perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
928 if (!exitstatus)
929 perl_run (staticperl);
930
931 exitstatus = perl_destruct (staticperl);
932 perl_free (staticperl);
933 PERL_SYS_TERM ();
934
935 return exitstatus;
936}
937EOF
938} else {
939 print $fh <<EOF;
940
941EXTERN_C void
942staticperl_init (void)
943{
944 extern char **environ; 1163 extern char **environ;
945 int argc = sizeof (args) / sizeof (args [0]); 1164 int argc = sizeof (args) / sizeof (args [0]);
946 char **argv = args; 1165 char **argv = args;
947 1166
948 static char *args[] = { 1167$IGNORE_ENV
949 "staticperl",
950 "-e",
951 "0"
952 };
953
954 PERL_SYS_INIT3 (&argc, &argv, &environ); 1168 PERL_SYS_INIT3 (&argc, &argv, &environ);
955 staticperl = perl_alloc (); 1169 staticperl = perl_alloc ();
956 perl_construct (staticperl); 1170 perl_construct (staticperl);
957 PL_origalen = 1; 1171 PL_origalen = 1;
958 PL_exit_flags |= PERL_EXIT_DESTRUCT_END; 1172 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1173 PL_oldname = (char *)xs_init;
959 perl_parse (staticperl, staticperl_xs_init, argc, argv, environ); 1174 perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
960 1175
961 perl_run (staticperl); 1176 perl_run (staticperl);
962} 1177}
963 1178
970 PERL_SYS_TERM (); 1185 PERL_SYS_TERM ();
971} 1186}
972EOF 1187EOF
973} 1188}
974 1189
1190close $fh;
1191
975print -s "$PREFIX.c", " octets (", (length $data) , " data octets).\n\n"; 1192print -s "$PREFIX.c", " octets (", (length $data) , " data octets).\n\n"
1193 if $VERBOSE >= 1;
976 1194
977############################################################################# 1195#############################################################################
978# libs, cflags 1196# libs, cflags
979 1197
1198my $ccopts;
1199
980{ 1200{
981 print "generating $PREFIX.ccopts... "; 1201 print "generating $PREFIX.ccopts... "
1202 if $VERBOSE >= 1;
982 1203
983 my $str = "$Config{ccflags} $Config{optimize} $Config{cppflags} -I$Config{archlibexp}/CORE"; 1204 $ccopts = "$Config{ccflags} $Config{optimize} $Config{cppflags} -I$Config{archlibexp}/CORE $EXTRA_CFLAGS";
984 $str =~ s/([\(\)])/\\$1/g; 1205 $ccopts =~ s/([\(\)])/\\$1/g;
985
986 print "$str\n\n";
987 1206
988 open my $fh, ">$PREFIX.ccopts" 1207 open my $fh, ">$PREFIX.ccopts"
989 or die "$PREFIX.ccopts: $!"; 1208 or die "$PREFIX.ccopts: $!";
990 print $fh $str; 1209 print $fh $ccopts;
1210
1211 print "$ccopts\n\n"
1212 if $VERBOSE >= 1;
991} 1213}
1214
1215my $ldopts;
992 1216
993{ 1217{
994 print "generating $PREFIX.ldopts... "; 1218 print "generating $PREFIX.ldopts... ";
995 1219
996 my $str = $STATIC ? "-static " : ""; 1220 $ldopts = $STATIC ? "-static " : "";
997 1221
998 $str .= "$Config{ccdlflags} $Config{ldflags} @libs $Config{archlibexp}/CORE/$Config{libperl} $Config{perllibs}"; 1222 $ldopts .= "$Config{ccdlflags} $Config{ldflags} $EXTRA_LDFLAGS @libs $Config{archlibexp}/CORE/$Config{libperl} $Config{perllibs} $EXTRA_LIBS";
999 1223
1000 my %seen; 1224 my %seen;
1001 $str .= " $_" for grep !$seen{$_}++, ($extralibs =~ /(\S+)/g); 1225 $ldopts .= " $_" for reverse grep !$seen{$_}++, reverse +($extralibs =~ /(\S+)/g);
1002 1226
1003 for (@staticlibs) { 1227 for (@staticlibs) {
1004 $str =~ s/(^|\s) (-l\Q$_\E) ($|\s)/$1-Wl,-Bstatic $2 -Wl,-Bdynamic$3/gx; 1228 $ldopts =~ s/(^|\s) (-l\Q$_\E) ($|\s)/$1-Wl,-Bstatic $2 -Wl,-Bdynamic$3/gx;
1005 } 1229 }
1006 1230
1007 $str =~ s/([\(\)])/\\$1/g; 1231 $ldopts =~ s/([\(\)])/\\$1/g;
1008
1009 print "$str\n\n";
1010 1232
1011 open my $fh, ">$PREFIX.ldopts" 1233 open my $fh, ">$PREFIX.ldopts"
1012 or die "$PREFIX.ldopts: $!"; 1234 or die "$PREFIX.ldopts: $!";
1013 print $fh $str; 1235 print $fh $ldopts;
1236
1237 print "$ldopts\n\n"
1238 if $VERBOSE >= 1;
1014} 1239}
1015 1240
1016if ($PERL or defined $APP) { 1241if ($PERL or defined $APP) {
1017 $APP = "perl" unless defined $APP; 1242 $APP = "perl" unless defined $APP;
1018 1243
1244 my $build = "$Config{cc} $ccopts -o \Q$APP\E$Config{_exe} bundle.c $ldopts";
1245
1019 print "generating $APP...\n"; 1246 print "build $APP...\n"
1247 if $VERBOSE >= 1;
1020 1248
1021 system "$Config{cc} \$(cat bundle.ccopts\) -o \Q$APP\E bundle.c \$(cat bundle.ldopts\)"; 1249 print "$build\n"
1250 if $VERBOSE >= 2;
1022 1251
1252 system $build;
1253
1023# unlink "$PREFIX.$_" 1254 unlink "$PREFIX.$_"
1024# for qw(ccopts ldopts c h); 1255 for qw(ccopts ldopts c h);
1025 1256
1026 print "\n"; 1257 print "\n"
1258 if $VERBOSE >= 1;
1027} 1259}
1028 1260

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines