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