ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/App-Staticperl/bin/staticperl
Revision: 1.4
Committed: Mon Dec 6 21:10:41 2010 UTC (15 years, 9 months ago) by root
Branch: MAIN
Changes since 1.3: +42 -37 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.4 # trick CPAN into avoiding ~/.cpan completely
276 root 1.2 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 root 1.3 $_[0] =~ /^(.*)(?:\s+(\S+))$/
577 root 1.1 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 root 1.4 "<>" => sub { cmd_file $_[0] },
630 root 1.1 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 root 1.4 a perl interpreter in your applications. Single-file means that it is
1232     fully self-contained - no separate shared objects, no autoload fragments,
1233     no .pm or .pl files are needed. And when linking statically, you can
1234     create (or embed) a single file that contains perl interpreter, libc, all
1235     the modules you need and all the libraries you need.
1236 root 1.1
1237 root 1.4 With F<uClibc> and F<upx> on x86, you can create a single 500kb binary that
1238 root 1.1 contains perl and 50 modules such as AnyEvent, EV, IO::AIO, Coro and so
1239     on. Or any other choice of modules.
1240    
1241 root 1.4 The created files do not need write access to the file system (like PAR
1242 root 1.1 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 root 1.4 PAR tries to be maintenance and hassle-free - it tries to include more
1271     files than necessary to make sure everything works out of the box. The
1272     extra files (such as the unicode database) can take substantial amounts of
1273     memory and file size.
1274 root 1.1
1275     With F<staticperl>, the burden is mostly with the developer - only direct
1276     compile-time dependencies and L<AutoLoader> are handled automatically.
1277     This means the modules to include often need to be tweaked manually.
1278    
1279     =item * PAR works out of the box, F<staticperl> does not.
1280    
1281     Maintaining your own custom perl build can be a pain in the ass, and while
1282     F<staticperl> tries to make this easy, it still requires a custom perl
1283     build and possibly fiddling with some modules. PAR is likely to produce
1284     results faster.
1285    
1286     =back
1287    
1288     =head1 HOW DOES IT WORK?
1289    
1290     Simple: F<staticperl> downloads, compile and installs a perl version of
1291     your choice in F<~/.staticperl>. You can add extra modules either by
1292     letting F<staticperl> install them for you automatically, or by using CPAN
1293     and doing it interactively. This usually takes 5-10 minutes, depending on
1294 root 1.4 the speed of your computer and your internet connection.
1295 root 1.1
1296     It is possible to do program development at this stage, too.
1297    
1298     Afterwards, you create a list of files and modules you want to include,
1299 root 1.4 and then either build a new perl binary (that acts just like a normal perl
1300 root 1.1 except everything is compiled in), or you create bundle files (basically C
1301     sources you can use to embed all files into your project).
1302    
1303     This step is very fast (a few seconds if PPI is not used for stripping,
1304     more seconds otherwise, as PPI is very slow), and can be tweaked and
1305     repeated as often as necessary.
1306    
1307     =head1 THE F<STATICPERL> SCRIPT
1308    
1309     This module installs a script called F<staticperl> into your perl
1310     binary directory. The script is fully self-contained, and can be used
1311     without perl (for example, in an uClibc chroot environment). In fact,
1312     it can be extracted from the C<App::Staticperl> distribution tarball as
1313     F<bin/staticperl>, without any installation.
1314    
1315     F<staticperl> interprets the first argument as a command to execute,
1316     optionally followed by any parameters.
1317    
1318     There are two command categories: the "phase 1" commands which deal with
1319     installing perl and perl modules, and the "phase 2" commands, which deal
1320     with creating binaries and bundle files.
1321    
1322     =head2 PHASE 1 COMMANDS: INSTALLING PERL
1323    
1324     The most important command is F<install>, which does basically
1325     everything. The default is to download and install perl 5.12.2 and a few
1326     modules required by F<staticperl> itself, but all this can (and should) be
1327     changed - see L<CONFIGURATION>, below.
1328    
1329     The command
1330    
1331     staticperl install
1332    
1333     Is normally all you need: It installs the perl interpreter in
1334     F<~/.staticperl/perl>. It downloads, configures, builds and installs the
1335     perl interpreter if required.
1336    
1337     Most of the following commands simply run one or more steps of this
1338     sequence.
1339    
1340 root 1.4 To force recompilation or reinstallation, you need to run F<staticperl
1341 root 1.1 distclean> first.
1342    
1343     =over 4
1344    
1345     =item F<staticperl fetch>
1346    
1347     Runs only the download and unpack phase, unless this has already happened.
1348    
1349     =item F<staticperl configure>
1350    
1351     Configures the unpacked perl sources, potentially after downloading them first.
1352    
1353     =item F<staticperl build>
1354    
1355     Builds the configured perl sources, potentially after automatically
1356     configuring them.
1357    
1358     =item F<staticperl install>
1359    
1360 root 1.4 Wipes the perl installation directory (usually F<~/.staticperl/perl>) and
1361     installs the perl distribution, potentially after building it first.
1362 root 1.1
1363     =item F<staticperl cpan> [args...]
1364    
1365 root 1.4 Starts an interactive CPAN shell that you can use to install further
1366     modules. Installs the perl first if necessary, but apart from that,
1367 root 1.1 no magic is involved: you could just as well run it manually via
1368     F<~/.staticperl/perl/bin/cpan>.
1369    
1370     Any additional arguments are simply passed to the F<cpan> command.
1371    
1372     =item F<staticperl instcpan> module...
1373    
1374     Tries to install all the modules given and their dependencies, using CPAN.
1375    
1376     Example:
1377    
1378     staticperl instcpan EV AnyEvent::HTTPD Coro
1379    
1380     =item F<staticperl instsrc> directory...
1381    
1382     In the unlikely case that you have unpacked perl modules around and want
1383 root 1.4 to install from these instead of from CPAN, you can do this using this
1384 root 1.1 command by specifying all the directories with modules in them that you
1385     want to have built.
1386    
1387     =item F<staticperl clean>
1388    
1389     Runs F<make distclean> in the perl source directory (and potentially
1390     cleans up other intermediate files). This can be used to clean up
1391     intermediate files without removing the installed perl interpreter.
1392    
1393     =item F<staticperl distclean>
1394    
1395     This wipes your complete F<~/.staticperl> directory. Be careful with this,
1396     it nukes your perl download, perl sources, perl distribution and any
1397     installed modules. It is useful if you wish to start over "from scratch"
1398     or when you want to uninstall F<staticperl>.
1399    
1400     =back
1401    
1402     =head2 PHASE 2 COMMANDS: BUILDING PERL BUNDLES
1403    
1404     Building (linking) a new F<perl> binary is handled by a separate
1405     script. To make it easy to use F<staticperl> from a F<chroot>, the script
1406     is embedded into F<staticperl>, which will write it out and call for you
1407     with any arguments you pass:
1408    
1409     staticperl mkbundle mkbundle-args...
1410    
1411     In the oh so unlikely case of something not working here, you
1412 root 1.2 can run the script manually as well (by default it is written to
1413 root 1.1 F<~/.staticperl/mkbundle>).
1414    
1415     F<mkbundle> is a more conventional command and expect the argument
1416 root 1.4 syntax commonly used on UNIX clones. For example, this command builds
1417 root 1.1 a new F<perl> binary and includes F<Config.pm> (for F<perl -V>),
1418     F<AnyEvent::HTTPD>, F<URI> and a custom F<httpd> script (from F<eg/httpd>
1419     in this distribution):
1420    
1421     # first make sure we have perl and the required modules
1422     staticperl instcpan AnyEvent::HTTPD
1423    
1424     # now build the perl
1425     staticperl mkperl -M'"Config_heavy.pl"' -MAnyEvent::Impl::Perl \
1426     -MAnyEvent::HTTPD -MURI::http \
1427     --add 'eg/httpd httpd.pm'
1428    
1429     # finally, invoke it
1430     ./perl -Mhttpd
1431    
1432 root 1.2 As you can see, things are not quite as trivial: the L<Config> module has
1433     a hidden dependency which is not even a perl module (F<Config_heavy.pl>),
1434     L<AnyEvent> needs at least one event loop backend that we have to
1435 root 1.4 specify manually (here L<AnyEvent::Impl::Perl>), and the F<URI> module
1436 root 1.2 (required by L<AnyEvent::HTTPD>) implements various URI schemes as extra
1437     modules - since L<AnyEvent::HTTPD> only needs C<http> URIs, we only need
1438 root 1.4 to include that module. I found out about these dependencies by carefully
1439     watching any error messages about missing modules...
1440 root 1.2
1441     =head3 OPTION PROCESSING
1442    
1443 root 1.4 All options can be given as arguments on the command line (typically
1444     using long (e.g. C<--verbose>) or short option (e.g. C<-v>) style). Since
1445     specifying a lot of modules can make the command line very cumbersome,
1446 root 1.2 you can put all long options into a "bundle specification file" (with or
1447     without C<--> prefix) and specify this bundle file instead.
1448    
1449     For example, the command given earlier could also look like this:
1450    
1451     staticperl mkperl httpd.bundle
1452    
1453     And all options could be in F<httpd.bundle>:
1454 root 1.1
1455 root 1.2 use "Config_heavy.pl"
1456     use AnyEvent::Impl::Perl
1457     use AnyEvent::HTTPD
1458     use URI::http
1459     add eg/httpd httpd.pm
1460    
1461     All options that specify modules or files to be added are processed in the
1462 root 1.4 order given on the command line (that affects the C<--use> and C<--eval>
1463 root 1.2 options at the moment).
1464    
1465     =head3 MKBUNDLE OPTIONS
1466    
1467     =over 4
1468    
1469     =item --verbose | -v
1470    
1471     Increases the verbosity level by one (the default is C<1>).
1472    
1473     =item --quiet | -q
1474    
1475     Decreases the verbosity level by one.
1476    
1477     =item --strip none|pod|ppi
1478    
1479     Specify the stripping method applied to reduce the file of the perl
1480     sources included.
1481    
1482     The default is C<pod>, which uses the L<Pod::Strip> module to remove all
1483 root 1.4 pod documentation, which is very fast and reduces file size a lot.
1484 root 1.2
1485     The C<ppi> method uses L<PPI> to parse and condense the perl sources. This
1486 root 1.4 saves a lot more than just L<Pod::Strip>, and is generally safer, but
1487     is also a lot slower, so is best used for production builds. Note that
1488     this method doesn't optimise for raw file size, but for best compression
1489     (that means that the uncompressed file size is a bit larger, but the files
1490     compress better, e.g. with F<upx>).
1491 root 1.2
1492     Last not least, in the unlikely case where C<pod> is too slow, or some
1493     module gets mistreated, you can specify C<none> to not mangle included
1494     perl sources in any way.
1495    
1496     =item --perl
1497    
1498     After writing out the bundle files, try to link a new perl interpreter. It
1499     will be called F<perl> and will be left in the current working
1500     directory. The bundle files will be removed.
1501    
1502 root 1.4 This switch is automatically used when F<staticperl> is invoked with the
1503 root 1.2 C<mkperl> command (instead of C<mkbundle>):
1504    
1505     # build a new ./perl with only common::sense in it - very small :)
1506     staticperl mkperl -Mcommon::sense
1507    
1508     =item --use module | -Mmodule
1509    
1510     Include the named module and all direct dependencies. This is done by
1511     C<require>'ing the module in a subprocess and tracing which other modules
1512     and files it actually loads. If the module uses L<AutoLoader>, then all
1513     splitfiles will be included as well.
1514    
1515     Example: include AnyEvent and AnyEvent::Impl::Perl.
1516    
1517     staticperl mkbundle --use AnyEvent --use AnyEvent::Impl::Perl
1518    
1519     Sometimes you want to load old-style "perl libraries" (F<.pl> files), or
1520     maybe other weirdly named files. To do that, you need to quote the name in
1521 root 1.4 single or double quotes. When given on the command line, you probably need
1522 root 1.2 to quote once more to avoid your shell interpreting it. Common cases that
1523     need this are F<Config_heavy.pl> and F<utf8_heavy.pl>.
1524    
1525     Example: include the required files for F<perl -V> to work in all its
1526     glory (F<Config.pm> is included automatically by this).
1527    
1528     # bourne shell
1529     staticperl mkbundle --use '"Config_heavy.pl"'
1530    
1531     # bundle specification file
1532     use "Config_heavy.pl"
1533    
1534     The C<-Mmodule> syntax is included as an alias that might be easier to
1535     remember than C<use>. Or maybe it confuses people. Time will tell. Or
1536     maybe not. Argh.
1537    
1538     =item --eval "perl code" | -e "perl code"
1539    
1540     Sometimes it is easier (or necessary) to specify dependencies using perl
1541     code, or maybe one of the modules you use need a special use statement. In
1542     that case, you can use C<eval> to execute some perl snippet or set some
1543     variables or whatever you need. All files C<require>'d or C<use>'d in the
1544     script are included in the final bundle.
1545    
1546     Keep in mind that F<mkbundle> will only C<require> the modules named
1547     by the C<--use> option, so do not expect the symbols from modules you
1548 root 1.4 C<--use>'d earlier on the command line to be available.
1549 root 1.2
1550     Example: force L<AnyEvent> to detect a backend and therefore include it
1551     in the final bundle.
1552    
1553     staticperl mkbundle --eval 'use AnyEvent; AnyEvent::detect'
1554    
1555     # or like this
1556     staticperl mkbundle -MAnyEvent --eval 'use AnyEvent; AnyEvent::detect'
1557    
1558     Example: use a separate "bootstrap" script that C<use>'s lots of modules
1559     and include this in the final bundle, to be executed automatically.
1560    
1561     staticperl mkbundle --eval 'do "bootstrap"' --boot bootstrap
1562    
1563     =item --boot filename
1564    
1565     Include the given file in the bundle and arrange for it to be executed
1566     (using a C<require>) before anything else when the new perl is
1567     initialised. This can be used to modify C<@INC> or anything else before
1568 root 1.4 the perl interpreter executes scripts given on the command line (or via
1569 root 1.2 C<-e>). This works even in an embedded interpreter.
1570    
1571     =item --add "file" | --add "file alias"
1572    
1573     Adds the given (perl) file into the bundle (and optionally call it
1574     "alias"). This is useful to include any custom files into the bundle.
1575    
1576     Example: embed the file F<httpd> as F<httpd.pm> when creating the bundle.
1577    
1578     staticperl mkperl --add "httpd httpd.pm"
1579    
1580     It is also a great way to add any custom modules:
1581    
1582     # specification file
1583     add file1 myfiles/file1
1584     add file2 myfiles/file2
1585     add file3 myfiles/file3
1586    
1587     =item --static
1588    
1589     When C<--perl> is also given, link statically instead of dynamically. The
1590     default is to link the new perl interpreter fully dynamic (that means all
1591     perl modules are linked statically, but all external libraries are still
1592     referenced dynamically).
1593    
1594     Keep in mind that Solaris doesn't support static linking at all, and
1595     systems based on GNU libc don't really support it in a usable fashion
1596     either. Try uClibc if you want to create fully statically linked
1597     executables, or try the C<--staticlibs> option to link only some libraries
1598     statically.
1599    
1600     =item any other argument
1601    
1602     Any other argument is interpreted as a bundle specification file, which
1603     supports most long options (without extra quoting), one option per line.
1604    
1605     =back
1606    
1607     =head2 F<STATCPERL> CONFIGURATION AND HOOKS
1608    
1609     During (each) startup, F<staticperl> tries to source the following shell
1610     files in order:
1611    
1612     /etc/staticperlrc
1613     ~/.staticperlrc
1614     $STATICPERL/rc
1615    
1616     They can be used to override shell variables, or define functions to be
1617     called at specific phases.
1618    
1619     Note that the last file is erased during F<staticperl distclean>, so
1620     generally should not be used.
1621    
1622     =head3 CONFIGURATION VARIABLES
1623    
1624     =head4 Variables you I<should> override
1625    
1626     =over 4
1627    
1628     =item C<EMAIL>
1629    
1630     The e-mail address of the person who built this binary. Has no good
1631     default, so should be specified by you.
1632    
1633     =back
1634    
1635     =head4 Variables you I<might want> to override
1636    
1637     =over 4
1638    
1639     =item C<PERLVER>
1640    
1641     The perl version to install - default is currently C<5.12.2>, but C<5.8.9>
1642     is also a good choice (5.8.9 is much smaller than 5.12.2, while 5.10.1 is
1643     about as big as 5.12.2).
1644    
1645     =item C<CPAN>
1646    
1647     The URL of the CPAN mirror to use (e.g. L<http://mirror.netcologne.de/cpan/>).
1648    
1649     =item C<PERL_CPPFLAGS>, C<PERL_OPTIMIZE>, C<PERL_LDFLAGS>, C<PERL_LIBS>
1650    
1651     These flags are passed to perl's F<Configure> script, and are generally
1652     optimised for small size (at the cost of performance). Since they also
1653     contain subtle workarounds around various build issues, changing these
1654     usually requires understanding their default values - best look at the top
1655     of the F<staticperl> script for more info on these.
1656    
1657     =item C<STATICPERL>
1658    
1659     The directory where staticperl stores all its files
1660     (default: F<~/.staticperl>).
1661    
1662     =item C<PREFIX>
1663    
1664 root 1.4 The prefix where perl gets installed (default: F<$STATICPERL/perl>),
1665 root 1.2 i.e. where the F<bin> and F<lib> subdirectories will end up.
1666    
1667     =item C<PERL_MM_USE_DEFAULT>, C<EV_EXTRA_DEFS>, others
1668    
1669     Usually set to C<1> to make modules "less inquisitive" during their
1670     installation, you can set any environment variable you want - some modules
1671     (such as L<Coro> or L<EV>) use environment variables for further tweaking.
1672    
1673     =item C<EXTRA_MODULES>
1674    
1675     Additional modules installed during F<staticperl install>. Here you can
1676     set which modules you want have to installed from CPAN.
1677    
1678     Example: I really really need EV, AnyEvent, Coro and IO::AIO.
1679    
1680     EXTRA_MODULES="EV AnyEvent Coro IO::AIO"
1681    
1682 root 1.4 Note that you can also use a C<postinstall> hook to achieve this, and
1683 root 1.2 more.
1684    
1685     =back
1686    
1687     =head4 Variables you I<probably do not want> to override
1688    
1689     =over 4
1690    
1691     =item C<MKBUNDLE>
1692    
1693     Where F<staticperl> writes the C<mkbundle> command to
1694     (default: F<$STATICPERL/mkbundle>).
1695 root 1.1
1696 root 1.2 =item C<STATICPERL_MODULES>
1697 root 1.1
1698 root 1.2 Additional modules needed by C<mkbundle> - should therefore not be changed
1699     unless you know what you are doing.
1700    
1701     =back
1702    
1703     =head3 OVERRIDABLE HOOKS
1704    
1705     In addition to environment variables, it is possible to provide some
1706     shell functions that are called at specific times. To provide your own
1707 root 1.4 commands, just define the corresponding function.
1708 root 1.2
1709     Example: install extra modules from CPAN and from some directories
1710     at F<staticperl install> time.
1711    
1712     postinstall() {
1713     rm -rf lib/threads.* # weg mit Schaden
1714     instcpan IO::AIO EV
1715     instsrc ~/src/AnyEvent
1716     instsrc ~/src/XML-Sablotron-1.0100001
1717     instcpan AnyEvent::HTTPD
1718     }
1719    
1720     =over 4
1721    
1722     =item postconfigure
1723    
1724     Called after configuring, but before building perl. Current working
1725     directory is the perl source directory.
1726    
1727     Could be used to tailor/patch config.sh (followed by F<./Configure -S>) or
1728     do any other modifications.
1729    
1730     =item postbuild
1731    
1732     Called after building, but before installing perl. Current working
1733     directory is the perl source directory.
1734    
1735     I have no clue what this could be used for - tell me.
1736    
1737     =item postinstall
1738    
1739     Called after perl and any extra modules have been installed in C<$PREFIX>,
1740     but before setting the "installation O.K." flag.
1741    
1742     The current working directory is C<$PREFIX>, but maybe you should not rely
1743     on that.
1744    
1745     This hook is most useful to customise the installation, by deleting files,
1746     or installing extra modules using the C<instcpan> or C<instsrc> functions.
1747    
1748     The script must return with a zero exit status, or the installation will
1749     fail.
1750 root 1.1
1751 root 1.2 =back
1752 root 1.1
1753     =head1 AUTHOR
1754    
1755     Marc Lehmann <schmorp@schmorp.de>
1756     http://software.schmorp.de/pkg/staticperl.html
1757