ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/App-Staticperl/bin/staticperl
Revision: 1.2
Committed: Mon Dec 6 20:53:44 2010 UTC (15 years, 9 months ago) by root
Branch: MAIN
Changes since 1.1: +331 -23 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #!/bin/sh
2
3 #############################################################################
4 # configuration to fill in
5
6 PERLVER=5.12.2 # 5.8.9 is also a good choice
7 STATICPERL=~/.staticperl
8 CPAN=http://mirror.netcologne.de/cpan/ # which mirror to use
9 EMAIL="read the documentation <rtfm@example.org>"
10
11 MKBUNDLE="$STATICPERL/mkbundle"
12
13 # perl build variables
14 PREFIX="$STATICPERL/perl" # where the perl gets installed
15 PERL_CPPFLAGS="-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=65536 -D_GNU_SOURCE -DNDEBUG -USITELIB_EXP -USITEARCHEXP -UARCHLIB_EXP"
16 PERL_OPTIMIZE="-Os -ffunction-sections -fdata-sections -finline-limit=8 -ffast-math"
17
18 ARCH="$(uname -m)"
19
20 case "$ARCH" in
21 i*86 | x86_64 | amd64 )
22 PERL_OPTIMIZE="$PERL_OPTIMIZE -mpush-args -mno-inline-stringops-dynamically -mno-align-stringops -mno-ieee-fp" # x86/amd64
23 case "$ARCH" in
24 i*86 )
25 PERL_OPTIMIZE="$PERL_OPTIMIZE -fomit-frame-pointer -march=pentium3 -mtune=i386" # x86 only
26 ;;
27 esac
28 ;;
29 esac
30
31 # -Wl,--gc-sections makes it impossible to check for undefined references
32 # for some reason so we need to patch away the "-no" after Configure and before make :/
33 # -z muldefs is to work around uclibc's pthread static linking bug
34 PERL_LDFLAGS="-Wl,--no-gc-sections -z muldefs"
35 PERL_LIBS="-lm -lcrypt" # perl loves to add lotsa crap itself
36
37 # some configuration options for modules
38 export PERL_MM_USE_DEFAULT=1
39 #export CORO_INTERFACE=p # needed without nptl on x86, due to bugs in linuxthreads - very slow
40 export EV_EXTRA_DEFS='-DEV_FEATURES=4+8+16+64 -DEV_USE_SELECT=0 -DEV_USE_POLL=1 -DEV_USE_EPOLL=1 -DEV_NO_LOOPS -DEV_COMPAT3=0'
41
42 # which extra modules to install by default from CPAN that are
43 # required by mkbundle
44 STATICPERL_MODULES="common::sense Pod::Strip PPI::XS Pod::Usage"
45
46 # which extra modules you might want to install
47 EXTRA_MODULES=""
48
49 # overridable functions
50 postconfigure() { : ; }
51 postbuild() { : ; }
52 postinstall() { : ; }
53
54 # now source user config, if any
55 [ -r /etc/staticperlrc ] && . /etc/staticperlrc
56 [ -r ~/.staticperlrc ] && . ~/.staticperlrc
57 [ -r "$STATICPERL/rc" ] && . "$STATICPERL/rc"
58
59 #############################################################################
60 # support
61
62 # set version in a way that Makefile.PL can extract
63 VERSION=VERSION; eval \
64 $VERSION=0.1
65
66 BZ2=bz2
67 BZIP2=bzip2
68
69 fatal() {
70 printf -- "\nFATAL: %s\n\n" "$*" >&2
71 exit 1
72 }
73
74 verbose() {
75 printf -- "%s\n" "$*"
76 }
77
78 verblock() {
79 verbose
80 verbose "***"
81 while read line; do
82 verbose "*** $line"
83 done
84 verbose "***"
85 verbose
86 }
87
88 rcd() {
89 cd "$1" || fatal "$1: cannot enter"
90 }
91
92 trace() {
93 prefix="$1"; shift
94 # "$@" 2>&1 | while read line; do
95 # echo "$prefix: $line"
96 # done
97 "$@"
98 }
99
100 trap wait 0
101
102 #############################################################################
103 # clean
104
105 distclean() {
106 verblock <<EOF
107 deleting everything installed by this script
108 EOF
109
110 rm -rf "$STATICPERL"
111 }
112
113 #############################################################################
114 # download/configure/compile/install perl
115
116 clean() {
117 cd "$STATICPERL/src/perl-$PERLVER" 2>/dev/null || return
118
119 rm -f staticstamp.configure
120 make distclean >/dev/null 2>&1
121 }
122
123 fetch() {
124 rcd "$STATICPERL"
125
126 mkdir -p src
127 rcd src
128
129 if ! [ -d "perl-$PERLVER" ]; then
130 if ! [ -e "perl-$PERLVER.tar.$BZ2" ]; then
131
132 URL="$CPAN/src/5.0/perl-$PERLVER.tar.$BZ2"
133
134 verblock <<EOF
135 downloading perl
136 to manually download perl yourself, place
137 perl-$PERLVER.tar.$BZ2 in $STATICPERL
138 trying $URL
139 EOF
140
141 curl >perl-$PERLVER.tar.$BZ2~ "$URL" \
142 || wget -O perl-$PERLVER.tar.$BZ2~ "$URL" \
143 || fatal "$URL: error during downloading"
144 mv perl-$PERLVER.tar.$BZ2~ perl-$PERLVER.tar.$BZ2
145 fi
146
147 verblock <<EOF
148 unpacking perl
149 EOF
150
151 mkdir -p unpack
152 $BZIP2 -d <perl-$PERLVER.tar.bz2 | tar xpC unpack \
153 || fatal "perl-$PERLVER.tar.bz2: error during unpacking"
154 mv unpack/perl-$PERLVER perl-$PERLVER
155 rmdir -p unpack
156 fi
157 }
158
159 # similar to GNU-sed -i or perl -pi
160 sedreplace() {
161 sed -e "$1" <"$2" > "$2~" || fatal "error while running sed"
162 mv "$2~" "$2"
163 }
164
165 configure() {
166 fetch
167
168 rcd "$STATICPERL/src/perl-$PERLVER"
169
170 [ -e staticstamp.configure ] && return
171
172 verblock <<EOF
173 configuring $STATICPERL/src/perl-$PERLVER
174 EOF
175
176 clean
177
178 rm -f "$PREFIX/staticstamp.install"
179
180 # I hate them
181 grep -q -- -fstack-protector Configure && \
182 sedreplace 's/-fstack-protector/-fno-stack-protector/g' Configure
183
184 # trace configure \
185 sh Configure -Duselargefiles \
186 -Uuse64bitint \
187 -Dusemymalloc=n \
188 -Uusedl \
189 -Uusethreads \
190 -Uuseithreads \
191 -Uusemultiplicity \
192 -Duseperlio \
193 -Uusesfio \
194 -Uuseshrplib \
195 -Dcppflags="$PERL_CPPFLAGS" \
196 -Dccflags="-g2 -fno-strict-aliasing" \
197 -Doptimize="$PERL_OPTIMIZE" \
198 -Dldflags="$PERL_LDFLAGS" \
199 -Dlibs="$PERL_LIBS" \
200 -Dprefix="$PREFIX" \
201 -Dbin="$PREFIX/bin" \
202 -Dprivlib="$PREFIX/lib" \
203 -Darchlib="$PREFIX/lib" \
204 -Uusevendorprefix \
205 -Dsitelib="$PREFIX/lib" \
206 -Dsitearch="$PREFIX/lib" \
207 -Usitelibexp \
208 -Uman1dir \
209 -Uman3dir \
210 -Usiteman1dir \
211 -Usiteman3dir \
212 -Dpager=/usr/bin/less \
213 -Demail="$EMAIL" \
214 -Dcf_email="$EMAIL" \
215 -Dcf_by="$EMAIL" \
216 -dE || fatal "Configure failed"
217
218 sedreplace '
219 s/-Wl,--no-gc-sections/-Wl,--gc-sections/g
220 s/ *-fno-stack-protector */ /g
221 ' config.sh
222
223 sh Configure -S || fatal "Configure -S failed"
224
225 postconfigure || fatal "postconfigure hook failed"
226
227 touch staticstamp.configure
228 }
229
230 build() {
231 configure
232
233 rcd "$STATICPERL/src/perl-$PERLVER"
234
235 verblock <<EOF
236 building $STATICPERL/src/perl-$PERLVER
237 EOF
238
239 rm -f "$PREFIX/staticstamp.install"
240
241 make || fatal "make: error while building perl"
242
243 postbuild || fatal "postbuild hook failed"
244 }
245
246 install() {
247 [ -e "$PREFIX/staticstamp.install" ] && return
248
249 build
250
251 verblock <<EOF
252 installing $STATICPERL/src/perl-$PERLVER
253 to $PREFIX
254 EOF
255
256 rm -rf "$PREFIX"
257
258 make install || fatal "make install: error while installing"
259
260 rcd "$PREFIX"
261
262 # create a "make install" replacement for CPAN
263 cat >"$PREFIX"/bin/cpan-make-install <<EOF
264 make install UNINST=1
265 if find blib/arch/auto -type f | grep -q -v .exists; then
266 echo Probably an XS module, rebuilding perl
267 make perl
268 rm -f "$PREFIX"/bin/perl
269 make -f Makefile.aperl inst_perl
270 make -f Makefile.aperl map_clean
271 fi
272 EOF
273 chmod 755 "$PREFIX"/bin/cpan-make-install
274
275 # try to trick CPAN into avoiding ~/.cpan completely
276 echo 1 >"$PREFIX/lib/CPAN/MyConfig.pm"
277
278 "$PREFIX"/bin/perl -MCPAN -e '
279 CPAN::Shell->o (conf => urllist => push => "'"$CPAN"'");
280 CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
281 CPAN::Shell->o (conf => q<init>);
282 CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
283 CPAN::Shell->o (conf => q<build_dir>, "'"$STATICPERL"'/cpan/build");
284 CPAN::Shell->o (conf => q<prefs_dir>, "'"$STATICPERL"'/cpan/prefs");
285 CPAN::Shell->o (conf => q<histfile> , "'"$STATICPERL"'/cpan/histfile");
286 CPAN::Shell->o (conf => q<keep_source_where>, "'"$STATICPERL"'/cpan/sources");
287 CPAN::Shell->o (conf => q<make_install_make_command>, "'"$PREFIX"'/bin/cpan-make-install");
288 CPAN::Shell->o (conf => q<prerequisites_policy>, q<follow>);
289 CPAN::Shell->o (conf => q<build_requires_install_policy>, q<no>);
290 CPAN::Shell->o (conf => q<commit>);
291 ' || fatal "error while initialising CPAN"
292
293 NOCHECK_INSTALL=+
294 instcpan $STATICPERL_MODULES
295 [ $EXTRA_MODULES ] && instcpan $EXTRA_MODULES
296
297 postinstall || fatal "postinstall hook failed"
298
299 touch "$PREFIX/staticstamp.install"
300 }
301
302 #############################################################################
303 # install a module from CPAN
304
305 instcpan() {
306 [ $NOCHECK_INSTALL ] || install
307
308 verblock <<EOF
309 installing modules from CPAN
310 $@
311 EOF
312
313 for mod in "$@"; do
314 "$PREFIX"/bin/perl -MCPAN -e 'notest install => "'"$mod"'"' \
315 || fatal "$mod: unable to install from CPAN"
316 done
317 rm -rf "$STATICPERL/build"
318 }
319
320 #############################################################################
321 # install a module from unpacked sources
322
323 instsrc() {
324 [ $NOCHECK_INSTALL ] || install
325
326 verblock <<EOF
327 installing modules from source
328 $@
329 EOF
330
331 for mod in "$@"; do
332 echo
333 echo $mod
334 (
335 rcd $mod
336 make -f Makefile.aperl map_clean >/dev/null 2>&1
337 make distclean >/dev/null 2>&1
338 "$PREFIX"/bin/perl Makefile.PL || fatal "$mod: error running Makefile.PL"
339 make || fatal "$mod: error building module"
340 "$PREFIX"/bin/cpan-make-install || fatal "$mod: error installing module"
341 make distclean >/dev/null 2>&1
342 exit 0
343 ) || exit $?
344 done
345 }
346
347 #############################################################################
348 # do schmorpy stuff
349
350 MODSRCDIR=~/src
351
352 instmodsrc() {
353 for mod in "$@"; do
354 instmod_src "$MODSRCDIR/$mod"
355 done
356 }
357
358 install_schmorp() {
359 install
360
361 instcpan Data::Dump Term::ReadLine::Perl Term::ANSIColor Term::ReadKey
362 instcpan Digest::SHA Digest::MD6 Digest::SHA256 Digest::MD4 Digest::HMAC_MD5 Digest::HMAC_MD6 Digest::FNV
363 #instcpan Net::SSLeay # requires static -ldl
364
365 instmodsrc common-sense Crypt-Twofish2 Array-Heap Convert-Scalar Compress-LZF JSON-XS
366 instmodsrc EV Guard Async-Interrupt IO-AIO
367 instmodsrc AnyEvent AnyEvent-AIO Coro AnyEvent-HTTP
368 instmodsrc Linux-Inotify2 EV-Loop-Async
369
370 instcpan AnyEvent::HTTPD
371 }
372
373 #############################################################################
374 # main
375
376 podusage() {
377 echo
378 if [ -e "$PREFIX/bin/perl" ]; then
379 "$PREFIX/bin/perl" -MPod::Usage -e \
380 'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
381 2>/dev/null && exit
382 fi
383 # try whatever perl we can find
384 perl -MPod::Usage -e \
385 'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
386 2>/dev/null && exit
387
388 fatal "displaying documentation requires a working perl - try '$0 install' first"
389 }
390
391 usage() {
392 podusage 0
393 }
394
395 catmkbundle() {
396 {
397 read dummy
398 echo "#!$PREFIX/bin/perl"
399 cat
400 } <<'MKBUNDLE'
401 #!/opt/bin/perl
402
403 #############################################################################
404 # cannot load modules till after the tracer BEGIN block
405
406 our $VERBOSE = 1;
407 our $STRIP = "pod"; # none, pod or ppi
408 our $PERL = 0;
409 our $VERIFY = 0;
410 our $STATIC = 0;
411
412 my $PREFIX = "bundle";
413 my $PACKAGE = "static";
414
415 my %pm;
416 my @libs;
417 my @static_ext;
418 my $extralibs;
419
420 @ARGV
421 or die "$0: use 'staticperl help' (or read the sources of staticperl)\n";
422
423 $|=1;
424
425 our ($TRACER_W, $TRACER_R);
426
427 sub find_inc($) {
428 for (@INC) {
429 next if ref;
430 return $_ if -e "$_/$_[0]";
431 }
432
433 undef
434 }
435
436 BEGIN {
437 # create a loader process to detect @INC requests before we load any modules
438 my ($W_TRACER, $R_TRACER); # used by tracer
439
440 pipe $R_TRACER, $TRACER_W or die "pipe: $!";
441 pipe $TRACER_R, $W_TRACER or die "pipe: $!";
442
443 unless (fork) {
444 close $TRACER_R;
445 close $TRACER_W;
446
447 unshift @INC, sub {
448 my $dir = find_inc $_[1]
449 or return;
450
451 syswrite $W_TRACER, "-\n$dir\n$_[1]\n";
452
453 open my $fh, "<:perlio", "$dir/$_[1]"
454 or warn "ERROR: $dir/$_[1]: $!\n";
455
456 $fh
457 };
458
459 while (<$R_TRACER>) {
460 if (/use (.*)$/) {
461 my $mod = $1;
462 eval "require $mod";
463 warn "ERROR: $@ (while loading '$mod')\n"
464 if $@;
465 syswrite $W_TRACER, "\n";
466 } elsif (/eval (.*)$/) {
467 my $eval = $1;
468 eval $eval;
469 warn "ERROR: $@ (in '$eval')\n"
470 if $@;
471 }
472 }
473
474 exit 0;
475 }
476 }
477
478 # module loading is now safe
479 use Config;
480
481 sub trace_module {
482 syswrite $TRACER_W, "use $_[0]\n";
483
484 for (;;) {
485 <$TRACER_R> =~ /^-$/ or last;
486 my $dir = <$TRACER_R>; chomp $dir;
487 my $name = <$TRACER_R>; chomp $name;
488
489 $pm{$name} = "$dir/$name";
490
491 if ($name =~ /^(.*)\.pm$/) {
492 my $auto = "auto/$1";
493 my $autodir = "$dir/$auto";
494
495 if (-d $autodir) {
496 opendir my $dir, $autodir
497 or die "$autodir: $!\n";
498
499 for (readdir $dir) {
500 # AutoLoader
501 $pm{"$auto/$_"} = "$autodir/$_"
502 if /\.(?:al|ix)$/;
503
504 # static ext
505 if (/\Q$Config{_a}\E$/o) {
506 push @libs, "$autodir/$_";
507 push @static_ext, $name;
508 }
509
510 # extralibs.ld
511 if ($_ eq "extralibs.ld") {
512 open my $fh, "<:perlio", "$autodir/$_"
513 or die "$autodir/$_";
514
515 local $/;
516 $extralibs .= " " . <$fh>;
517 }
518
519 # dynamic object
520 warn "WARNING: found shared object - can't link statically ($_)\n"
521 if /\.\Q$Config{dlext}\E$/o;
522
523 #TODO: extralibs?
524 }
525 }
526 }
527 }
528 }
529
530 sub trace_eval {
531 syswrite $TRACER_W, "eval $_[0]\n";
532 }
533
534 sub trace_finish {
535 close $TRACER_W;
536 close $TRACER_R;
537 }
538
539 #############################################################################
540 # now we can use modules
541
542 use common::sense;
543 use Digest::MD5;
544
545 sub dump_string {
546 my ($fh, $data) = @_;
547
548 if (length $data) {
549 for (
550 my $ofs = 0;
551 length (my $substr = substr $data, $ofs, 80);
552 $ofs += 80
553 ) {
554 $substr =~ s/([^\x20-\x21\x23-\x5b\x5d-\x7e])/sprintf "\\%03o", ord $1/ge;
555 $substr =~ s/\?/\\?/g; # trigraphs...
556 print $fh " \"$substr\"\n";
557 }
558 } else {
559 print $fh " \"\"\n";
560 }
561 }
562
563 # required for @INC loading, unfortunately
564 trace_module "PerlIO::scalar";
565
566 #trace_module "Term::ReadLine::readline"; # Term::ReadLine::Perl dependency
567 # URI is difficult
568 #trace_module "URI::http";
569 #trace_module "URI::_generic";
570
571 sub cmd_boot {
572 $pm{"//boot"} = $_[0];
573 }
574
575 sub cmd_add {
576 $_[0] =~ /^(.*)(?:\s*(\S+))$/
577 or die "$_[0]: cannot parse";
578
579 my $file = $1;
580 my $as = defined $2 ? $2 : "/$1";
581
582 $pm{$as} = $file;
583 }
584
585 sub cmd_file {
586 open my $fh, "<", $_[0]
587 or die "$_[0]: $!\n";
588
589 while (<$fh>) {
590 chomp;
591 my ($cmd, $args) = split / /, $_, 2;
592 $cmd =~ s/^-+//;
593
594 if ($cmd eq "strip") {
595 $STRIP = $args;
596 } elsif ($cmd eq "eval") {
597 trace_eval $_;
598 } elsif ($cmd eq "use") {
599 trace_module $_
600 for split / /, $args;
601 } elsif ($cmd eq "boot") {
602 cmd_boot $args;
603 } elsif ($cmd eq "static") {
604 $STATIC = 1;
605 } elsif ($cmd eq "add") {
606 cmd_add $args;
607 } elsif (/^\s*#/) {
608 # comment
609 } elsif (/\S/) {
610 die "$_: unsupported directive\n";
611 }
612 }
613 }
614
615 use Getopt::Long;
616
617 Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case");
618
619 GetOptions
620 "strip=s" => \$STRIP,
621 "verbose|v" => sub { ++$VERBOSE },
622 "quiet|q" => sub { --$VERBOSE },
623 "perl" => \$PERL,
624 "eval|e=s" => sub { trace_eval $_[1] },
625 "use|M=s" => sub { trace_module $_[1] },
626 "boot=s" => sub { cmd_boot $_[1] },
627 "add=s" => sub { cmd_add $_[1] },
628 "static" => sub { $STATIC = 1 },
629 "<>" => sub { cmd_file $_[1] },
630 or exit 1;
631
632 my $data;
633 my @index;
634 my @order = sort {
635 length $a <=> length $b
636 or $a cmp $b
637 } keys %pm;
638
639 # sorting by name - better compression, but needs more metadata
640 # sorting by length - faster lookup
641 # usually, the metadata overhead beats the loss through compression
642
643 for my $pm (@order) {
644 my $path = $pm{$pm};
645
646 128 > length $pm
647 or die "$pm: path too long (only 128 octets supported)\n";
648
649 my $src = ref $path
650 ? $$path
651 : do {
652 open my $pm, "<:perlio", $path
653 or die "$path: $!";
654
655 local $/;
656
657 <$pm>
658 };
659
660 if ($pm =~ /^auto\/POSIX\/[^\/]+\.al$/) {
661 if ($src =~ /^ unimpl \"/m) {
662 warn "$pm: skipping (not implemented anyways).\n"
663 if $VERBOSE >= 2;
664 next;
665 }
666 }
667
668 if ($STRIP =~ /ppi/i) {
669 require PPI;
670
671 my $ppi = PPI::Document->new (\$src);
672 $ppi->prune ("PPI::Token::Comment");
673 $ppi->prune ("PPI::Token::Pod");
674
675 # prune END stuff
676 for (my $last = $ppi->last_element; $last; ) {
677 my $prev = $last->previous_token;
678
679 if ($last->isa (PPI::Token::Whitespace::)) {
680 $last->delete;
681 } elsif ($last->isa (PPI::Statement::End::)) {
682 $last->delete;
683 last;
684 } elsif ($last->isa (PPI::Token::Pod::)) {
685 $last->delete;
686 } else {
687 last;
688 }
689
690 $last = $prev;
691 }
692
693 # prune some but not all insignificant whitespace
694 for my $ws (@{ $ppi->find (PPI::Token::Whitespace::) }) {
695 my $prev = $ws->previous_token;
696 my $next = $ws->next_token;
697
698 if (!$prev || !$next) {
699 $ws->delete;
700 } else {
701 if (
702 $next->isa (PPI::Token::Operator::) && $next->{content} =~ /^(?:,|=|!|!=|==|=>)$/ # no ., because of digits. == float
703 or $prev->isa (PPI::Token::Operator::) && $prev->{content} =~ /^(?:,|=|\.|!|!=|==|=>)$/
704 or $prev->isa (PPI::Token::Structure::)
705 # decrease size, decrease compressability
706 #or ($prev->isa (PPI::Token::Word::)
707 # && (PPI::Token::Symbol:: eq ref $next
708 # || $next->isa (PPI::Structure::Block::)
709 # || $next->isa (PPI::Structure::List::)
710 # || $next->isa (PPI::Structure::Condition::)))
711 ) {
712 $ws->delete;
713 } elsif ($prev->isa (PPI::Token::Whitespace::)) {
714 $ws->{content} = ' ';
715 $prev->delete;
716 } else {
717 $ws->{content} = ' ';
718 }
719 }
720 }
721
722 # prune whitespace around blocks
723 if (0) {
724 # these usually decrease size, but decrease compressability more
725 for my $struct (PPI::Structure::Block::, PPI::Structure::Condition::) {
726 for my $node (@{ $ppi->find ($struct) }) {
727 my $n1 = $node->first_token;
728 my $n2 = $n1->previous_token;
729 $n1->delete if $n1->isa (PPI::Token::Whitespace::);
730 $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
731 my $n1 = $node->last_token;
732 my $n2 = $n1->next_token;
733 $n1->delete if $n1->isa (PPI::Token::Whitespace::);
734 $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
735 }
736 }
737
738 for my $node (@{ $ppi->find (PPI::Structure::List::) }) {
739 my $n1 = $node->first_token;
740 $n1->delete if $n1->isa (PPI::Token::Whitespace::);
741 my $n1 = $node->last_token;
742 $n1->delete if $n1->isa (PPI::Token::Whitespace::);
743 }
744 }
745
746 # reformat qw() lists which often have lots of whitespace
747 for my $node (@{ $ppi->find (PPI::Token::QuoteLike::Words::) }) {
748 if ($node->{content} =~ /^qw(.)(.*)(.)$/s) {
749 my ($a, $qw, $b) = ($1, $2, $3);
750 $qw =~ s/^\s+//;
751 $qw =~ s/\s+$//;
752 $qw =~ s/\s+/ /g;
753 $node->{content} = "qw$a$qw$b";
754 }
755 }
756
757 $src = $ppi->serialize;
758 } elsif ($STRIP =~ /pod/i && $pm ne "Opcode.pm") { # opcode parses it's own pod
759 require Pod::Strip;
760
761 my $stripper = Pod::Strip->new;
762
763 my $out;
764 $stripper->output_string (\$out);
765 $stripper->parse_string_document ($src);
766 $src = $out;
767 }
768
769 if ($VERIFY && $pm =~ /\.pm$/ && $pm ne "Opcode.pm") {
770 if (open my $fh, "-|") {
771 <$fh>;
772 } else {
773 eval "#line 1 \"$pm\"\n$src" or warn "\n\n\n$pm\n\n$src\n$@\n\n\n";
774 exit 0;
775 }
776 }
777
778 # if ($pm eq "Opcode.pm") {
779 # open my $fh, ">x" or die; print $fh $src;#d#
780 # exit 1;
781 # }
782
783 warn "adding $pm\n"
784 if $VERBOSE >= 2;
785
786 push @index, ((length $pm) << 25) | length $data;
787 $data .= $pm . $src;
788 }
789
790 length $data < 2**25
791 or die "bundle too large (only 32MB supported)\n";
792
793 my $varpfx = "bundle_" . substr +(Digest::MD5::md5_hex $data), 0, 16;
794
795 #############################################################################
796 # output
797
798 print "generating $PREFIX.h... ";
799
800 {
801 open my $fh, ">", "$PREFIX.h"
802 or die "$PREFIX.h: $!\n";
803
804 print $fh <<EOF;
805 /* do not edit, automatically created by mkstaticbundle */
806 #include <EXTERN.h>
807 #include <perl.h>
808 #include <XSUB.h>
809
810 /* public API */
811 EXTERN_C PerlInterpreter *staticperl;
812 EXTERN_C void staticperl_init (void);
813 EXTERN_C void staticperl_cleanup (void);
814 EOF
815 }
816
817 print "\n";
818
819 #############################################################################
820 # output
821
822 print "generating $PREFIX.c... ";
823
824 open my $fh, ">", "$PREFIX.c"
825 or die "$PREFIX.c: $!\n";
826
827 print $fh <<EOF;
828 /* do not edit, automatically created by mkstaticbundle */
829
830 #include <EXTERN.h>
831 #include <perl.h>
832 #include <XSUB.h>
833
834 #include "bundle.h"
835
836 /* public API */
837 PerlInterpreter *staticperl;
838
839 EOF
840
841 #############################################################################
842 # bundle data
843
844 my $count = @index;
845
846 print $fh <<EOF;
847 #include "bundle.h"
848
849 /* bundle data */
850
851 static const U32 $varpfx\_count = $count;
852 static const U32 $varpfx\_index [$count + 1] = {
853 EOF
854
855 my $col;
856 for (@index) {
857 printf $fh "0x%08x,", $_;
858 print $fh "\n" unless ++$col % 10;
859
860 }
861 printf $fh "0x%08x\n};\n", (length $data);
862
863 print $fh "static const char $varpfx\_data [] =\n";
864 dump_string $fh, $data;
865
866 print $fh ";\n\n";;
867
868 #############################################################################
869 # bootstrap
870
871 # boot file for staticperl
872 # this file will be eval'ed at initialisation time
873
874 my $bootstrap = '
875 BEGIN {
876 package ' . $PACKAGE . ';
877
878 PerlIO::scalar->bootstrap;
879
880 @INC = sub {
881 my $data = find "$_[1]"
882 or return;
883
884 $INC{$_[1]} = $_[1];
885
886 open my $fh, "<", \$data;
887 $fh
888 };
889 }
890 ';
891
892 $bootstrap .= "require '//boot';"
893 if exists $pm{"//boot"};
894
895 $bootstrap =~ s/\s+/ /g;
896 $bootstrap =~ s/(\W) /$1/g;
897 $bootstrap =~ s/ (\W)/$1/g;
898
899 print $fh "const char bootstrap [] = ";
900 dump_string $fh, $bootstrap;
901 print $fh ";\n\n";
902
903 print $fh <<EOF;
904 /* search all bundles for the given file, using binary search */
905 XS(find)
906 {
907 dXSARGS;
908
909 if (items != 1)
910 Perl_croak (aTHX_ "Usage: $PACKAGE\::find (\$path)");
911
912 {
913 STRLEN namelen;
914 char *name = SvPV (ST (0), namelen);
915 SV *res = 0;
916
917 int l = 0, r = $varpfx\_count;
918
919 while (l <= r)
920 {
921 int m = (l + r) >> 1;
922 U32 idx = $varpfx\_index [m];
923 int comp = namelen - (idx >> 25);
924
925 if (!comp)
926 {
927 int ofs = idx & 0x1FFFFFFU;
928 comp = memcmp (name, $varpfx\_data + ofs, namelen);
929
930 if (!comp)
931 {
932 /* found */
933 int ofs2 = $varpfx\_index [m + 1] & 0x1FFFFFFU;
934
935 ofs += namelen;
936 res = newSVpvn ($varpfx\_data + ofs, ofs2 - ofs);
937 goto found;
938 }
939 }
940
941 if (comp < 0)
942 r = m - 1;
943 else
944 l = m + 1;
945 }
946
947 XSRETURN (0);
948
949 found:
950 ST (0) = res;
951 sv_2mortal (ST (0));
952 }
953
954 XSRETURN (1);
955 }
956
957 /* list all files in the bundle */
958 XS(list)
959 {
960 dXSARGS;
961
962 if (items != 0)
963 Perl_croak (aTHX_ "Usage: $PACKAGE\::list");
964
965 {
966 int i;
967
968 EXTEND (SP, $varpfx\_count);
969
970 for (i = 0; i < $varpfx\_count; ++i)
971 {
972 U32 idx = $varpfx\_index [i];
973
974 PUSHs (newSVpvn ($varpfx\_data + (idx & 0x1FFFFFFU), idx >> 25));
975 }
976 }
977
978 XSRETURN ($varpfx\_count);
979 }
980
981 static char *args[] = {
982 "staticperl",
983 "-e",
984 "0"
985 };
986
987 EOF
988
989 #############################################################################
990 # xs_init
991
992 print $fh <<EOF;
993 static void
994 xs_init (pTHX)
995 {
996 EOF
997
998 @static_ext = ("DynaLoader", sort @static_ext);
999
1000 # prototypes
1001 for (@static_ext) {
1002 s/\.pm$//;
1003 (my $cname = $_) =~ s/\//__/g;
1004 print $fh " EXTERN_C void boot_$cname (pTHX_ CV* cv);\n";
1005 }
1006
1007 print $fh <<EOF;
1008 char *file = __FILE__;
1009 dXSUB_SYS;
1010
1011 newXSproto ("$PACKAGE\::find", find, file, "\$");
1012 newXSproto ("$PACKAGE\::list", list, file, "");
1013 EOF
1014
1015 # calls
1016 for (@static_ext) {
1017 s/\.pm$//;
1018
1019 (my $cname = $_) =~ s/\//__/g;
1020 (my $pname = $_) =~ s/\//::/g;
1021
1022 my $bootstrap = $pname eq "DynaLoader" ? "boot" : "bootstrap";
1023
1024 print $fh " newXS (\"$pname\::$bootstrap\", boot_$cname, file);\n";
1025 }
1026
1027 print $fh <<EOF;
1028 Perl_av_create_and_unshift_one (&PL_preambleav, newSVpv (bootstrap, sizeof (bootstrap) - 1));
1029 }
1030 EOF
1031
1032 #############################################################################
1033 # optional perl_init/perl_destroy
1034
1035 if ($PERL) {
1036 print $fh <<EOF;
1037
1038 int
1039 main (int argc, char *argv [])
1040 {
1041 extern char **environ;
1042 int exitstatus;
1043
1044 PERL_SYS_INIT3 (&argc, &argv, &environ);
1045 staticperl = perl_alloc ();
1046 perl_construct (staticperl);
1047
1048 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1049
1050 exitstatus = perl_parse (staticperl, xs_init, argc, argv, environ);
1051 if (!exitstatus)
1052 perl_run (staticperl);
1053
1054 exitstatus = perl_destruct (staticperl);
1055 perl_free (staticperl);
1056 PERL_SYS_TERM ();
1057
1058 return exitstatus;
1059 }
1060 EOF
1061 } else {
1062 print $fh <<EOF;
1063
1064 EXTERN_C void
1065 staticperl_init (void)
1066 {
1067 extern char **environ;
1068 int argc = sizeof (args) / sizeof (args [0]);
1069 char **argv = args;
1070
1071 PERL_SYS_INIT3 (&argc, &argv, &environ);
1072 staticperl = perl_alloc ();
1073 perl_construct (staticperl);
1074 PL_origalen = 1;
1075 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1076 perl_parse (staticperl, xs_init, argc, argv, environ);
1077
1078 perl_run (staticperl);
1079 }
1080
1081 EXTERN_C void
1082 staticperl_cleanup (void)
1083 {
1084 perl_destruct (staticperl);
1085 perl_free (staticperl);
1086 staticperl = 0;
1087 PERL_SYS_TERM ();
1088 }
1089 EOF
1090 }
1091
1092 print -s "$PREFIX.c", " octets (", (length $data) , " data octets).\n\n";
1093
1094 #############################################################################
1095 # libs, cflags
1096
1097 {
1098 print "generating $PREFIX.ccopts... ";
1099
1100 my $str = "$Config{ccflags} $Config{optimize} $Config{cppflags} -I$Config{archlibexp}/CORE";
1101 $str =~ s/([\(\)])/\\$1/g;
1102
1103 print "$str\n\n";
1104
1105 open my $fh, ">$PREFIX.ccopts"
1106 or die "$PREFIX.ccopts: $!";
1107 print $fh $str;
1108 }
1109
1110 {
1111 print "generating $PREFIX.ldopts... ";
1112
1113 my $str = $STATIC ? "--static " : "";
1114
1115 $str .= "$Config{ccdlflags} $Config{ldflags} @libs $Config{archlibexp}/CORE/$Config{libperl} $Config{perllibs}";
1116
1117 my %seen;
1118 $str .= " $_" for grep !$seen{$_}++, ($extralibs =~ /(\S+)/g);
1119
1120 $str =~ s/([\(\)])/\\$1/g;
1121
1122 print "$str\n\n";
1123
1124 open my $fh, ">$PREFIX.ldopts"
1125 or die "$PREFIX.ldopts: $!";
1126 print $fh $str;
1127 }
1128
1129 if ($PERL) {
1130 system "$Config{cc} \$(cat bundle.ccopts\) -o perl bundle.c \$(cat bundle.ldopts\)";
1131
1132 unlink "$PREFIX.$_"
1133 for qw(ccopts ldopts c h);
1134 }
1135
1136 MKBUNDLE
1137 }
1138
1139 bundle() {
1140 catmkbundle >"$MKBUNDLE~" || fatal "$MKBUNDLE~: cannot create"
1141 chmod 755 "$MKBUNDLE~" && mv "$MKBUNDLE~" "$MKBUNDLE"
1142 "$PREFIX/bin/perl" -- "$MKBUNDLE" "$@"
1143 }
1144
1145 if [ $# -gt 0 ]; then
1146 while [ $# -gt 0 ]; do
1147 mkdir -p "$STATICPERL" || fatal "$STATICPERL: cannot create"
1148 mkdir -p "$PREFIX" || fatal "$PREFIX: cannot create"
1149
1150 command="${1#--}"; shift
1151 case "$command" in
1152 fetch | configure | build | install | clean | distclean)
1153 verblock <<EOF
1154 $command
1155 EOF
1156 "$command"
1157 ;;
1158 instsrc )
1159 instsrc "$@"
1160 exit
1161 ;;
1162 instcpan )
1163 instcpan "$@"
1164 exit
1165 ;;
1166 instschmorp )
1167 install_schmorp
1168 ;;
1169 cpan )
1170 install
1171 "$PREFIX/bin/cpan" "$@"
1172 exit
1173 ;;
1174 mkbundle )
1175 install
1176 bundle "$@"
1177 exit
1178 ;;
1179 mkperl )
1180 install
1181 bundle --perl "$@"
1182 exit
1183 ;;
1184 help )
1185 podusage 2
1186 ;;
1187 * )
1188 exec 1>&2
1189 echo
1190 echo "Unknown command: $command"
1191 podusage 0
1192 ;;
1193 esac
1194 done
1195 else
1196 usage
1197 fi
1198
1199 exit 0
1200
1201 =head1 NAME
1202
1203 staticperl - perl, libc, 50 modules all in one 500kb file
1204
1205 =head1 SYNOPSIS
1206
1207 staticperl help # print the embedded documentation
1208 staticperl fetch # fetch and unpack perl sources
1209 staticperl configure # fetch and then configure perl
1210 staticperl build # configure and then build perl
1211 staticperl install # build and then install perl
1212 staticperl clean # clean most intermediate files (restart at configure)
1213 staticperl distclean # delete everything installed by this script
1214 staticperl cpan # invoke CPAN shell
1215 staticperl instmod path... # install unpacked modules
1216 staticperl instcpan modulename... # install modules from CPAN
1217 staticperl mkbundle <bundle-args...> # see documentation
1218 staticperl mkperl <bundle-args...> # see documentation
1219
1220 Typical Examples:
1221
1222 staticperl install # fetch, configure, build and install perl
1223 staticperl cpan # run interactive cpan shell
1224 staticperl mkperl -M '"Config_heavy.pl"' # build a perl that supports -V
1225 staticperl mkperl -MAnyEvent::Impl::Perl -MAnyEvent::HTTPD -MURI -MURI::http
1226 # build a perl with the above modules linked in
1227
1228 =head1 DESCRIPTION
1229
1230 This script helps you creating single-file perl interpreters, or embedding
1231 a pelr interpreter in your apps. Single-file means that it is fully
1232 self-contained - no separate shared objects, no autoload fragments, no .pm
1233 or .pl files are needed. And when linking statically, you can create (or
1234 embed) a single file that contains perl interpreter, libc, all the modules
1235 you need and all the libraries you need.
1236
1237 With uclibc and upx on x86, you can create a single 500kb binary that
1238 contains perl and 50 modules such as AnyEvent, EV, IO::AIO, Coro and so
1239 on. Or any other choice of modules.
1240
1241 The created files do not need write access to the filesystem (like PAR
1242 does). In fact, since this script is in many ways similar to PAR::Packer,
1243 here are the differences:
1244
1245 =over 4
1246
1247 =item * The generated executables are much smaller than PAR created ones.
1248
1249 Shared objects and the perl binary contain a lot of extra info, while
1250 the static nature of F<staticperl> allows the linker to remove all
1251 functionality and meta-info not required by the final executable. Even
1252 extensions statically compiled into perl at build time will only be
1253 present in the final executable when needed.
1254
1255 In addition, F<staticperl> can strip perl sources much more effectively
1256 than PAR.
1257
1258 =item * The generated executables start much faster.
1259
1260 There is no need to unpack files, or even to parse Zip archives (which is
1261 slow and memory-consuming business).
1262
1263 =item * The generated executables don't need a writable filesystem.
1264
1265 F<staticperl> loads all required files directly from memory. There is no
1266 need to unpack files into a temporary directory.
1267
1268 =item * More control over included files.
1269
1270 PAR tries to be maintainance and hassle-free - it tries to include more files
1271 than necessary to make sure everything works out of the box. The extra files
1272 (such as the unicode database) can take substantial amounts of memory and filesize.
1273
1274 With F<staticperl>, the burden is mostly with the developer - only direct
1275 compile-time dependencies and L<AutoLoader> are handled automatically.
1276 This means the modules to include often need to be tweaked manually.
1277
1278 =item * PAR works out of the box, F<staticperl> does not.
1279
1280 Maintaining your own custom perl build can be a pain in the ass, and while
1281 F<staticperl> tries to make this easy, it still requires a custom perl
1282 build and possibly fiddling with some modules. PAR is likely to produce
1283 results faster.
1284
1285 =back
1286
1287 =head1 HOW DOES IT WORK?
1288
1289 Simple: F<staticperl> downloads, compile and installs a perl version of
1290 your choice in F<~/.staticperl>. You can add extra modules either by
1291 letting F<staticperl> install them for you automatically, or by using CPAN
1292 and doing it interactively. This usually takes 5-10 minutes, depending on
1293 the speed of your computer and your internet conenction.
1294
1295 It is possible to do program development at this stage, too.
1296
1297 Afterwards, you create a list of files and modules you want to include,
1298 and then either build a new perl binary (that acts just like a normla perl
1299 except everything is compiled in), or you create bundle files (basically C
1300 sources you can use to embed all files into your project).
1301
1302 This step is very fast (a few seconds if PPI is not used for stripping,
1303 more seconds otherwise, as PPI is very slow), and can be tweaked and
1304 repeated as often as necessary.
1305
1306 =head1 THE F<STATICPERL> SCRIPT
1307
1308 This module installs a script called F<staticperl> into your perl
1309 binary directory. The script is fully self-contained, and can be used
1310 without perl (for example, in an uClibc chroot environment). In fact,
1311 it can be extracted from the C<App::Staticperl> distribution tarball as
1312 F<bin/staticperl>, without any installation.
1313
1314 F<staticperl> interprets the first argument as a command to execute,
1315 optionally followed by any parameters.
1316
1317 There are two command categories: the "phase 1" commands which deal with
1318 installing perl and perl modules, and the "phase 2" commands, which deal
1319 with creating binaries and bundle files.
1320
1321 =head2 PHASE 1 COMMANDS: INSTALLING PERL
1322
1323 The most important command is F<install>, which does basically
1324 everything. The default is to download and install perl 5.12.2 and a few
1325 modules required by F<staticperl> itself, but all this can (and should) be
1326 changed - see L<CONFIGURATION>, below.
1327
1328 The command
1329
1330 staticperl install
1331
1332 Is normally all you need: It installs the perl interpreter in
1333 F<~/.staticperl/perl>. It downloads, configures, builds and installs the
1334 perl interpreter if required.
1335
1336 Most of the following commands simply run one or more steps of this
1337 sequence.
1338
1339 To force recompilation or reinstalaltion, you need to run F<staticperl
1340 distclean> first.
1341
1342 =over 4
1343
1344 =item F<staticperl fetch>
1345
1346 Runs only the download and unpack phase, unless this has already happened.
1347
1348 =item F<staticperl configure>
1349
1350 Configures the unpacked perl sources, potentially after downloading them first.
1351
1352 =item F<staticperl build>
1353
1354 Builds the configured perl sources, potentially after automatically
1355 configuring them.
1356
1357 =item F<staticperl install>
1358
1359 Wipes the perl installation directory (usually F<~/.staticperl/perl>) and installs
1360 the perl distribution, potentially aftering building it first.
1361
1362 =item F<staticperl cpan> [args...]
1363
1364 Starts an interactive CPAN shell that you cna use to install further
1365 modules. Installs the perl first if neccessary, but apart from that,
1366 no magic is involved: you could just as well run it manually via
1367 F<~/.staticperl/perl/bin/cpan>.
1368
1369 Any additional arguments are simply passed to the F<cpan> command.
1370
1371 =item F<staticperl instcpan> module...
1372
1373 Tries to install all the modules given and their dependencies, using CPAN.
1374
1375 Example:
1376
1377 staticperl instcpan EV AnyEvent::HTTPD Coro
1378
1379 =item F<staticperl instsrc> directory...
1380
1381 In the unlikely case that you have unpacked perl modules around and want
1382 to install from these instead of from CPAN, you cna do this using this
1383 command by specifying all the directories with modules in them that you
1384 want to have built.
1385
1386 =item F<staticperl clean>
1387
1388 Runs F<make distclean> in the perl source directory (and potentially
1389 cleans up other intermediate files). This can be used to clean up
1390 intermediate files without removing the installed perl interpreter.
1391
1392 =item F<staticperl distclean>
1393
1394 This wipes your complete F<~/.staticperl> directory. Be careful with this,
1395 it nukes your perl download, perl sources, perl distribution and any
1396 installed modules. It is useful if you wish to start over "from scratch"
1397 or when you want to uninstall F<staticperl>.
1398
1399 =back
1400
1401 =head2 PHASE 2 COMMANDS: BUILDING PERL BUNDLES
1402
1403 Building (linking) a new F<perl> binary is handled by a separate
1404 script. To make it easy to use F<staticperl> from a F<chroot>, the script
1405 is embedded into F<staticperl>, which will write it out and call for you
1406 with any arguments you pass:
1407
1408 staticperl mkbundle mkbundle-args...
1409
1410 In the oh so unlikely case of something not working here, you
1411 can run the script manually as well (by default it is written to
1412 F<~/.staticperl/mkbundle>).
1413
1414 F<mkbundle> is a more conventional command and expect the argument
1415 syntax commonly used on unix clones. For example, this command builds
1416 a new F<perl> binary and includes F<Config.pm> (for F<perl -V>),
1417 F<AnyEvent::HTTPD>, F<URI> and a custom F<httpd> script (from F<eg/httpd>
1418 in this distribution):
1419
1420 # first make sure we have perl and the required modules
1421 staticperl instcpan AnyEvent::HTTPD
1422
1423 # now build the perl
1424 staticperl mkperl -M'"Config_heavy.pl"' -MAnyEvent::Impl::Perl \
1425 -MAnyEvent::HTTPD -MURI::http \
1426 --add 'eg/httpd httpd.pm'
1427
1428 # finally, invoke it
1429 ./perl -Mhttpd
1430
1431 As you can see, things are not quite as trivial: the L<Config> module has
1432 a hidden dependency which is not even a perl module (F<Config_heavy.pl>),
1433 L<AnyEvent> needs at least one event loop backend that we have to
1434 specifymanually (here L<AnyEvent::Impl::Perl>), and the F<URI> module
1435 (required by L<AnyEvent::HTTPD>) implements various URI schemes as extra
1436 modules - since L<AnyEvent::HTTPD> only needs C<http> URIs, we only need
1437 to include that module.
1438
1439 =head3 OPTION PROCESSING
1440
1441 All options can be given as arguments on the commandline (typically using
1442 long (e.g. C<--verbose>) or short option (e.g. C<-v>) style). Since
1443 specifying a lot of modules can make the commandlien very cumbersome,
1444 you can put all long options into a "bundle specification file" (with or
1445 without C<--> prefix) and specify this bundle file instead.
1446
1447 For example, the command given earlier could also look like this:
1448
1449 staticperl mkperl httpd.bundle
1450
1451 And all options could be in F<httpd.bundle>:
1452
1453 use "Config_heavy.pl"
1454 use AnyEvent::Impl::Perl
1455 use AnyEvent::HTTPD
1456 use URI::http
1457 add eg/httpd httpd.pm
1458
1459 All options that specify modules or files to be added are processed in the
1460 order given on the commandline (that affects the C<--use> and C<--eval>
1461 options at the moment).
1462
1463 =head3 MKBUNDLE OPTIONS
1464
1465 =over 4
1466
1467 =item --verbose | -v
1468
1469 Increases the verbosity level by one (the default is C<1>).
1470
1471 =item --quiet | -q
1472
1473 Decreases the verbosity level by one.
1474
1475 =item --strip none|pod|ppi
1476
1477 Specify the stripping method applied to reduce the file of the perl
1478 sources included.
1479
1480 The default is C<pod>, which uses the L<Pod::Strip> module to remove all
1481 pod documenatiton, which is very fast and reduces filesize a lot.
1482
1483 The C<ppi> method uses L<PPI> to parse and condense the perl sources. This
1484 saves a lot more than just L<Pod::Strip>, and is generally safer, but is
1485 also a lot slower, so is best used for production builds.
1486
1487 Last not least, in the unlikely case where C<pod> is too slow, or some
1488 module gets mistreated, you can specify C<none> to not mangle included
1489 perl sources in any way.
1490
1491 =item --perl
1492
1493 After writing out the bundle files, try to link a new perl interpreter. It
1494 will be called F<perl> and will be left in the current working
1495 directory. The bundle files will be removed.
1496
1497 This switch is automatically ued when F<staticperl> is invoked with the
1498 C<mkperl> command (instead of C<mkbundle>):
1499
1500 # build a new ./perl with only common::sense in it - very small :)
1501 staticperl mkperl -Mcommon::sense
1502
1503 =item --use module | -Mmodule
1504
1505 Include the named module and all direct dependencies. This is done by
1506 C<require>'ing the module in a subprocess and tracing which other modules
1507 and files it actually loads. If the module uses L<AutoLoader>, then all
1508 splitfiles will be included as well.
1509
1510 Example: include AnyEvent and AnyEvent::Impl::Perl.
1511
1512 staticperl mkbundle --use AnyEvent --use AnyEvent::Impl::Perl
1513
1514 Sometimes you want to load old-style "perl libraries" (F<.pl> files), or
1515 maybe other weirdly named files. To do that, you need to quote the name in
1516 single or double quoutes. When given on the commandline, you probably need
1517 to quote once more to avoid your shell interpreting it. Common cases that
1518 need this are F<Config_heavy.pl> and F<utf8_heavy.pl>.
1519
1520 Example: include the required files for F<perl -V> to work in all its
1521 glory (F<Config.pm> is included automatically by this).
1522
1523 # bourne shell
1524 staticperl mkbundle --use '"Config_heavy.pl"'
1525
1526 # bundle specification file
1527 use "Config_heavy.pl"
1528
1529 The C<-Mmodule> syntax is included as an alias that might be easier to
1530 remember than C<use>. Or maybe it confuses people. Time will tell. Or
1531 maybe not. Argh.
1532
1533 =item --eval "perl code" | -e "perl code"
1534
1535 Sometimes it is easier (or necessary) to specify dependencies using perl
1536 code, or maybe one of the modules you use need a special use statement. In
1537 that case, you can use C<eval> to execute some perl snippet or set some
1538 variables or whatever you need. All files C<require>'d or C<use>'d in the
1539 script are included in the final bundle.
1540
1541 Keep in mind that F<mkbundle> will only C<require> the modules named
1542 by the C<--use> option, so do not expect the symbols from modules you
1543 C<--use>'d earlier on the commandlien to be available.
1544
1545 Example: force L<AnyEvent> to detect a backend and therefore include it
1546 in the final bundle.
1547
1548 staticperl mkbundle --eval 'use AnyEvent; AnyEvent::detect'
1549
1550 # or like this
1551 staticperl mkbundle -MAnyEvent --eval 'use AnyEvent; AnyEvent::detect'
1552
1553 Example: use a separate "bootstrap" script that C<use>'s lots of modules
1554 and include this in the final bundle, to be executed automatically.
1555
1556 staticperl mkbundle --eval 'do "bootstrap"' --boot bootstrap
1557
1558 =item --boot filename
1559
1560 Include the given file in the bundle and arrange for it to be executed
1561 (using a C<require>) before anything else when the new perl is
1562 initialised. This can be used to modify C<@INC> or anything else before
1563 the perl interpreter executes scripts given on the commandline (or via
1564 C<-e>). This works even in an embedded interpreter.
1565
1566 =item --add "file" | --add "file alias"
1567
1568 Adds the given (perl) file into the bundle (and optionally call it
1569 "alias"). This is useful to include any custom files into the bundle.
1570
1571 Example: embed the file F<httpd> as F<httpd.pm> when creating the bundle.
1572
1573 staticperl mkperl --add "httpd httpd.pm"
1574
1575 It is also a great way to add any custom modules:
1576
1577 # specification file
1578 add file1 myfiles/file1
1579 add file2 myfiles/file2
1580 add file3 myfiles/file3
1581
1582 =item --static
1583
1584 When C<--perl> is also given, link statically instead of dynamically. The
1585 default is to link the new perl interpreter fully dynamic (that means all
1586 perl modules are linked statically, but all external libraries are still
1587 referenced dynamically).
1588
1589 Keep in mind that Solaris doesn't support static linking at all, and
1590 systems based on GNU libc don't really support it in a usable fashion
1591 either. Try uClibc if you want to create fully statically linked
1592 executables, or try the C<--staticlibs> option to link only some libraries
1593 statically.
1594
1595 =item any other argument
1596
1597 Any other argument is interpreted as a bundle specification file, which
1598 supports most long options (without extra quoting), one option per line.
1599
1600 =back
1601
1602 =head2 F<STATCPERL> CONFIGURATION AND HOOKS
1603
1604 During (each) startup, F<staticperl> tries to source the following shell
1605 files in order:
1606
1607 /etc/staticperlrc
1608 ~/.staticperlrc
1609 $STATICPERL/rc
1610
1611 They can be used to override shell variables, or define functions to be
1612 called at specific phases.
1613
1614 Note that the last file is erased during F<staticperl distclean>, so
1615 generally should not be used.
1616
1617 =head3 CONFIGURATION VARIABLES
1618
1619 =head4 Variables you I<should> override
1620
1621 =over 4
1622
1623 =item C<EMAIL>
1624
1625 The e-mail address of the person who built this binary. Has no good
1626 default, so should be specified by you.
1627
1628 =back
1629
1630 =head4 Variables you I<might want> to override
1631
1632 =over 4
1633
1634 =item C<PERLVER>
1635
1636 The perl version to install - default is currently C<5.12.2>, but C<5.8.9>
1637 is also a good choice (5.8.9 is much smaller than 5.12.2, while 5.10.1 is
1638 about as big as 5.12.2).
1639
1640 =item C<CPAN>
1641
1642 The URL of the CPAN mirror to use (e.g. L<http://mirror.netcologne.de/cpan/>).
1643
1644 =item C<PERL_CPPFLAGS>, C<PERL_OPTIMIZE>, C<PERL_LDFLAGS>, C<PERL_LIBS>
1645
1646 These flags are passed to perl's F<Configure> script, and are generally
1647 optimised for small size (at the cost of performance). Since they also
1648 contain subtle workarounds around various build issues, changing these
1649 usually requires understanding their default values - best look at the top
1650 of the F<staticperl> script for more info on these.
1651
1652 =item C<STATICPERL>
1653
1654 The directory where staticperl stores all its files
1655 (default: F<~/.staticperl>).
1656
1657 =item C<PREFIX>
1658
1659 The prefix where perl get's installed (default: F<$STATICPERL/perl>),
1660 i.e. where the F<bin> and F<lib> subdirectories will end up.
1661
1662 =item C<PERL_MM_USE_DEFAULT>, C<EV_EXTRA_DEFS>, others
1663
1664 Usually set to C<1> to make modules "less inquisitive" during their
1665 installation, you can set any environment variable you want - some modules
1666 (such as L<Coro> or L<EV>) use environment variables for further tweaking.
1667
1668 =item C<EXTRA_MODULES>
1669
1670 Additional modules installed during F<staticperl install>. Here you can
1671 set which modules you want have to installed from CPAN.
1672
1673 Example: I really really need EV, AnyEvent, Coro and IO::AIO.
1674
1675 EXTRA_MODULES="EV AnyEvent Coro IO::AIO"
1676
1677 Note that you cna also use a C<postinstall> hook to achieve this, and
1678 more.
1679
1680 =back
1681
1682 =head4 Variables you I<probably do not want> to override
1683
1684 =over 4
1685
1686 =item C<MKBUNDLE>
1687
1688 Where F<staticperl> writes the C<mkbundle> command to
1689 (default: F<$STATICPERL/mkbundle>).
1690
1691 =item C<STATICPERL_MODULES>
1692
1693 Additional modules needed by C<mkbundle> - should therefore not be changed
1694 unless you know what you are doing.
1695
1696 =back
1697
1698 =head3 OVERRIDABLE HOOKS
1699
1700 In addition to environment variables, it is possible to provide some
1701 shell functions that are called at specific times. To provide your own
1702 commands, justd efine the corresponding function.
1703
1704 Example: install extra modules from CPAN and from some directories
1705 at F<staticperl install> time.
1706
1707 postinstall() {
1708 rm -rf lib/threads.* # weg mit Schaden
1709 instcpan IO::AIO EV
1710 instsrc ~/src/AnyEvent
1711 instsrc ~/src/XML-Sablotron-1.0100001
1712 instcpan AnyEvent::HTTPD
1713 }
1714
1715 =over 4
1716
1717 =item postconfigure
1718
1719 Called after configuring, but before building perl. Current working
1720 directory is the perl source directory.
1721
1722 Could be used to tailor/patch config.sh (followed by F<./Configure -S>) or
1723 do any other modifications.
1724
1725 =item postbuild
1726
1727 Called after building, but before installing perl. Current working
1728 directory is the perl source directory.
1729
1730 I have no clue what this could be used for - tell me.
1731
1732 =item postinstall
1733
1734 Called after perl and any extra modules have been installed in C<$PREFIX>,
1735 but before setting the "installation O.K." flag.
1736
1737 The current working directory is C<$PREFIX>, but maybe you should not rely
1738 on that.
1739
1740 This hook is most useful to customise the installation, by deleting files,
1741 or installing extra modules using the C<instcpan> or C<instsrc> functions.
1742
1743 The script must return with a zero exit status, or the installation will
1744 fail.
1745
1746 =back
1747
1748 =head1 AUTHOR
1749
1750 Marc Lehmann <schmorp@schmorp.de>
1751 http://software.schmorp.de/pkg/staticperl.html
1752