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