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

# User Rev Content
1 root 1.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 root 1.2 STATICPERL_MODULES="common::sense Pod::Strip PPI::XS Pod::Usage"
45    
46     # which extra modules you might want to install
47     EXTRA_MODULES=""
48 root 1.1
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 root 1.2 -Dprivlib="$PREFIX/lib" \
203     -Darchlib="$PREFIX/lib" \
204 root 1.1 -Uusevendorprefix \
205 root 1.2 -Dsitelib="$PREFIX/lib" \
206     -Dsitearch="$PREFIX/lib" \
207 root 1.1 -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 root 1.2 rcd "$PREFIX"
261    
262 root 1.1 # 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 root 1.2 # try to trick CPAN into avoiding ~/.cpan completely
276     echo 1 >"$PREFIX/lib/CPAN/MyConfig.pm"
277    
278 root 1.1 "$PREFIX"/bin/perl -MCPAN -e '
279     CPAN::Shell->o (conf => urllist => push => "'"$CPAN"'");
280 root 1.2 CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
281 root 1.1 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 root 1.2 instcpan $STATICPERL_MODULES
295     [ $EXTRA_MODULES ] && instcpan $EXTRA_MODULES
296 root 1.1
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 root 1.2 $cmd =~ s/^-+//;
593 root 1.1
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 root 1.2 "eval|e=s" => sub { trace_eval $_[1] },
625 root 1.1 "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 root 1.2 can run the script manually as well (by default it is written to
1412 root 1.1 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 root 1.2 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 root 1.1
1453 root 1.2 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 root 1.1
1691 root 1.2 =item C<STATICPERL_MODULES>
1692 root 1.1
1693 root 1.2 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 root 1.1
1746 root 1.2 =back
1747 root 1.1
1748     =head1 AUTHOR
1749    
1750     Marc Lehmann <schmorp@schmorp.de>
1751     http://software.schmorp.de/pkg/staticperl.html
1752