ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/App-Staticperl/bin/staticperl
Revision: 1.21
Committed: Sat Dec 11 15:51:39 2010 UTC (15 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-0_911
Changes since 1.20: +3 -4 lines
Log Message:
0.911

File Contents

# User Rev Content
1 root 1.1 #!/bin/sh
2    
3     #############################################################################
4     # configuration to fill in
5    
6     STATICPERL=~/.staticperl
7 root 1.19 CPAN=http://mirror.netcologne.de/cpan # which mirror to use
8 root 1.1 EMAIL="read the documentation <rtfm@example.org>"
9    
10     # perl build variables
11 root 1.10 PERL_VERSION=5.12.2 # 5.8.9 is also a good choice
12 root 1.8 PERL_CONFIGURE="" # additional Configure arguments
13 root 1.1 PERL_CPPFLAGS="-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=65536 -D_GNU_SOURCE -DNDEBUG -USITELIB_EXP -USITEARCHEXP -UARCHLIB_EXP"
14     PERL_OPTIMIZE="-Os -ffunction-sections -fdata-sections -finline-limit=8 -ffast-math"
15    
16     ARCH="$(uname -m)"
17    
18     case "$ARCH" in
19     i*86 | x86_64 | amd64 )
20     PERL_OPTIMIZE="$PERL_OPTIMIZE -mpush-args -mno-inline-stringops-dynamically -mno-align-stringops -mno-ieee-fp" # x86/amd64
21     case "$ARCH" in
22     i*86 )
23     PERL_OPTIMIZE="$PERL_OPTIMIZE -fomit-frame-pointer -march=pentium3 -mtune=i386" # x86 only
24     ;;
25     esac
26     ;;
27     esac
28    
29     # -Wl,--gc-sections makes it impossible to check for undefined references
30     # for some reason so we need to patch away the "-no" after Configure and before make :/
31 root 1.21 # --allow-multiple-definition exists to work around uclibc's pthread static linking bug
32     PERL_LDFLAGS="-Wl,--no-gc-sections -Wl,--allow-multiple-definition"
33 root 1.1 PERL_LIBS="-lm -lcrypt" # perl loves to add lotsa crap itself
34    
35     # some configuration options for modules
36     export PERL_MM_USE_DEFAULT=1
37     #export CORO_INTERFACE=p # needed without nptl on x86, due to bugs in linuxthreads - very slow
38     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'
39    
40     # which extra modules to install by default from CPAN that are
41     # required by mkbundle
42 root 1.2 STATICPERL_MODULES="common::sense Pod::Strip PPI::XS Pod::Usage"
43    
44     # which extra modules you might want to install
45     EXTRA_MODULES=""
46 root 1.1
47     # overridable functions
48 root 1.11 preconfigure() { : ; }
49 root 1.1 postconfigure() { : ; }
50     postbuild() { : ; }
51     postinstall() { : ; }
52    
53     # now source user config, if any
54 root 1.19 if [ "$STATICPERLRC" ]; then
55     . "$STATICPERLRC"
56     else
57     [ -r /etc/staticperlrc ] && . /etc/staticperlrc
58     [ -r ~/.staticperlrc ] && . ~/.staticperlrc
59     [ -r "$STATICPERL/rc" ] && . "$STATICPERL/rc"
60     fi
61 root 1.1
62     #############################################################################
63     # support
64    
65 root 1.19 MKBUNDLE="${MKBUNDLE:=$STATICPERL/mkbundle}"
66     PERL_PREFIX="${PERL_PREFIX:=$STATICPERL/perl}" # where the perl gets installed
67    
68 root 1.18 unset PERL5OPT PERL5LIB PERLLIB PERL_UNICODE PERLIO_DEBUG
69     export LC_ALL=C # just to be on the safe side
70    
71 root 1.1 # set version in a way that Makefile.PL can extract
72     VERSION=VERSION; eval \
73 root 1.21 $VERSION=0.911
74 root 1.1
75     BZ2=bz2
76     BZIP2=bzip2
77    
78     fatal() {
79     printf -- "\nFATAL: %s\n\n" "$*" >&2
80     exit 1
81     }
82    
83     verbose() {
84     printf -- "%s\n" "$*"
85     }
86    
87     verblock() {
88     verbose
89     verbose "***"
90     while read line; do
91     verbose "*** $line"
92     done
93     verbose "***"
94     verbose
95     }
96    
97     rcd() {
98     cd "$1" || fatal "$1: cannot enter"
99     }
100    
101     trace() {
102     prefix="$1"; shift
103     # "$@" 2>&1 | while read line; do
104     # echo "$prefix: $line"
105     # done
106     "$@"
107     }
108    
109     trap wait 0
110    
111     #############################################################################
112     # clean
113    
114     distclean() {
115     verblock <<EOF
116 root 1.19 deleting everything installed by this script (rm -rf $STATICPERL)
117 root 1.1 EOF
118    
119     rm -rf "$STATICPERL"
120     }
121    
122     #############################################################################
123     # download/configure/compile/install perl
124    
125     clean() {
126 root 1.11 rm -rf "$STATICPERL/src/perl-$PERL_VERSION"
127 root 1.1 }
128    
129     fetch() {
130     rcd "$STATICPERL"
131    
132     mkdir -p src
133     rcd src
134    
135 root 1.10 if ! [ -d "perl-$PERL_VERSION" ]; then
136     if ! [ -e "perl-$PERL_VERSION.tar.$BZ2" ]; then
137 root 1.1
138 root 1.10 URL="$CPAN/src/5.0/perl-$PERL_VERSION.tar.$BZ2"
139 root 1.1
140     verblock <<EOF
141     downloading perl
142     to manually download perl yourself, place
143 root 1.10 perl-$PERL_VERSION.tar.$BZ2 in $STATICPERL
144 root 1.1 trying $URL
145     EOF
146    
147 root 1.10 rm -f perl-$PERL_VERSION.tar.$BZ2~ # just to be on the safe side
148     wget -O perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
149     || curl >perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
150     || fatal "$URL: unable to download"
151     mv perl-$PERL_VERSION.tar.$BZ2~ perl-$PERL_VERSION.tar.$BZ2
152 root 1.1 fi
153    
154     verblock <<EOF
155     unpacking perl
156     EOF
157    
158     mkdir -p unpack
159 root 1.19 $BZIP2 -d <perl-$PERL_VERSION.tar.bz2 | tar xfC - unpack \
160 root 1.10 || fatal "perl-$PERL_VERSION.tar.bz2: error during unpacking"
161 root 1.12 chmod -R u+w unpack/perl-$PERL_VERSION
162 root 1.10 mv unpack/perl-$PERL_VERSION perl-$PERL_VERSION
163 root 1.1 rmdir -p unpack
164     fi
165     }
166    
167     # similar to GNU-sed -i or perl -pi
168     sedreplace() {
169     sed -e "$1" <"$2" > "$2~" || fatal "error while running sed"
170     mv "$2~" "$2"
171     }
172    
173     configure() {
174     fetch
175    
176 root 1.10 rcd "$STATICPERL/src/perl-$PERL_VERSION"
177 root 1.1
178     [ -e staticstamp.configure ] && return
179    
180     verblock <<EOF
181 root 1.10 configuring $STATICPERL/src/perl-$PERL_VERSION
182 root 1.1 EOF
183    
184 root 1.12 rm -f "$PERL_PREFIX/staticstamp.install"
185 root 1.1
186 root 1.12 make distclean >/dev/null 2>&1
187 root 1.1
188     # I hate them
189     grep -q -- -fstack-protector Configure && \
190     sedreplace 's/-fstack-protector/-fno-stack-protector/g' Configure
191    
192 root 1.11 preconfigure
193    
194 root 1.1 # trace configure \
195     sh Configure -Duselargefiles \
196     -Uuse64bitint \
197     -Dusemymalloc=n \
198     -Uusedl \
199     -Uusethreads \
200     -Uuseithreads \
201     -Uusemultiplicity \
202     -Duseperlio \
203     -Uusesfio \
204     -Uuseshrplib \
205     -Dcppflags="$PERL_CPPFLAGS" \
206     -Dccflags="-g2 -fno-strict-aliasing" \
207     -Doptimize="$PERL_OPTIMIZE" \
208     -Dldflags="$PERL_LDFLAGS" \
209     -Dlibs="$PERL_LIBS" \
210 root 1.10 -Dprefix="$PERL_PREFIX" \
211     -Dbin="$PERL_PREFIX/bin" \
212     -Dprivlib="$PERL_PREFIX/lib" \
213     -Darchlib="$PERL_PREFIX/lib" \
214 root 1.1 -Uusevendorprefix \
215 root 1.10 -Dsitelib="$PERL_PREFIX/lib" \
216     -Dsitearch="$PERL_PREFIX/lib" \
217 root 1.1 -Usitelibexp \
218     -Uman1dir \
219     -Uman3dir \
220     -Usiteman1dir \
221     -Usiteman3dir \
222     -Dpager=/usr/bin/less \
223     -Demail="$EMAIL" \
224     -Dcf_email="$EMAIL" \
225     -Dcf_by="$EMAIL" \
226 root 1.8 $PERL_CONFIGURE \
227 root 1.1 -dE || fatal "Configure failed"
228    
229     sedreplace '
230     s/-Wl,--no-gc-sections/-Wl,--gc-sections/g
231     s/ *-fno-stack-protector */ /g
232     ' config.sh
233    
234     sh Configure -S || fatal "Configure -S failed"
235    
236     postconfigure || fatal "postconfigure hook failed"
237    
238     touch staticstamp.configure
239     }
240    
241     build() {
242     configure
243    
244 root 1.10 rcd "$STATICPERL/src/perl-$PERL_VERSION"
245 root 1.1
246     verblock <<EOF
247 root 1.10 building $STATICPERL/src/perl-$PERL_VERSION
248 root 1.1 EOF
249    
250 root 1.10 rm -f "$PERL_PREFIX/staticstamp.install"
251 root 1.1
252     make || fatal "make: error while building perl"
253    
254     postbuild || fatal "postbuild hook failed"
255     }
256    
257     install() {
258 root 1.13 if ! [ -e "$PERL_PREFIX/staticstamp.install" ]; then
259     build
260 root 1.1
261 root 1.13 verblock <<EOF
262 root 1.10 installing $STATICPERL/src/perl-$PERL_VERSION
263     to $PERL_PREFIX
264 root 1.1 EOF
265    
266 root 1.19 ln -sf "perl/bin/" "$STATICPERL/bin"
267     ln -sf "perl/lib/" "$STATICPERL/lib"
268    
269     ln -sf "$PERL_PREFIX" "$STATICPERL/perl" # might get overwritten
270     rm -rf "$PERL_PREFIX" # by this rm -rf
271    
272 root 1.13 make install || fatal "make install: error while installing"
273 root 1.1
274 root 1.13 rcd "$PERL_PREFIX"
275 root 1.2
276 root 1.13 # create a "make install" replacement for CPAN
277     cat >"$PERL_PREFIX"/bin/cpan-make-install <<EOF
278 root 1.14 make || exit
279    
280 root 1.1 if find blib/arch/auto -type f | grep -q -v .exists; then
281     echo Probably an XS module, rebuilding perl
282 root 1.14 if make perl; then
283     mv perl "$PERL_PREFIX"/bin/perl
284     make -f Makefile.aperl map_clean
285     else
286     make -f Makefile.aperl map_clean
287     exit 1
288     fi
289 root 1.1 fi
290 root 1.14
291     make install UNINST=1
292 root 1.1 EOF
293 root 1.13 chmod 755 "$PERL_PREFIX"/bin/cpan-make-install
294    
295     # trick CPAN into avoiding ~/.cpan completely
296     echo 1 >"$PERL_PREFIX/lib/CPAN/MyConfig.pm"
297 root 1.1
298 root 1.13 "$PERL_PREFIX"/bin/perl -MCPAN -e '
299     CPAN::Shell->o (conf => urllist => push => "'"$CPAN"'");
300     CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
301     CPAN::Shell->o (conf => q<init>);
302     CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
303     CPAN::Shell->o (conf => q<build_dir>, "'"$STATICPERL"'/cpan/build");
304     CPAN::Shell->o (conf => q<prefs_dir>, "'"$STATICPERL"'/cpan/prefs");
305     CPAN::Shell->o (conf => q<histfile> , "'"$STATICPERL"'/cpan/histfile");
306     CPAN::Shell->o (conf => q<keep_source_where>, "'"$STATICPERL"'/cpan/sources");
307     CPAN::Shell->o (conf => q<make_install_make_command>, "'"$PERL_PREFIX"'/bin/cpan-make-install");
308     CPAN::Shell->o (conf => q<prerequisites_policy>, q<follow>);
309     CPAN::Shell->o (conf => q<build_requires_install_policy>, q<no>);
310     CPAN::Shell->o (conf => q<commit>);
311     ' || fatal "error while initialising CPAN"
312 root 1.2
313 root 1.13 touch "$PERL_PREFIX/staticstamp.install"
314     fi
315    
316 root 1.14 if ! [ -e "$PERL_PREFIX/staticstamp.postinstall" ]; then
317 root 1.13 NOCHECK_INSTALL=+
318     instcpan $STATICPERL_MODULES
319     [ $EXTRA_MODULES ] && instcpan $EXTRA_MODULES
320 root 1.1
321 root 1.13 postinstall || fatal "postinstall hook failed"
322 root 1.1
323 root 1.13 touch "$PERL_PREFIX/staticstamp.postinstall"
324     fi
325 root 1.1 }
326    
327     #############################################################################
328     # install a module from CPAN
329    
330     instcpan() {
331     [ $NOCHECK_INSTALL ] || install
332    
333     verblock <<EOF
334     installing modules from CPAN
335     $@
336     EOF
337    
338     for mod in "$@"; do
339 root 1.10 "$PERL_PREFIX"/bin/perl -MCPAN -e 'notest install => "'"$mod"'"' \
340 root 1.1 || fatal "$mod: unable to install from CPAN"
341     done
342     rm -rf "$STATICPERL/build"
343     }
344    
345     #############################################################################
346     # install a module from unpacked sources
347    
348     instsrc() {
349     [ $NOCHECK_INSTALL ] || install
350    
351     verblock <<EOF
352     installing modules from source
353     $@
354     EOF
355    
356     for mod in "$@"; do
357     echo
358     echo $mod
359     (
360     rcd $mod
361     make -f Makefile.aperl map_clean >/dev/null 2>&1
362     make distclean >/dev/null 2>&1
363 root 1.10 "$PERL_PREFIX"/bin/perl Makefile.PL || fatal "$mod: error running Makefile.PL"
364 root 1.1 make || fatal "$mod: error building module"
365 root 1.10 "$PERL_PREFIX"/bin/cpan-make-install || fatal "$mod: error installing module"
366 root 1.1 make distclean >/dev/null 2>&1
367     exit 0
368     ) || exit $?
369     done
370     }
371    
372     #############################################################################
373     # main
374    
375     podusage() {
376     echo
377 root 1.10 if [ -e "$PERL_PREFIX/bin/perl" ]; then
378     "$PERL_PREFIX/bin/perl" -MPod::Usage -e \
379 root 1.1 'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
380     2>/dev/null && exit
381     fi
382     # try whatever perl we can find
383     perl -MPod::Usage -e \
384     'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
385     2>/dev/null && exit
386    
387     fatal "displaying documentation requires a working perl - try '$0 install' first"
388     }
389    
390     usage() {
391     podusage 0
392     }
393    
394     catmkbundle() {
395     {
396     read dummy
397 root 1.10 echo "#!$PERL_PREFIX/bin/perl"
398 root 1.1 cat
399     } <<'MKBUNDLE'
400     #!/opt/bin/perl
401    
402     #############################################################################
403     # cannot load modules till after the tracer BEGIN block
404    
405     our $VERBOSE = 1;
406     our $STRIP = "pod"; # none, pod or ppi
407 root 1.18 our $UNISTRIP = 1; # always on, try to strip unicore swash data
408 root 1.1 our $PERL = 0;
409 root 1.17 our $APP;
410 root 1.1 our $VERIFY = 0;
411     our $STATIC = 0;
412 root 1.19 our $PACKLIST = 0;
413 root 1.1
414 root 1.18 our $OPTIMISE_SIZE = 0; # optimise for raw file size instead of for compression?
415    
416     our $CACHE;
417     our $CACHEVER = 1; # do not change unless you know what you are doing
418    
419 root 1.1 my $PREFIX = "bundle";
420     my $PACKAGE = "static";
421    
422     my %pm;
423 root 1.8 my %pmbin;
424 root 1.1 my @libs;
425     my @static_ext;
426     my $extralibs;
427 root 1.18 my @staticlibs;
428     my @incext;
429 root 1.1
430     @ARGV
431     or die "$0: use 'staticperl help' (or read the sources of staticperl)\n";
432    
433 root 1.18 # remove "." from @INC - staticperl.sh does it for us, but be on the safe side
434     BEGIN { @INC = grep !/^\.$/, @INC }
435    
436 root 1.1 $|=1;
437    
438     our ($TRACER_W, $TRACER_R);
439    
440 root 1.19 sub find_incdir($) {
441 root 1.1 for (@INC) {
442     next if ref;
443     return $_ if -e "$_/$_[0]";
444     }
445    
446     undef
447     }
448    
449 root 1.19 sub find_inc($) {
450     my $dir = find_incdir $_[0];
451    
452     return "$dir/$_[0]"
453     if defined $dir;
454    
455     undef
456     }
457    
458 root 1.1 BEGIN {
459     # create a loader process to detect @INC requests before we load any modules
460     my ($W_TRACER, $R_TRACER); # used by tracer
461    
462     pipe $R_TRACER, $TRACER_W or die "pipe: $!";
463     pipe $TRACER_R, $W_TRACER or die "pipe: $!";
464    
465     unless (fork) {
466     close $TRACER_R;
467     close $TRACER_W;
468    
469     unshift @INC, sub {
470 root 1.19 my $dir = find_incdir $_[1]
471 root 1.1 or return;
472    
473     syswrite $W_TRACER, "-\n$dir\n$_[1]\n";
474    
475     open my $fh, "<:perlio", "$dir/$_[1]"
476     or warn "ERROR: $dir/$_[1]: $!\n";
477    
478     $fh
479     };
480    
481     while (<$R_TRACER>) {
482     if (/use (.*)$/) {
483     my $mod = $1;
484     eval "require $mod";
485     warn "ERROR: $@ (while loading '$mod')\n"
486     if $@;
487     } elsif (/eval (.*)$/) {
488     my $eval = $1;
489     eval $eval;
490     warn "ERROR: $@ (in '$eval')\n"
491     if $@;
492     }
493 root 1.19
494     syswrite $W_TRACER, "\n";
495 root 1.1 }
496    
497     exit 0;
498     }
499     }
500    
501     # module loading is now safe
502 root 1.7
503 root 1.19 sub trace_parse {
504 root 1.1 for (;;) {
505     <$TRACER_R> =~ /^-$/ or last;
506     my $dir = <$TRACER_R>; chomp $dir;
507     my $name = <$TRACER_R>; chomp $name;
508    
509     $pm{$name} = "$dir/$name";
510 root 1.19
511     print "+ found potential dependency $name\n"
512     if $VERBOSE >= 3;
513 root 1.1 }
514     }
515    
516 root 1.19 sub trace_module {
517     print "tracing module $_[0]\n"
518     if $VERBOSE >= 2;
519    
520     syswrite $TRACER_W, "use $_[0]\n";
521     trace_parse;
522     }
523    
524 root 1.1 sub trace_eval {
525 root 1.19 print "tracing eval $_[0]\n"
526     if $VERBOSE >= 2;
527    
528 root 1.1 syswrite $TRACER_W, "eval $_[0]\n";
529 root 1.19 trace_parse;
530 root 1.1 }
531    
532     sub trace_finish {
533     close $TRACER_W;
534     close $TRACER_R;
535     }
536    
537     #############################################################################
538     # now we can use modules
539    
540     use common::sense;
541 root 1.18 use Config;
542 root 1.1 use Digest::MD5;
543    
544 root 1.18 sub cache($$$) {
545     my ($variant, $src, $filter) = @_;
546    
547 root 1.19 if (length $CACHE and 2048 <= length $src and defined $variant) {
548 root 1.18 my $file = "$CACHE/" . Digest::MD5::md5_hex "$CACHEVER\x00$variant\x00$src";
549    
550     if (open my $fh, "<:perlio", $file) {
551 root 1.19 print "using cache for $file\n"
552     if $VERBOSE >= 7;
553    
554 root 1.18 local $/;
555     return <$fh>;
556     }
557    
558     $src = $filter->($src);
559    
560 root 1.19 print "creating cache entry $file\n"
561     if $VERBOSE >= 8;
562    
563 root 1.18 if (open my $fh, ">:perlio", "$file~") {
564     if ((syswrite $fh, $src) == length $src) {
565     close $fh;
566     rename "$file~", $file;
567     }
568     }
569    
570     return $src;
571     }
572    
573     $filter->($src)
574     }
575    
576 root 1.1 sub dump_string {
577     my ($fh, $data) = @_;
578    
579     if (length $data) {
580     for (
581     my $ofs = 0;
582     length (my $substr = substr $data, $ofs, 80);
583     $ofs += 80
584     ) {
585     $substr =~ s/([^\x20-\x21\x23-\x5b\x5d-\x7e])/sprintf "\\%03o", ord $1/ge;
586     $substr =~ s/\?/\\?/g; # trigraphs...
587     print $fh " \"$substr\"\n";
588     }
589     } else {
590     print $fh " \"\"\n";
591     }
592     }
593    
594 root 1.18 #############################################################################
595    
596     sub glob2re {
597     for (quotemeta $_[0]) {
598     s/\\\*/\x00/g;
599     s/\x00\x00/.*/g;
600     s/\x00/[^\/]*/g;
601     s/\\\?/[^\/]/g;
602    
603     $_ = s/^\\\/// ? "^$_\$" : "(?:^|/)$_\$";
604    
605     s/(?: \[\^\/\] | \. ) \*\$$//x;
606    
607     return qr<$_>s
608     }
609     }
610    
611     our %INCSKIP = (
612     "unicore/TestProp.pl" => undef, # 3.5MB of insanity, apparently just some testcase
613     );
614    
615     sub get_dirtree {
616     my $root = shift;
617    
618     my @tree;
619     my $skip;
620    
621     my $scan; $scan = sub {
622     for (sort do {
623     opendir my $fh, $_[0]
624     or return;
625     readdir $fh
626     }) {
627     next if /^\./;
628    
629     my $path = "$_[0]/$_";
630    
631     if (-d "$path/.") {
632     $scan->($path);
633     } else {
634     next unless /\.(?:pm|pl)$/;
635    
636     $path = substr $path, $skip;
637     push @tree, $path
638     unless exists $INCSKIP{$path};
639     }
640     }
641     };
642    
643     $root =~ s/\/$//;
644     $skip = 1 + length $root;
645     $scan->($root);
646    
647     \@tree
648     }
649    
650     my $inctrees;
651    
652     sub get_inctrees {
653     unless ($inctrees) {
654     my %inctree;
655     $inctree{$_} ||= [$_, get_dirtree $_] # entries in @INC are often duplicates
656     for @INC;
657     $inctrees = [values %inctree];
658     }
659    
660     @$inctrees
661     }
662 root 1.1
663 root 1.18 #############################################################################
664 root 1.1
665     sub cmd_boot {
666     $pm{"//boot"} = $_[0];
667     }
668    
669     sub cmd_add {
670 root 1.3 $_[0] =~ /^(.*)(?:\s+(\S+))$/
671 root 1.1 or die "$_[0]: cannot parse";
672    
673     my $file = $1;
674     my $as = defined $2 ? $2 : "/$1";
675    
676     $pm{$as} = $file;
677 root 1.8 $pmbin{$as} = 1 if $_[1];
678 root 1.1 }
679    
680 root 1.18 sub cmd_staticlib {
681     push @staticlibs, $_
682     for split /\s+/, $_[0];
683     }
684    
685     sub cmd_include {
686     push @incext, [$_[1], glob2re $_[0]];
687     }
688    
689     sub cmd_incglob {
690     my ($pattern) = @_;
691    
692     $pattern = glob2re $pattern;
693    
694     for (get_inctrees) {
695     my ($dir, $files) = @$_;
696    
697     $pm{$_} = "$dir/$_"
698     for grep /$pattern/, @$files;
699     }
700     }
701    
702 root 1.19 sub parse_argv;
703    
704 root 1.1 sub cmd_file {
705     open my $fh, "<", $_[0]
706     or die "$_[0]: $!\n";
707    
708 root 1.19 local @ARGV;
709    
710 root 1.1 while (<$fh>) {
711     chomp;
712 root 1.19 next unless /\S/;
713     next if /^\s*#/;
714    
715     s/^\s*-*/--/;
716 root 1.1 my ($cmd, $args) = split / /, $_, 2;
717    
718 root 1.19 push @ARGV, $cmd;
719     push @ARGV, $args if defined $args;
720 root 1.1 }
721 root 1.19
722     parse_argv;
723 root 1.1 }
724    
725     use Getopt::Long;
726    
727 root 1.19 sub parse_argv {
728     GetOptions
729     "strip=s" => \$STRIP,
730     "cache=s" => \$CACHE, # internal option
731     "verbose|v" => sub { ++$VERBOSE },
732     "quiet|q" => sub { --$VERBOSE },
733     "perl" => \$PERL,
734     "app=s" => \$APP,
735     "eval|e=s" => sub { trace_eval $_[1] },
736     "use|M=s" => sub { trace_module $_[1] },
737     "boot=s" => sub { cmd_boot $_[1] },
738     "add=s" => sub { cmd_add $_[1], 0 },
739     "addbin=s" => sub { cmd_add $_[1], 1 },
740     "incglob=s" => sub { cmd_incglob $_[1] },
741     "include|i=s" => sub { cmd_include $_[1], 1 },
742     "exclude|x=s" => sub { cmd_include $_[1], 0 },
743     "static!" => \$STATIC,
744     "usepacklist!" => \$PACKLIST,
745     "staticlib=s" => sub { cmd_staticlib $_[1] },
746     "<>" => sub { cmd_file $_[0] },
747     or exit 1;
748     }
749    
750 root 1.1 Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case");
751    
752 root 1.19 parse_argv;
753 root 1.1
754 root 1.17 die "cannot specify both --app and --perl\n"
755     if $PERL and defined $APP;
756    
757 root 1.18 # required for @INC loading, unfortunately
758     trace_module "PerlIO::scalar";
759    
760     #############################################################################
761     # include/exclude apply
762    
763     {
764     my %pmi;
765    
766     for (@incext) {
767     my ($inc, $glob) = @$_;
768    
769     my @match = grep /$glob/, keys %pm;
770    
771     if ($inc) {
772     # include
773     @pmi{@match} = delete @pm{@match};
774 root 1.19
775     print "applying include $glob - protected ", (scalar @match), " files.\n"
776     if $VERBOSE >= 5;
777 root 1.18 } else {
778     # exclude
779     delete @pm{@match};
780 root 1.19
781     print "applying exclude $glob - excluded ", (scalar @match), " files.\n"
782     if $VERBOSE >= 5;
783 root 1.18 }
784     }
785    
786     my @pmi = keys %pmi;
787     @pm{@pmi} = delete @pmi{@pmi};
788     }
789    
790     #############################################################################
791     # scan for AutoLoader and static archives
792    
793     sub scan_al {
794     my ($auto, $autodir) = @_;
795    
796     my $ix = "$autodir/autosplit.ix";
797    
798 root 1.19 print "processing autoload index for '$auto'\n"
799     if $VERBOSE >= 6;
800    
801 root 1.18 $pm{"$auto/autosplit.ix"} = $ix;
802    
803     open my $fh, "<:perlio", $ix
804     or die "$ix: $!";
805    
806     my $package;
807    
808     while (<$fh>) {
809     if (/^\s*sub\s+ ([^[:space:];]+) \s* (?:\([^)]*\))? \s*;?\s*$/x) {
810     my $al = "auto/$package/$1.al";
811     my $inc = find_inc $al;
812    
813     defined $inc or die "$al: autoload file not found, but should be there.\n";
814    
815 root 1.19 $pm{$al} = $inc;
816     print "found autoload function '$al'\n"
817     if $VERBOSE >= 6;
818 root 1.18
819     } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) {
820     ($package = $1) =~ s/::/\//g;
821     } elsif (/^\s*(?:#|1?\s*;?\s*$)/) {
822     # nop
823     } else {
824 root 1.19 warn "WARNING: $ix: unparsable line, please report: $_";
825 root 1.18 }
826     }
827     }
828    
829     for my $pm (keys %pm) {
830     if ($pm =~ /^(.*)\.pm$/) {
831     my $auto = "auto/$1";
832     my $autodir = find_inc $auto;
833    
834 root 1.19 if (defined $autodir && -d $autodir) {
835 root 1.18 # AutoLoader
836     scan_al $auto, $autodir
837     if -f "$autodir/autosplit.ix";
838    
839     # extralibs.ld
840     if (open my $fh, "<:perlio", "$autodir/extralibs.ld") {
841 root 1.19 print "found extralibs for $pm\n"
842     if $VERBOSE >= 6;
843    
844 root 1.18 local $/;
845     $extralibs .= " " . <$fh>;
846     }
847    
848     $pm =~ /([^\/]+).pm$/ or die "$pm: unable to match last component";
849    
850     my $base = $1;
851    
852     # static ext
853     if (-f "$autodir/$base$Config{_a}") {
854 root 1.19 print "found static archive for $pm\n"
855     if $VERBOSE >= 3;
856    
857 root 1.18 push @libs, "$autodir/$base$Config{_a}";
858     push @static_ext, $pm;
859     }
860    
861     # dynamic object
862     die "ERROR: found shared object - can't link statically ($_)\n"
863     if -f "$autodir/$base.$Config{dlext}";
864 root 1.19
865     if ($PACKLIST && open my $fh, "<:perlio", "$autodir/.packlist") {
866     print "found .packlist for $pm\n"
867     if $VERBOSE >= 3;
868    
869     while (<$fh>) {
870     chomp;
871    
872     # only include certain files (.al, .ix, .pm, .pl)
873     if (/\.(pm|pl|al|ix)$/) {
874     for my $inc (@INC) {
875     # in addition, we only add files that are below some @INC path
876     $inc =~ s/\/*$/\//;
877    
878     if ($inc eq substr $_, 0, length $inc) {
879     my $base = substr $_, length $inc;
880     $pm{$base} = $_;
881    
882     print "+ added .packlist dependency $base\n"
883     if $VERBOSE >= 3;
884     }
885    
886     last;
887     }
888     }
889     }
890     }
891 root 1.18 }
892     }
893     }
894    
895     #############################################################################
896    
897 root 1.19 print "processing bundle files (try more -v power if you get bored waiting here)...\n"
898     if $VERBOSE >= 1;
899    
900 root 1.1 my $data;
901     my @index;
902     my @order = sort {
903     length $a <=> length $b
904     or $a cmp $b
905     } keys %pm;
906    
907     # sorting by name - better compression, but needs more metadata
908     # sorting by length - faster lookup
909     # usually, the metadata overhead beats the loss through compression
910    
911     for my $pm (@order) {
912     my $path = $pm{$pm};
913    
914     128 > length $pm
915 root 1.18 or die "ERROR: $pm: path too long (only 128 octets supported)\n";
916 root 1.1
917     my $src = ref $path
918     ? $$path
919     : do {
920 root 1.7 open my $pm, "<", $path
921 root 1.1 or die "$path: $!";
922    
923     local $/;
924    
925     <$pm>
926     };
927    
928 root 1.18 my $size = length $src;
929    
930 root 1.8 unless ($pmbin{$pm}) { # only do this unless the file is binary
931     if ($pm =~ /^auto\/POSIX\/[^\/]+\.al$/) {
932     if ($src =~ /^ unimpl \"/m) {
933 root 1.19 print "$pm: skipping (only raises runtime error).\n"
934     if $VERBOSE >= 3;
935 root 1.8 next;
936     }
937 root 1.1 }
938    
939 root 1.19 $src = cache +($STRIP eq "ppi" ? "$UNISTRIP,$OPTIMISE_SIZE" : undef), $src, sub {
940 root 1.18 if ($UNISTRIP && $pm =~ /^unicore\/.*\.pl$/) {
941 root 1.19 print "applying unicore stripping $pm\n"
942     if $VERBOSE >= 6;
943    
944 root 1.18 # special stripping for unicore swashes and properties
945     # much more could be done by going binary
946     $src =~ s{
947     (^return\ <<'END';\n) (.*?\n) (END(?:\n|\Z))
948     }{
949     my ($pre, $data, $post) = ($1, $2, $3);
950    
951     for ($data) {
952     s/^([0-9a-fA-F]+)\t([0-9a-fA-F]+)\t/sprintf "%X\t%X", hex $1, hex $2/gem
953     if $OPTIMISE_SIZE;
954    
955     # s{
956     # ^([0-9a-fA-F]+)\t([0-9a-fA-F]*)\t
957     # }{
958     # # ww - smaller filesize, UU - compress better
959     # pack "C0UU",
960     # hex $1,
961     # length $2 ? (hex $2) - (hex $1) : 0
962     # }gemx;
963 root 1.1
964 root 1.18 s/#.*\n/\n/mg;
965     s/\s+\n/\n/mg;
966     }
967 root 1.8
968 root 1.18 "$pre$data$post"
969     }smex;
970 root 1.1 }
971    
972 root 1.18 if ($STRIP =~ /ppi/i) {
973     require PPI;
974    
975     if (my $ppi = PPI::Document->new (\$src)) {
976     $ppi->prune ("PPI::Token::Comment");
977     $ppi->prune ("PPI::Token::Pod");
978    
979     # prune END stuff
980     for (my $last = $ppi->last_element; $last; ) {
981     my $prev = $last->previous_token;
982    
983     if ($last->isa (PPI::Token::Whitespace::)) {
984     $last->delete;
985     } elsif ($last->isa (PPI::Statement::End::)) {
986     $last->delete;
987     last;
988     } elsif ($last->isa (PPI::Token::Pod::)) {
989     $last->delete;
990     } else {
991     last;
992     }
993    
994     $last = $prev;
995     }
996    
997     # prune some but not all insignificant whitespace
998     for my $ws (@{ $ppi->find (PPI::Token::Whitespace::) }) {
999     my $prev = $ws->previous_token;
1000     my $next = $ws->next_token;
1001    
1002     if (!$prev || !$next) {
1003     $ws->delete;
1004     } else {
1005     if (
1006     $next->isa (PPI::Token::Operator::) && $next->{content} =~ /^(?:,|=|!|!=|==|=>)$/ # no ., because of digits. == float
1007     or $prev->isa (PPI::Token::Operator::) && $prev->{content} =~ /^(?:,|=|\.|!|!=|==|=>)$/
1008     or $prev->isa (PPI::Token::Structure::)
1009     or ($OPTIMISE_SIZE &&
1010     ($prev->isa (PPI::Token::Word::)
1011     && (PPI::Token::Symbol:: eq ref $next
1012     || $next->isa (PPI::Structure::Block::)
1013     || $next->isa (PPI::Structure::List::)
1014     || $next->isa (PPI::Structure::Condition::)))
1015     )
1016     ) {
1017     $ws->delete;
1018     } elsif ($prev->isa (PPI::Token::Whitespace::)) {
1019     $ws->{content} = ' ';
1020     $prev->delete;
1021     } else {
1022     $ws->{content} = ' ';
1023     }
1024     }
1025     }
1026 root 1.1
1027 root 1.18 # prune whitespace around blocks
1028     if ($OPTIMISE_SIZE) {
1029     # these usually decrease size, but decrease compressability more
1030     for my $struct (PPI::Structure::Block::, PPI::Structure::Condition::) {
1031     for my $node (@{ $ppi->find ($struct) }) {
1032     my $n1 = $node->first_token;
1033     my $n2 = $n1->previous_token;
1034     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
1035     $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
1036     my $n1 = $node->last_token;
1037     my $n2 = $n1->next_token;
1038     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
1039     $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
1040     }
1041     }
1042    
1043     for my $node (@{ $ppi->find (PPI::Structure::List::) }) {
1044     my $n1 = $node->first_token;
1045     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
1046     my $n1 = $node->last_token;
1047     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
1048     }
1049 root 1.8 }
1050 root 1.1
1051 root 1.18 # reformat qw() lists which often have lots of whitespace
1052     for my $node (@{ $ppi->find (PPI::Token::QuoteLike::Words::) }) {
1053     if ($node->{content} =~ /^qw(.)(.*)(.)$/s) {
1054     my ($a, $qw, $b) = ($1, $2, $3);
1055     $qw =~ s/^\s+//;
1056     $qw =~ s/\s+$//;
1057     $qw =~ s/\s+/ /g;
1058     $node->{content} = "qw$a$qw$b";
1059     }
1060 root 1.8 }
1061 root 1.18
1062     $src = $ppi->serialize;
1063     } else {
1064     warn "WARNING: $pm{$pm}: PPI failed to parse this file\n";
1065 root 1.8 }
1066 root 1.18 } elsif ($STRIP =~ /pod/i && $pm ne "Opcode.pm") { # opcode parses it's own pod
1067     require Pod::Strip;
1068 root 1.8
1069 root 1.18 my $stripper = Pod::Strip->new;
1070    
1071     my $out;
1072     $stripper->output_string (\$out);
1073     $stripper->parse_string_document ($src)
1074     or die;
1075     $src = $out;
1076 root 1.1 }
1077    
1078 root 1.18 if ($VERIFY && $pm =~ /\.pm$/ && $pm ne "Opcode.pm") {
1079     if (open my $fh, "-|") {
1080     <$fh>;
1081     } else {
1082     eval "#line 1 \"$pm\"\n$src" or warn "\n\n\n$pm\n\n$src\n$@\n\n\n";
1083     exit 0;
1084 root 1.8 }
1085 root 1.1 }
1086 root 1.8
1087 root 1.18 $src
1088     };
1089 root 1.1
1090 root 1.8 # if ($pm eq "Opcode.pm") {
1091     # open my $fh, ">x" or die; print $fh $src;#d#
1092     # exit 1;
1093     # }
1094 root 1.1 }
1095    
1096 root 1.19 print "adding $pm (original size $size, stored size ", length $src, ")\n"
1097 root 1.1 if $VERBOSE >= 2;
1098    
1099     push @index, ((length $pm) << 25) | length $data;
1100     $data .= $pm . $src;
1101     }
1102    
1103     length $data < 2**25
1104 root 1.19 or die "ERROR: bundle too large (only 32MB supported)\n";
1105 root 1.1
1106     my $varpfx = "bundle_" . substr +(Digest::MD5::md5_hex $data), 0, 16;
1107    
1108     #############################################################################
1109     # output
1110    
1111 root 1.19 print "generating $PREFIX.h... "
1112     if $VERBOSE >= 1;
1113 root 1.1
1114     {
1115     open my $fh, ">", "$PREFIX.h"
1116     or die "$PREFIX.h: $!\n";
1117    
1118     print $fh <<EOF;
1119     /* do not edit, automatically created by mkstaticbundle */
1120 root 1.8
1121 root 1.1 #include <EXTERN.h>
1122     #include <perl.h>
1123     #include <XSUB.h>
1124    
1125     /* public API */
1126     EXTERN_C PerlInterpreter *staticperl;
1127 root 1.7 EXTERN_C void staticperl_xs_init (pTHX);
1128 root 1.1 EXTERN_C void staticperl_init (void);
1129     EXTERN_C void staticperl_cleanup (void);
1130 root 1.8
1131 root 1.1 EOF
1132     }
1133    
1134 root 1.19 print "\n"
1135     if $VERBOSE >= 1;
1136 root 1.1
1137     #############################################################################
1138     # output
1139    
1140 root 1.19 print "generating $PREFIX.c... "
1141     if $VERBOSE >= 1;
1142 root 1.1
1143     open my $fh, ">", "$PREFIX.c"
1144     or die "$PREFIX.c: $!\n";
1145    
1146     print $fh <<EOF;
1147     /* do not edit, automatically created by mkstaticbundle */
1148    
1149     #include "bundle.h"
1150    
1151     /* public API */
1152     PerlInterpreter *staticperl;
1153    
1154     EOF
1155    
1156     #############################################################################
1157     # bundle data
1158    
1159     my $count = @index;
1160    
1161     print $fh <<EOF;
1162     #include "bundle.h"
1163    
1164     /* bundle data */
1165    
1166     static const U32 $varpfx\_count = $count;
1167     static const U32 $varpfx\_index [$count + 1] = {
1168     EOF
1169    
1170     my $col;
1171     for (@index) {
1172     printf $fh "0x%08x,", $_;
1173     print $fh "\n" unless ++$col % 10;
1174    
1175     }
1176     printf $fh "0x%08x\n};\n", (length $data);
1177    
1178     print $fh "static const char $varpfx\_data [] =\n";
1179     dump_string $fh, $data;
1180    
1181 root 1.19 print $fh ";\n\n";
1182 root 1.1
1183     #############################################################################
1184     # bootstrap
1185    
1186     # boot file for staticperl
1187     # this file will be eval'ed at initialisation time
1188    
1189     my $bootstrap = '
1190     BEGIN {
1191     package ' . $PACKAGE . ';
1192    
1193     PerlIO::scalar->bootstrap;
1194    
1195     @INC = sub {
1196     my $data = find "$_[1]"
1197     or return;
1198    
1199     $INC{$_[1]} = $_[1];
1200    
1201     open my $fh, "<", \$data;
1202     $fh
1203     };
1204     }
1205     ';
1206    
1207     $bootstrap .= "require '//boot';"
1208     if exists $pm{"//boot"};
1209    
1210     $bootstrap =~ s/\s+/ /g;
1211     $bootstrap =~ s/(\W) /$1/g;
1212     $bootstrap =~ s/ (\W)/$1/g;
1213    
1214     print $fh "const char bootstrap [] = ";
1215     dump_string $fh, $bootstrap;
1216     print $fh ";\n\n";
1217    
1218     print $fh <<EOF;
1219     /* search all bundles for the given file, using binary search */
1220     XS(find)
1221     {
1222     dXSARGS;
1223    
1224     if (items != 1)
1225     Perl_croak (aTHX_ "Usage: $PACKAGE\::find (\$path)");
1226    
1227     {
1228     STRLEN namelen;
1229     char *name = SvPV (ST (0), namelen);
1230     SV *res = 0;
1231    
1232     int l = 0, r = $varpfx\_count;
1233    
1234     while (l <= r)
1235     {
1236     int m = (l + r) >> 1;
1237     U32 idx = $varpfx\_index [m];
1238     int comp = namelen - (idx >> 25);
1239    
1240     if (!comp)
1241     {
1242     int ofs = idx & 0x1FFFFFFU;
1243     comp = memcmp (name, $varpfx\_data + ofs, namelen);
1244    
1245     if (!comp)
1246     {
1247     /* found */
1248     int ofs2 = $varpfx\_index [m + 1] & 0x1FFFFFFU;
1249    
1250     ofs += namelen;
1251     res = newSVpvn ($varpfx\_data + ofs, ofs2 - ofs);
1252     goto found;
1253     }
1254     }
1255    
1256     if (comp < 0)
1257     r = m - 1;
1258     else
1259     l = m + 1;
1260     }
1261    
1262     XSRETURN (0);
1263    
1264     found:
1265     ST (0) = res;
1266     sv_2mortal (ST (0));
1267     }
1268    
1269     XSRETURN (1);
1270     }
1271    
1272     /* list all files in the bundle */
1273     XS(list)
1274     {
1275     dXSARGS;
1276    
1277     if (items != 0)
1278     Perl_croak (aTHX_ "Usage: $PACKAGE\::list");
1279    
1280     {
1281     int i;
1282    
1283     EXTEND (SP, $varpfx\_count);
1284    
1285     for (i = 0; i < $varpfx\_count; ++i)
1286     {
1287     U32 idx = $varpfx\_index [i];
1288    
1289     PUSHs (newSVpvn ($varpfx\_data + (idx & 0x1FFFFFFU), idx >> 25));
1290     }
1291     }
1292    
1293     XSRETURN ($varpfx\_count);
1294     }
1295    
1296     EOF
1297    
1298     #############################################################################
1299     # xs_init
1300    
1301     print $fh <<EOF;
1302 root 1.7 void
1303     staticperl_xs_init (pTHX)
1304 root 1.1 {
1305     EOF
1306    
1307     @static_ext = ("DynaLoader", sort @static_ext);
1308    
1309     # prototypes
1310     for (@static_ext) {
1311     s/\.pm$//;
1312     (my $cname = $_) =~ s/\//__/g;
1313     print $fh " EXTERN_C void boot_$cname (pTHX_ CV* cv);\n";
1314     }
1315    
1316     print $fh <<EOF;
1317     char *file = __FILE__;
1318     dXSUB_SYS;
1319    
1320     newXSproto ("$PACKAGE\::find", find, file, "\$");
1321     newXSproto ("$PACKAGE\::list", list, file, "");
1322     EOF
1323    
1324     # calls
1325     for (@static_ext) {
1326     s/\.pm$//;
1327    
1328     (my $cname = $_) =~ s/\//__/g;
1329     (my $pname = $_) =~ s/\//::/g;
1330    
1331     my $bootstrap = $pname eq "DynaLoader" ? "boot" : "bootstrap";
1332    
1333     print $fh " newXS (\"$pname\::$bootstrap\", boot_$cname, file);\n";
1334     }
1335    
1336     print $fh <<EOF;
1337     Perl_av_create_and_unshift_one (&PL_preambleav, newSVpv (bootstrap, sizeof (bootstrap) - 1));
1338     }
1339     EOF
1340    
1341     #############################################################################
1342     # optional perl_init/perl_destroy
1343    
1344 root 1.17 if ($APP) {
1345     print $fh <<EOF;
1346    
1347     int
1348     main (int argc, char *argv [])
1349     {
1350     extern char **environ;
1351     int exitstatus;
1352    
1353     static char *args[] = {
1354     "staticperl",
1355     "-e",
1356     "0"
1357     };
1358    
1359     PERL_SYS_INIT3 (&argc, &argv, &environ);
1360     staticperl = perl_alloc ();
1361     perl_construct (staticperl);
1362    
1363     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1364    
1365     exitstatus = perl_parse (staticperl, staticperl_xs_init, sizeof (args) / sizeof (*args), args, environ);
1366     if (!exitstatus)
1367     perl_run (staticperl);
1368    
1369     exitstatus = perl_destruct (staticperl);
1370     perl_free (staticperl);
1371     PERL_SYS_TERM ();
1372    
1373     return exitstatus;
1374     }
1375     EOF
1376     } elsif ($PERL) {
1377 root 1.1 print $fh <<EOF;
1378    
1379     int
1380     main (int argc, char *argv [])
1381     {
1382     extern char **environ;
1383     int exitstatus;
1384    
1385     PERL_SYS_INIT3 (&argc, &argv, &environ);
1386     staticperl = perl_alloc ();
1387     perl_construct (staticperl);
1388    
1389     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1390    
1391 root 1.7 exitstatus = perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
1392 root 1.1 if (!exitstatus)
1393     perl_run (staticperl);
1394    
1395     exitstatus = perl_destruct (staticperl);
1396     perl_free (staticperl);
1397     PERL_SYS_TERM ();
1398    
1399     return exitstatus;
1400     }
1401     EOF
1402     } else {
1403     print $fh <<EOF;
1404    
1405     EXTERN_C void
1406     staticperl_init (void)
1407     {
1408     extern char **environ;
1409     int argc = sizeof (args) / sizeof (args [0]);
1410     char **argv = args;
1411    
1412 root 1.17 static char *args[] = {
1413     "staticperl",
1414     "-e",
1415     "0"
1416     };
1417    
1418 root 1.1 PERL_SYS_INIT3 (&argc, &argv, &environ);
1419     staticperl = perl_alloc ();
1420     perl_construct (staticperl);
1421     PL_origalen = 1;
1422     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1423 root 1.7 perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
1424 root 1.1
1425     perl_run (staticperl);
1426     }
1427    
1428     EXTERN_C void
1429     staticperl_cleanup (void)
1430     {
1431     perl_destruct (staticperl);
1432     perl_free (staticperl);
1433     staticperl = 0;
1434     PERL_SYS_TERM ();
1435     }
1436     EOF
1437     }
1438    
1439 root 1.19 print -s "$PREFIX.c", " octets (", (length $data) , " data octets).\n\n"
1440     if $VERBOSE >= 1;
1441 root 1.1
1442     #############################################################################
1443     # libs, cflags
1444    
1445     {
1446 root 1.19 print "generating $PREFIX.ccopts... "
1447     if $VERBOSE >= 1;
1448 root 1.1
1449     my $str = "$Config{ccflags} $Config{optimize} $Config{cppflags} -I$Config{archlibexp}/CORE";
1450     $str =~ s/([\(\)])/\\$1/g;
1451    
1452     open my $fh, ">$PREFIX.ccopts"
1453     or die "$PREFIX.ccopts: $!";
1454     print $fh $str;
1455 root 1.19
1456     print "$str\n\n"
1457     if $VERBOSE >= 1;
1458 root 1.1 }
1459    
1460     {
1461     print "generating $PREFIX.ldopts... ";
1462    
1463 root 1.18 my $str = $STATIC ? "-static " : "";
1464 root 1.1
1465     $str .= "$Config{ccdlflags} $Config{ldflags} @libs $Config{archlibexp}/CORE/$Config{libperl} $Config{perllibs}";
1466    
1467     my %seen;
1468     $str .= " $_" for grep !$seen{$_}++, ($extralibs =~ /(\S+)/g);
1469    
1470 root 1.18 for (@staticlibs) {
1471     $str =~ s/(^|\s) (-l\Q$_\E) ($|\s)/$1-Wl,-Bstatic $2 -Wl,-Bdynamic$3/gx;
1472     }
1473    
1474 root 1.1 $str =~ s/([\(\)])/\\$1/g;
1475    
1476     open my $fh, ">$PREFIX.ldopts"
1477     or die "$PREFIX.ldopts: $!";
1478     print $fh $str;
1479 root 1.19
1480     print "$str\n\n"
1481     if $VERBOSE >= 1;
1482 root 1.1 }
1483    
1484 root 1.17 if ($PERL or defined $APP) {
1485     $APP = "perl" unless defined $APP;
1486    
1487 root 1.19 print "building $APP...\n"
1488     if $VERBOSE >= 1;
1489 root 1.17
1490     system "$Config{cc} \$(cat bundle.ccopts\) -o \Q$APP\E bundle.c \$(cat bundle.ldopts\)";
1491 root 1.1
1492 root 1.19 unlink "$PREFIX.$_"
1493     for qw(ccopts ldopts c h);
1494 root 1.18
1495 root 1.19 print "\n"
1496     if $VERBOSE >= 1;
1497 root 1.1 }
1498    
1499     MKBUNDLE
1500     }
1501    
1502     bundle() {
1503     catmkbundle >"$MKBUNDLE~" || fatal "$MKBUNDLE~: cannot create"
1504     chmod 755 "$MKBUNDLE~" && mv "$MKBUNDLE~" "$MKBUNDLE"
1505 root 1.18 CACHE="$STATICPERL/cache"
1506     mkdir -p "$CACHE"
1507     "$PERL_PREFIX/bin/perl" -- "$MKBUNDLE" --cache "$CACHE" "$@"
1508 root 1.1 }
1509    
1510     if [ $# -gt 0 ]; then
1511     while [ $# -gt 0 ]; do
1512     mkdir -p "$STATICPERL" || fatal "$STATICPERL: cannot create"
1513 root 1.10 mkdir -p "$PERL_PREFIX" || fatal "$PERL_PREFIX: cannot create"
1514 root 1.1
1515     command="${1#--}"; shift
1516     case "$command" in
1517 root 1.19 version )
1518     echo "staticperl version $VERSION"
1519     ;;
1520 root 1.1 fetch | configure | build | install | clean | distclean)
1521 root 1.10 ( "$command" )
1522 root 1.1 ;;
1523     instsrc )
1524 root 1.10 ( instsrc "$@" )
1525 root 1.1 exit
1526     ;;
1527     instcpan )
1528 root 1.10 ( instcpan "$@" )
1529 root 1.1 exit
1530     ;;
1531     cpan )
1532 root 1.10 ( install )
1533     "$PERL_PREFIX/bin/cpan" "$@"
1534 root 1.1 exit
1535     ;;
1536     mkbundle )
1537 root 1.10 ( install )
1538 root 1.1 bundle "$@"
1539     exit
1540     ;;
1541     mkperl )
1542 root 1.10 ( install )
1543 root 1.1 bundle --perl "$@"
1544     exit
1545     ;;
1546 root 1.17 mkapp )
1547     ( install )
1548     bundle --app "$@"
1549     exit
1550     ;;
1551 root 1.1 help )
1552     podusage 2
1553     ;;
1554     * )
1555     exec 1>&2
1556     echo
1557     echo "Unknown command: $command"
1558     podusage 0
1559     ;;
1560     esac
1561     done
1562     else
1563     usage
1564     fi
1565    
1566     exit 0
1567    
1568     =head1 NAME
1569    
1570 root 1.7 staticperl - perl, libc, 100 modules, all in one 500kb file
1571 root 1.1
1572     =head1 SYNOPSIS
1573    
1574     staticperl help # print the embedded documentation
1575     staticperl fetch # fetch and unpack perl sources
1576     staticperl configure # fetch and then configure perl
1577     staticperl build # configure and then build perl
1578     staticperl install # build and then install perl
1579     staticperl clean # clean most intermediate files (restart at configure)
1580     staticperl distclean # delete everything installed by this script
1581     staticperl cpan # invoke CPAN shell
1582     staticperl instmod path... # install unpacked modules
1583     staticperl instcpan modulename... # install modules from CPAN
1584     staticperl mkbundle <bundle-args...> # see documentation
1585     staticperl mkperl <bundle-args...> # see documentation
1586 root 1.17 staticperl mkapp appname <bundle-args...> # see documentation
1587 root 1.1
1588     Typical Examples:
1589    
1590     staticperl install # fetch, configure, build and install perl
1591     staticperl cpan # run interactive cpan shell
1592     staticperl mkperl -M '"Config_heavy.pl"' # build a perl that supports -V
1593     staticperl mkperl -MAnyEvent::Impl::Perl -MAnyEvent::HTTPD -MURI -MURI::http
1594     # build a perl with the above modules linked in
1595 root 1.17 staticperl mkapp myapp --boot mainprog mymodules
1596     # build a binary "myapp" from mainprog and mymodules
1597 root 1.1
1598     =head1 DESCRIPTION
1599    
1600 root 1.18 This script helps you to create single-file perl interpreters
1601     or applications, or embedding a perl interpreter in your
1602     applications. Single-file means that it is fully self-contained - no
1603     separate shared objects, no autoload fragments, no .pm or .pl files are
1604     needed. And when linking statically, you can create (or embed) a single
1605     file that contains perl interpreter, libc, all the modules you need, all
1606     the libraries you need and of course your actual program.
1607 root 1.1
1608 root 1.7 With F<uClibc> and F<upx> on x86, you can create a single 500kb binary
1609     that contains perl and 100 modules such as POSIX, AnyEvent, EV, IO::AIO,
1610     Coro and so on. Or any other choice of modules.
1611 root 1.1
1612 root 1.19 To see how this turns out, you can try out smallperl and bigperl, two
1613     pre-built static and compressed perl binaries with many and even more
1614     modules: just follow the links at L<http://staticperl.schmorp.de/>.
1615    
1616 root 1.4 The created files do not need write access to the file system (like PAR
1617 root 1.1 does). In fact, since this script is in many ways similar to PAR::Packer,
1618     here are the differences:
1619    
1620     =over 4
1621    
1622     =item * The generated executables are much smaller than PAR created ones.
1623    
1624     Shared objects and the perl binary contain a lot of extra info, while
1625     the static nature of F<staticperl> allows the linker to remove all
1626     functionality and meta-info not required by the final executable. Even
1627     extensions statically compiled into perl at build time will only be
1628     present in the final executable when needed.
1629    
1630     In addition, F<staticperl> can strip perl sources much more effectively
1631     than PAR.
1632    
1633     =item * The generated executables start much faster.
1634    
1635     There is no need to unpack files, or even to parse Zip archives (which is
1636     slow and memory-consuming business).
1637    
1638     =item * The generated executables don't need a writable filesystem.
1639    
1640     F<staticperl> loads all required files directly from memory. There is no
1641     need to unpack files into a temporary directory.
1642    
1643 root 1.18 =item * More control over included files, more burden.
1644 root 1.1
1645 root 1.4 PAR tries to be maintenance and hassle-free - it tries to include more
1646 root 1.18 files than necessary to make sure everything works out of the box. It
1647     mostly succeeds at this, but he extra files (such as the unicode database)
1648     can take substantial amounts of memory and file size.
1649 root 1.1
1650     With F<staticperl>, the burden is mostly with the developer - only direct
1651     compile-time dependencies and L<AutoLoader> are handled automatically.
1652     This means the modules to include often need to be tweaked manually.
1653    
1654 root 1.18 All this does not preclude more permissive modes to be implemented in
1655     the future, but right now, you have to resolve state hidden dependencies
1656     manually.
1657    
1658 root 1.1 =item * PAR works out of the box, F<staticperl> does not.
1659    
1660     Maintaining your own custom perl build can be a pain in the ass, and while
1661     F<staticperl> tries to make this easy, it still requires a custom perl
1662     build and possibly fiddling with some modules. PAR is likely to produce
1663     results faster.
1664    
1665 root 1.13 Ok, PAR never has worked for me out of the box, and for some people,
1666     F<staticperl> does work out of the box, as they don't count "fiddling with
1667     module use lists" against it, but nevertheless, F<staticperl> is certainly
1668     a bit more difficult to use.
1669    
1670 root 1.1 =back
1671    
1672     =head1 HOW DOES IT WORK?
1673    
1674     Simple: F<staticperl> downloads, compile and installs a perl version of
1675     your choice in F<~/.staticperl>. You can add extra modules either by
1676     letting F<staticperl> install them for you automatically, or by using CPAN
1677     and doing it interactively. This usually takes 5-10 minutes, depending on
1678 root 1.4 the speed of your computer and your internet connection.
1679 root 1.1
1680     It is possible to do program development at this stage, too.
1681    
1682     Afterwards, you create a list of files and modules you want to include,
1683 root 1.4 and then either build a new perl binary (that acts just like a normal perl
1684 root 1.1 except everything is compiled in), or you create bundle files (basically C
1685     sources you can use to embed all files into your project).
1686    
1687 root 1.18 This step is very fast (a few seconds if PPI is not used for stripping, or
1688     the stripped files are in the cache), and can be tweaked and repeated as
1689     often as necessary.
1690 root 1.1
1691     =head1 THE F<STATICPERL> SCRIPT
1692    
1693     This module installs a script called F<staticperl> into your perl
1694     binary directory. The script is fully self-contained, and can be used
1695     without perl (for example, in an uClibc chroot environment). In fact,
1696     it can be extracted from the C<App::Staticperl> distribution tarball as
1697     F<bin/staticperl>, without any installation.
1698    
1699     F<staticperl> interprets the first argument as a command to execute,
1700     optionally followed by any parameters.
1701    
1702     There are two command categories: the "phase 1" commands which deal with
1703     installing perl and perl modules, and the "phase 2" commands, which deal
1704     with creating binaries and bundle files.
1705    
1706     =head2 PHASE 1 COMMANDS: INSTALLING PERL
1707    
1708     The most important command is F<install>, which does basically
1709     everything. The default is to download and install perl 5.12.2 and a few
1710     modules required by F<staticperl> itself, but all this can (and should) be
1711     changed - see L<CONFIGURATION>, below.
1712    
1713     The command
1714    
1715     staticperl install
1716    
1717     Is normally all you need: It installs the perl interpreter in
1718     F<~/.staticperl/perl>. It downloads, configures, builds and installs the
1719     perl interpreter if required.
1720    
1721     Most of the following commands simply run one or more steps of this
1722     sequence.
1723    
1724 root 1.4 To force recompilation or reinstallation, you need to run F<staticperl
1725 root 1.1 distclean> first.
1726    
1727     =over 4
1728    
1729 root 1.19 =item F<staticperl version>
1730    
1731     Prints some info about the version of the F<staticperl> script you are using.
1732    
1733 root 1.1 =item F<staticperl fetch>
1734    
1735     Runs only the download and unpack phase, unless this has already happened.
1736    
1737     =item F<staticperl configure>
1738    
1739     Configures the unpacked perl sources, potentially after downloading them first.
1740    
1741     =item F<staticperl build>
1742    
1743     Builds the configured perl sources, potentially after automatically
1744     configuring them.
1745    
1746     =item F<staticperl install>
1747    
1748 root 1.4 Wipes the perl installation directory (usually F<~/.staticperl/perl>) and
1749     installs the perl distribution, potentially after building it first.
1750 root 1.1
1751     =item F<staticperl cpan> [args...]
1752    
1753 root 1.4 Starts an interactive CPAN shell that you can use to install further
1754     modules. Installs the perl first if necessary, but apart from that,
1755 root 1.1 no magic is involved: you could just as well run it manually via
1756     F<~/.staticperl/perl/bin/cpan>.
1757    
1758     Any additional arguments are simply passed to the F<cpan> command.
1759    
1760     =item F<staticperl instcpan> module...
1761    
1762     Tries to install all the modules given and their dependencies, using CPAN.
1763    
1764     Example:
1765    
1766     staticperl instcpan EV AnyEvent::HTTPD Coro
1767    
1768     =item F<staticperl instsrc> directory...
1769    
1770     In the unlikely case that you have unpacked perl modules around and want
1771 root 1.4 to install from these instead of from CPAN, you can do this using this
1772 root 1.1 command by specifying all the directories with modules in them that you
1773     want to have built.
1774    
1775     =item F<staticperl clean>
1776    
1777 root 1.11 Deletes the perl source directory (and potentially cleans up other
1778     intermediate files). This can be used to clean up files only needed for
1779     building perl, without removing the installed perl interpreter, or to
1780     force a re-build from scratch.
1781    
1782     At the moment, it doesn't delete downloaded tarballs.
1783 root 1.1
1784     =item F<staticperl distclean>
1785    
1786     This wipes your complete F<~/.staticperl> directory. Be careful with this,
1787     it nukes your perl download, perl sources, perl distribution and any
1788     installed modules. It is useful if you wish to start over "from scratch"
1789     or when you want to uninstall F<staticperl>.
1790    
1791     =back
1792    
1793     =head2 PHASE 2 COMMANDS: BUILDING PERL BUNDLES
1794    
1795     Building (linking) a new F<perl> binary is handled by a separate
1796     script. To make it easy to use F<staticperl> from a F<chroot>, the script
1797     is embedded into F<staticperl>, which will write it out and call for you
1798     with any arguments you pass:
1799    
1800     staticperl mkbundle mkbundle-args...
1801    
1802     In the oh so unlikely case of something not working here, you
1803 root 1.2 can run the script manually as well (by default it is written to
1804 root 1.1 F<~/.staticperl/mkbundle>).
1805    
1806     F<mkbundle> is a more conventional command and expect the argument
1807 root 1.4 syntax commonly used on UNIX clones. For example, this command builds
1808 root 1.1 a new F<perl> binary and includes F<Config.pm> (for F<perl -V>),
1809     F<AnyEvent::HTTPD>, F<URI> and a custom F<httpd> script (from F<eg/httpd>
1810     in this distribution):
1811    
1812     # first make sure we have perl and the required modules
1813     staticperl instcpan AnyEvent::HTTPD
1814    
1815     # now build the perl
1816     staticperl mkperl -M'"Config_heavy.pl"' -MAnyEvent::Impl::Perl \
1817     -MAnyEvent::HTTPD -MURI::http \
1818     --add 'eg/httpd httpd.pm'
1819    
1820     # finally, invoke it
1821     ./perl -Mhttpd
1822    
1823 root 1.2 As you can see, things are not quite as trivial: the L<Config> module has
1824     a hidden dependency which is not even a perl module (F<Config_heavy.pl>),
1825     L<AnyEvent> needs at least one event loop backend that we have to
1826 root 1.4 specify manually (here L<AnyEvent::Impl::Perl>), and the F<URI> module
1827 root 1.2 (required by L<AnyEvent::HTTPD>) implements various URI schemes as extra
1828     modules - since L<AnyEvent::HTTPD> only needs C<http> URIs, we only need
1829 root 1.4 to include that module. I found out about these dependencies by carefully
1830     watching any error messages about missing modules...
1831 root 1.2
1832 root 1.17 Instead of building a new perl binary, you can also build a standalone
1833     application:
1834    
1835     # build the app
1836     staticperl mkapp app --boot eg/httpd \
1837     -MAnyEvent::Impl::Perl -MAnyEvent::HTTPD -MURI::http
1838    
1839     # run it
1840     ./app
1841    
1842 root 1.2 =head3 OPTION PROCESSING
1843    
1844 root 1.4 All options can be given as arguments on the command line (typically
1845     using long (e.g. C<--verbose>) or short option (e.g. C<-v>) style). Since
1846     specifying a lot of modules can make the command line very cumbersome,
1847 root 1.2 you can put all long options into a "bundle specification file" (with or
1848     without C<--> prefix) and specify this bundle file instead.
1849    
1850     For example, the command given earlier could also look like this:
1851    
1852     staticperl mkperl httpd.bundle
1853    
1854     And all options could be in F<httpd.bundle>:
1855 root 1.1
1856 root 1.2 use "Config_heavy.pl"
1857     use AnyEvent::Impl::Perl
1858     use AnyEvent::HTTPD
1859     use URI::http
1860     add eg/httpd httpd.pm
1861    
1862     All options that specify modules or files to be added are processed in the
1863 root 1.4 order given on the command line (that affects the C<--use> and C<--eval>
1864 root 1.2 options at the moment).
1865    
1866 root 1.19 =head3 PACKAGE SELECTION WORKFLOW
1867    
1868     F<staticperl mkbundle> has a number of options to control package
1869     selection. This section describes how they interact with each other. Also,
1870     since I am still a newbie w.r.t. these issues, maybe future versions of
1871     F<staticperl> will change this, so watch out :)
1872    
1873     The idiom "in order" means "in order that they are specified on the
1874     commandline". If you use a bundle specification file, then the options
1875     will be processed as if they were given in place of the bundle file name.
1876    
1877     =over 4
1878    
1879     =item 1. apply all C<--use>, C<--eval>, C<--add>, C<--addbin> and
1880     C<--incglob> options, in order.
1881    
1882     In addition, C<--use> and C<--eval> dependencies will be added when the
1883     options are processed.
1884    
1885     =item 2. apply all C<--include> and C<--exclude> options, in order.
1886    
1887     All this step does is potentially reduce the number of files already
1888     selected or found in phase 1.
1889    
1890     =item 3. find all modules (== F<.pm> files), gather their static archives
1891     (F<.a>) and AutoLoader splitfiles (F<.ix> and F<.al> files), find any
1892     extra libraries they need for linking (F<extralibs.ld>) and optionally
1893     evaluate any F<.packlist> files.
1894    
1895     This step is required to link against XS extensions and also adds files
1896     required for L<AutoLoader> to do it's job.
1897    
1898     =back
1899    
1900     After this, all the files selected for bundling will be read and processed
1901     (stripped), the bundle files will be written, and optionally a new F<perl>
1902     or application binary will be linked.
1903    
1904 root 1.2 =head3 MKBUNDLE OPTIONS
1905    
1906     =over 4
1907    
1908     =item --verbose | -v
1909    
1910     Increases the verbosity level by one (the default is C<1>).
1911    
1912     =item --quiet | -q
1913    
1914     Decreases the verbosity level by one.
1915    
1916     =item --strip none|pod|ppi
1917    
1918     Specify the stripping method applied to reduce the file of the perl
1919     sources included.
1920    
1921     The default is C<pod>, which uses the L<Pod::Strip> module to remove all
1922 root 1.4 pod documentation, which is very fast and reduces file size a lot.
1923 root 1.2
1924     The C<ppi> method uses L<PPI> to parse and condense the perl sources. This
1925 root 1.18 saves a lot more than just L<Pod::Strip>, and is generally safer,
1926     but is also a lot slower (some files take almost a minute to strip -
1927     F<staticperl> maintains a cache of stripped files to speed up subsequent
1928     runs for this reason). Note that this method doesn't optimise for raw file
1929     size, but for best compression (that means that the uncompressed file size
1930     is a bit larger, but the files compress better, e.g. with F<upx>).
1931 root 1.2
1932 root 1.7 Last not least, if you need accurate line numbers in error messages,
1933     or in the unlikely case where C<pod> is too slow, or some module gets
1934     mistreated, you can specify C<none> to not mangle included perl sources in
1935     any way.
1936 root 1.2
1937     =item --perl
1938    
1939     After writing out the bundle files, try to link a new perl interpreter. It
1940     will be called F<perl> and will be left in the current working
1941     directory. The bundle files will be removed.
1942    
1943 root 1.4 This switch is automatically used when F<staticperl> is invoked with the
1944 root 1.2 C<mkperl> command (instead of C<mkbundle>):
1945    
1946     # build a new ./perl with only common::sense in it - very small :)
1947     staticperl mkperl -Mcommon::sense
1948    
1949 root 1.17 =item --app name
1950    
1951     After writing out the bundle files, try to link a new standalone
1952     program. It will be called C<name>, and the bundle files get removed after
1953     linking it.
1954    
1955     The difference to the (mutually exclusive) C<--perl> option is that the
1956     binary created by this option will not try to act as a perl interpreter -
1957     instead it will simply initialise the perl interpreter, clean it up and
1958     exit.
1959    
1960     This switch is automatically used when F<staticperl> is invoked with the
1961     C<mkapp> command (instead of C<mkbundle>):
1962    
1963     To let it do something useful you I<must> add some boot code, e.g. with
1964     the C<--boot> option.
1965    
1966     Example: create a standalone perl binary that will execute F<appfile> when
1967     it is started.
1968    
1969     staticperl mkbundle --app myexe --boot appfile
1970    
1971 root 1.2 =item --use module | -Mmodule
1972    
1973     Include the named module and all direct dependencies. This is done by
1974     C<require>'ing the module in a subprocess and tracing which other modules
1975     and files it actually loads. If the module uses L<AutoLoader>, then all
1976     splitfiles will be included as well.
1977    
1978     Example: include AnyEvent and AnyEvent::Impl::Perl.
1979    
1980     staticperl mkbundle --use AnyEvent --use AnyEvent::Impl::Perl
1981    
1982     Sometimes you want to load old-style "perl libraries" (F<.pl> files), or
1983     maybe other weirdly named files. To do that, you need to quote the name in
1984 root 1.4 single or double quotes. When given on the command line, you probably need
1985 root 1.2 to quote once more to avoid your shell interpreting it. Common cases that
1986     need this are F<Config_heavy.pl> and F<utf8_heavy.pl>.
1987    
1988     Example: include the required files for F<perl -V> to work in all its
1989     glory (F<Config.pm> is included automatically by this).
1990    
1991     # bourne shell
1992     staticperl mkbundle --use '"Config_heavy.pl"'
1993    
1994     # bundle specification file
1995     use "Config_heavy.pl"
1996    
1997     The C<-Mmodule> syntax is included as an alias that might be easier to
1998     remember than C<use>. Or maybe it confuses people. Time will tell. Or
1999     maybe not. Argh.
2000    
2001     =item --eval "perl code" | -e "perl code"
2002    
2003     Sometimes it is easier (or necessary) to specify dependencies using perl
2004     code, or maybe one of the modules you use need a special use statement. In
2005     that case, you can use C<eval> to execute some perl snippet or set some
2006     variables or whatever you need. All files C<require>'d or C<use>'d in the
2007     script are included in the final bundle.
2008    
2009     Keep in mind that F<mkbundle> will only C<require> the modules named
2010     by the C<--use> option, so do not expect the symbols from modules you
2011 root 1.4 C<--use>'d earlier on the command line to be available.
2012 root 1.2
2013     Example: force L<AnyEvent> to detect a backend and therefore include it
2014     in the final bundle.
2015    
2016     staticperl mkbundle --eval 'use AnyEvent; AnyEvent::detect'
2017    
2018     # or like this
2019     staticperl mkbundle -MAnyEvent --eval 'use AnyEvent; AnyEvent::detect'
2020    
2021     Example: use a separate "bootstrap" script that C<use>'s lots of modules
2022     and include this in the final bundle, to be executed automatically.
2023    
2024     staticperl mkbundle --eval 'do "bootstrap"' --boot bootstrap
2025    
2026     =item --boot filename
2027    
2028     Include the given file in the bundle and arrange for it to be executed
2029     (using a C<require>) before anything else when the new perl is
2030     initialised. This can be used to modify C<@INC> or anything else before
2031 root 1.4 the perl interpreter executes scripts given on the command line (or via
2032 root 1.2 C<-e>). This works even in an embedded interpreter.
2033    
2034 root 1.19 =item --usepacklist
2035    
2036     Read F<.packlist> files for each distribution that happens to match a
2037     module name you specified. Sounds weird, and it is, so expect semantics to
2038     change somehow in the future.
2039    
2040     The idea is that most CPAN distributions have a F<.pm> file that matches
2041     the name of the distribution (which is rather reasonable after all).
2042    
2043     If this switch is enabled, then if any of the F<.pm> files that have been
2044     selected match an install distribution, then all F<.pm>, F<.pl>, F<.al>
2045     and F<.ix> files installed by this distribution are also included.
2046    
2047     For example, using this switch, when the L<URI> module is specified, then
2048     all L<URI> submodules that have been installed via the CPAN distribution
2049     are included as well, so you don't have to manually specify them.
2050    
2051 root 1.18 =item --incglob pattern
2052    
2053     This goes through all library directories and tries to match any F<.pm>
2054     and F<.pl> files against the extended glob pattern (see below). If a file
2055     matches, it is added. This switch will automatically detect L<AutoLoader>
2056     files and the required link libraries for XS modules, but it will I<not>
2057     scan the file for dependencies (at the moment).
2058    
2059     This is mainly useful to include "everything":
2060    
2061     --incglob '*'
2062    
2063     Or to include perl libraries, or trees of those, such as the unicode
2064     database files needed by many other modules:
2065    
2066     --incglob '/unicore/**.pl'
2067    
2068     =item --add file | --add "file alias"
2069 root 1.2
2070     Adds the given (perl) file into the bundle (and optionally call it
2071     "alias"). This is useful to include any custom files into the bundle.
2072    
2073     Example: embed the file F<httpd> as F<httpd.pm> when creating the bundle.
2074    
2075     staticperl mkperl --add "httpd httpd.pm"
2076    
2077     It is also a great way to add any custom modules:
2078    
2079     # specification file
2080     add file1 myfiles/file1
2081     add file2 myfiles/file2
2082     add file3 myfiles/file3
2083    
2084 root 1.18 =item --binadd file | --add "file alias"
2085 root 1.8
2086     Just like C<--add>, except that it treats the file as binary and adds it
2087     without any processing.
2088    
2089     You should probably add a C</> prefix to avoid clashing with embedded
2090     perl files (whose paths do not start with C</>), and/or use a special
2091     directory, such as C</res/name>.
2092    
2093     You can later get a copy of these files by calling C<staticperl::find
2094     "alias">.
2095    
2096 root 1.18 =item --include pattern | -i pattern | --exclude pattern | -x pattern
2097    
2098     These two options define an include/exclude filter that is used after all
2099     files selected by the other options have been found. Each include/exclude
2100     is applied to all files found so far - an include makes sure that the
2101     given files will be part of the resulting file set, an exclude will
2102     exclude files. The patterns are "extended glob patterns" (see below).
2103    
2104     For example, to include everything, except C<Devel> modules, but still
2105     include F<Devel::PPPort>, you could use this:
2106    
2107     --incglob '*' -i '/Devel/PPPort.pm' -x '/Devel/**'
2108    
2109 root 1.2 =item --static
2110    
2111     When C<--perl> is also given, link statically instead of dynamically. The
2112     default is to link the new perl interpreter fully dynamic (that means all
2113     perl modules are linked statically, but all external libraries are still
2114     referenced dynamically).
2115    
2116     Keep in mind that Solaris doesn't support static linking at all, and
2117     systems based on GNU libc don't really support it in a usable fashion
2118     either. Try uClibc if you want to create fully statically linked
2119     executables, or try the C<--staticlibs> option to link only some libraries
2120     statically.
2121    
2122 root 1.18 =item --staticlib libname
2123    
2124     When not linking fully statically, this option allows you to link specific
2125     libraries statically. What it does is simply replace all occurances of
2126     C<-llibname> with the GCC-specific C<-Wl,-Bstatic -llibname -Wl,-Bdynamic>
2127     option.
2128    
2129     This will have no effect unless the library is actually linked against,
2130     specifically, C<--staticlib> will not link against the named library
2131     unless it would be linked against anyway.
2132    
2133     Example: link libcrypt statically into the binary.
2134    
2135     staticperl mkperl -MIO::AIO --staticlib crypt
2136    
2137     # ldopts might nwo contain:
2138     # -lm -Wl,-Bstatic -lcrypt -Wl,-Bdynamic -lpthread
2139    
2140 root 1.2 =item any other argument
2141    
2142     Any other argument is interpreted as a bundle specification file, which
2143     supports most long options (without extra quoting), one option per line.
2144    
2145     =back
2146    
2147 root 1.18 =head3 EXTENDED GLOB PATTERNS
2148    
2149     Some options of F<staticperl mkbundle> expect an I<extended glob
2150     pattern>. This is neither a normal shell glob nor a regex, but something
2151     in between. The idea has been copied from rsync, and there are the current
2152     matching rules:
2153    
2154     =over 4
2155    
2156     =item Patterns starting with F</> will be a anchored at the root of the library tree.
2157    
2158     That is, F</unicore> will match the F<unicore> directory in C<@INC>, but
2159     nothing inside, and neither any other file or directory called F<unicore>
2160     anywhere else in the hierarchy.
2161    
2162     =item Patterns not starting with F</> will be anchored at the end of the path.
2163    
2164     That is, F<idna.pl> will match any file called F<idna.pl> anywhere in the
2165     hierarchy, but not any directories of the same name.
2166    
2167     =item A F<*> matches any single component.
2168    
2169     That is, F</unicore/*.pl> would match all F<.pl> files directly inside
2170     C</unicore>, not any deeper level F<.pl> files. Or in other words, F<*>
2171     will not match slashes.
2172    
2173     =item A F<**> matches anything.
2174    
2175     That is, F</unicore/**.pl> would match all F<.pl> files under F</unicore>,
2176     no matter how deeply nested they are inside subdirectories.
2177    
2178     =item A F<?> matches a single character within a component.
2179    
2180     That is, F</Encode/??.pm> matches F</Encode/JP.pm>, but not the
2181     hypothetical F</Encode/J/.pm>, as F<?> does not match F</>.
2182    
2183     =back
2184    
2185     =head2 F<STATICPERL> CONFIGURATION AND HOOKS
2186 root 1.2
2187 root 1.19 During (each) startup, F<staticperl> tries to source some shell files to
2188     allow you to fine-tune/override configuration settings.
2189    
2190     In them you can override shell variables, or define shell functions
2191     ("hooks") to be called at specific phases during installation. For
2192     example, you could define a C<postinstall> hook to install additional
2193     modules from CPAN each time you start from scratch.
2194    
2195     If the env variable C<$STATICPERLRC> is set, then F<staticperl> will try
2196     to source the file named with it only. Otherwise, it tries the following
2197     shell files in order:
2198 root 1.2
2199     /etc/staticperlrc
2200     ~/.staticperlrc
2201     $STATICPERL/rc
2202    
2203     Note that the last file is erased during F<staticperl distclean>, so
2204     generally should not be used.
2205    
2206     =head3 CONFIGURATION VARIABLES
2207    
2208     =head4 Variables you I<should> override
2209    
2210     =over 4
2211    
2212     =item C<EMAIL>
2213    
2214     The e-mail address of the person who built this binary. Has no good
2215     default, so should be specified by you.
2216    
2217     =item C<CPAN>
2218    
2219     The URL of the CPAN mirror to use (e.g. L<http://mirror.netcologne.de/cpan/>).
2220    
2221 root 1.6 =item C<EXTRA_MODULES>
2222 root 1.2
2223 root 1.6 Additional modules installed during F<staticperl install>. Here you can
2224     set which modules you want have to installed from CPAN.
2225 root 1.2
2226 root 1.10 Example: I really really need EV, AnyEvent, Coro and AnyEvent::AIO.
2227 root 1.2
2228 root 1.10 EXTRA_MODULES="EV AnyEvent Coro AnyEvent::AIO"
2229 root 1.2
2230 root 1.6 Note that you can also use a C<postinstall> hook to achieve this, and
2231     more.
2232 root 1.2
2233 root 1.10 =back
2234    
2235     =head4 Variables you might I<want> to override
2236    
2237     =over 4
2238    
2239     =item C<STATICPERL>
2240    
2241     The directory where staticperl stores all its files
2242     (default: F<~/.staticperl>).
2243    
2244 root 1.6 =item C<PERL_MM_USE_DEFAULT>, C<EV_EXTRA_DEFS>, ...
2245 root 1.2
2246     Usually set to C<1> to make modules "less inquisitive" during their
2247     installation, you can set any environment variable you want - some modules
2248     (such as L<Coro> or L<EV>) use environment variables for further tweaking.
2249    
2250 root 1.10 =item C<PERL_VERSION>
2251 root 1.6
2252 root 1.10 The perl version to install - default is currently C<5.12.2>, but C<5.8.9>
2253     is also a good choice (5.8.9 is much smaller than 5.12.2, while 5.10.1 is
2254     about as big as 5.12.2).
2255 root 1.2
2256 root 1.10 =item C<PERL_PREFIX>
2257 root 1.2
2258 root 1.6 The prefix where perl gets installed (default: F<$STATICPERL/perl>),
2259     i.e. where the F<bin> and F<lib> subdirectories will end up.
2260 root 1.2
2261 root 1.8 =item C<PERL_CONFIGURE>
2262    
2263     Additional Configure options - these are simply passed to the perl
2264     Configure script. For example, if you wanted to enable dynamic loading,
2265     you could pass C<-Dusedl>. To enable ithreads (Why would you want that
2266     insanity? Don't! Use L<forks> instead!) you would pass C<-Duseithreads>
2267     and so on.
2268    
2269     More commonly, you would either activate 64 bit integer support
2270     (C<-Duse64bitint>), or disable large files support (-Uuselargefiles), to
2271     reduce filesize further.
2272    
2273 root 1.6 =item C<PERL_CPPFLAGS>, C<PERL_OPTIMIZE>, C<PERL_LDFLAGS>, C<PERL_LIBS>
2274 root 1.2
2275 root 1.6 These flags are passed to perl's F<Configure> script, and are generally
2276     optimised for small size (at the cost of performance). Since they also
2277     contain subtle workarounds around various build issues, changing these
2278     usually requires understanding their default values - best look at the top
2279     of the F<staticperl> script for more info on these.
2280 root 1.2
2281     =back
2282    
2283 root 1.5 =head4 Variables you probably I<do not want> to override
2284 root 1.2
2285     =over 4
2286    
2287     =item C<MKBUNDLE>
2288    
2289     Where F<staticperl> writes the C<mkbundle> command to
2290     (default: F<$STATICPERL/mkbundle>).
2291 root 1.1
2292 root 1.2 =item C<STATICPERL_MODULES>
2293 root 1.1
2294 root 1.2 Additional modules needed by C<mkbundle> - should therefore not be changed
2295     unless you know what you are doing.
2296    
2297     =back
2298    
2299     =head3 OVERRIDABLE HOOKS
2300    
2301     In addition to environment variables, it is possible to provide some
2302     shell functions that are called at specific times. To provide your own
2303 root 1.4 commands, just define the corresponding function.
2304 root 1.2
2305     Example: install extra modules from CPAN and from some directories
2306     at F<staticperl install> time.
2307    
2308     postinstall() {
2309 root 1.5 rm -rf lib/threads* # weg mit Schaden
2310 root 1.2 instcpan IO::AIO EV
2311     instsrc ~/src/AnyEvent
2312     instsrc ~/src/XML-Sablotron-1.0100001
2313 root 1.5 instcpan Anyevent::AIO AnyEvent::HTTPD
2314 root 1.2 }
2315    
2316     =over 4
2317    
2318 root 1.11 =item preconfigure
2319    
2320     Called just before running F<./Configur> in the perl source
2321     directory. Current working directory is the perl source directory.
2322    
2323     This can be used to set any C<PERL_xxx> variables, which might be costly
2324     to compute.
2325    
2326 root 1.2 =item postconfigure
2327    
2328     Called after configuring, but before building perl. Current working
2329     directory is the perl source directory.
2330    
2331 root 1.11 Could be used to tailor/patch config.sh (followed by F<sh Configure -S>)
2332     or do any other modifications.
2333 root 1.2
2334     =item postbuild
2335    
2336     Called after building, but before installing perl. Current working
2337     directory is the perl source directory.
2338    
2339     I have no clue what this could be used for - tell me.
2340    
2341     =item postinstall
2342    
2343     Called after perl and any extra modules have been installed in C<$PREFIX>,
2344     but before setting the "installation O.K." flag.
2345    
2346     The current working directory is C<$PREFIX>, but maybe you should not rely
2347     on that.
2348    
2349     This hook is most useful to customise the installation, by deleting files,
2350     or installing extra modules using the C<instcpan> or C<instsrc> functions.
2351    
2352     The script must return with a zero exit status, or the installation will
2353     fail.
2354 root 1.1
2355 root 1.2 =back
2356 root 1.1
2357 root 1.7 =head1 ANATOMY OF A BUNDLE
2358    
2359     When not building a new perl binary, C<mkbundle> will leave a number of
2360     files in the current working directory, which can be used to embed a perl
2361     interpreter in your program.
2362    
2363     Intimate knowledge of L<perlembed> and preferably some experience with
2364     embedding perl is highly recommended.
2365    
2366     C<mkperl> (or the C<--perl> option) basically does this to link the new
2367     interpreter (it also adds a main program to F<bundle.>):
2368    
2369     $Config{cc} $(cat bundle.ccopts) -o perl bundle.c $(cat bundle.ldopts)
2370    
2371     =over 4
2372    
2373     =item bundle.h
2374    
2375     A header file that contains the prototypes of the few symbols "exported"
2376     by bundle.c, and also exposes the perl headers to the application.
2377    
2378     =over 4
2379    
2380     =item staticperl_init ()
2381    
2382     Initialises the perl interpreter. You can use the normal perl functions
2383     after calling this function, for example, to define extra functions or
2384     to load a .pm file that contains some initialisation code, or the main
2385     program function:
2386    
2387     XS (xsfunction)
2388     {
2389     dXSARGS;
2390    
2391     // now we have items, ST(i) etc.
2392     }
2393    
2394     static void
2395     run_myapp(void)
2396     {
2397     staticperl_init ();
2398     newXSproto ("myapp::xsfunction", xsfunction, __FILE__, "$$;$");
2399     eval_pv ("require myapp::main", 1); // executes "myapp/main.pm"
2400     }
2401    
2402     =item staticperl_xs_init (pTHX)
2403    
2404     Sometimes you need direct control over C<perl_parse> and C<perl_run>, in
2405     which case you do not want to use C<staticperl_init> but call them on your
2406     own.
2407    
2408     Then you need this function - either pass it directly as the C<xs_init>
2409     function to C<perl_parse>, or call it from your own C<xs_init> function.
2410    
2411     =item staticperl_cleanup ()
2412    
2413     In the unlikely case that you want to destroy the perl interpreter, here
2414     is the corresponding function.
2415    
2416     =item PerlInterpreter *staticperl
2417    
2418     The perl interpreter pointer used by staticperl. Not normally so useful,
2419     but there it is.
2420    
2421     =back
2422    
2423     =item bundle.ccopts
2424    
2425     Contains the compiler options required to compile at least F<bundle.c> and
2426     any file that includes F<bundle.h> - you should probably use it in your
2427     C<CFLAGS>.
2428    
2429     =item bundle.ldopts
2430    
2431     The linker options needed to link the final program.
2432    
2433     =back
2434    
2435     =head1 RUNTIME FUNCTIONALITY
2436    
2437     Binaries created with C<mkbundle>/C<mkperl> contain extra functions, which
2438     are required to access the bundled perl sources, but might be useful for
2439     other purposes.
2440    
2441     In addition, for the embedded loading of perl files to work, F<staticperl>
2442     overrides the C<@INC> array.
2443    
2444     =over 4
2445    
2446     =item $file = staticperl::find $path
2447    
2448     Returns the data associated with the given C<$path>
2449     (e.g. C<Digest/MD5.pm>, C<auto/POSIX/autosplit.ix>), which is basically
2450     the UNIX path relative to the perl library directory.
2451    
2452     Returns C<undef> if the file isn't embedded.
2453    
2454 root 1.8 =item @paths = staticperl::list
2455 root 1.7
2456     Returns the list of all paths embedded in this binary.
2457    
2458     =back
2459    
2460 root 1.8 =head1 FULLY STATIC BINARIES - BUILDROOT
2461    
2462     To make truly static (Linux-) libraries, you might want to have a look at
2463     buildroot (L<http://buildroot.uclibc.org/>).
2464    
2465     Buildroot is primarily meant to set up a cross-compile environment (which
2466     is not so useful as perl doesn't quite like cross compiles), but it can also compile
2467     a chroot environment where you can use F<staticperl>.
2468    
2469     To do so, download buildroot, and enable "Build options => development
2470     files in target filesystem" and optionally "Build options => gcc
2471     optimization level (optimize for size)". At the time of writing, I had
2472     good experiences with GCC 4.4.x but not GCC 4.5.
2473    
2474     To minimise code size, I used C<-pipe -ffunction-sections -fdata-sections
2475     -finline-limit=8 -fno-builtin-strlen -mtune=i386>. The C<-mtune=i386>
2476     doesn't decrease codesize much, but it makes the file much more
2477     compressible.
2478    
2479     If you don't need Coro or threads, you can go with "linuxthreads.old" (or
2480     no thread support). For Coro, it is highly recommended to switch to a
2481     uClibc newer than 0.9.31 (at the time of this writing, I used the 20101201
2482     snapshot) and enable NPTL, otherwise Coro needs to be configured with the
2483     ultra-slow pthreads backend to work around linuxthreads bugs (it also uses
2484     twice the address space needed for stacks).
2485    
2486     If you use C<linuxthreads.old>, then you should also be aware that
2487     uClibc shares C<errno> between all threads when statically linking. See
2488     L<http://lists.uclibc.org/pipermail/uclibc/2010-June/044157.html> for a
2489     workaround (And L<https://bugs.uclibc.org/2089> for discussion).
2490    
2491 root 1.10 C<ccache> support is also recommended, especially if you want
2492     to play around with buildroot options. Enabling the C<miniperl>
2493     package will probably enable all options required for a successful
2494     perl build. F<staticperl> itself additionally needs either C<wget>
2495     (recommended, for CPAN) or C<curl>.
2496 root 1.8
2497     As for shells, busybox should provide all that is needed, but the default
2498     busybox configuration doesn't include F<comm> which is needed by perl -
2499     either make a custom busybox config, or compile coreutils.
2500    
2501     For the latter route, you might find that bash has some bugs that keep
2502     it from working properly in a chroot - either use dash (and link it to
2503     F</bin/sh> inside the chroot) or link busybox to F</bin/sh>, using it's
2504     built-in ash shell.
2505    
2506     Finally, you need F</dev/null> inside the chroot for many scripts to work
2507     - F<cp /dev/null output/target/dev> or bind-mounting your F</dev> will
2508     both provide this.
2509    
2510     After you have compiled and set up your buildroot target, you can copy
2511     F<staticperl> from the C<App::Staticperl> distribution or from your
2512     perl f<bin> directory (if you installed it) into the F<output/target>
2513     filesystem, chroot inside and run it.
2514    
2515 root 1.18 =head1 RECIPES / SPECIFIC MODULES
2516    
2517     This section contains some common(?) recipes and information about
2518     problems with some common modules or perl constructs that require extra
2519     files to be included.
2520    
2521     =head2 MODULES
2522    
2523     =over 4
2524    
2525     =item utf8
2526    
2527     Some functionality in the utf8 module, such as swash handling (used
2528     for unicode character ranges in regexes) is implemented in the
2529     C<"utf8_heavy.pl"> library:
2530    
2531     -M'"utf8_heavy.pl"'
2532    
2533     Many Unicode properties in turn are defined in separate modules,
2534     such as C<"unicore/Heavy.pl"> and more specific data tables such as
2535     C<"unicore/To/Digit.pl"> or C<"unicore/lib/Perl/Word.pl">. These tables
2536     are big (7MB uncompressed, although F<staticperl> contains special
2537     handling for those files), so including them on demand by your application
2538     only might pay off.
2539    
2540     To simply include the whole unicode database, use:
2541    
2542     --incglob '/unicore/*.pl'
2543    
2544     =item AnyEvent
2545    
2546     AnyEvent needs a backend implementation that it will load in a delayed
2547     fashion. The L<AnyEvent::Impl::Perl> backend is the default choice
2548     for AnyEvent if it can't find anything else, and is usually a safe
2549     fallback. If you plan to use e.g. L<EV> (L<POE>...), then you need to
2550     include the L<AnyEvent::Impl::EV> (L<AnyEvent::Impl::POE>...) backend as
2551     well.
2552    
2553     If you want to handle IRIs or IDNs (L<AnyEvent::Util> punycode and idn
2554     functions), you also need to include C<"AnyEvent/Util/idna.pl"> and
2555     C<"AnyEvent/Util/uts46data.pl">.
2556    
2557 root 1.19 Or you can use C<--usepacklist> and specify C<-MAnyEvent> to include
2558     everything.
2559    
2560 root 1.18 =item Carp
2561    
2562     Carp had (in older versions of perl) a dependency on L<Carp::Heavy>. As of
2563     perl 5.12.2 (maybe earlier), this dependency no longer exists.
2564    
2565     =item Config
2566    
2567     The F<perl -V> switch (as well as many modules) needs L<Config>, which in
2568     turn might need L<"Config_heavy.pl">. Including the latter gives you
2569     both.
2570    
2571     =item Term::ReadLine::Perl
2572    
2573 root 1.19 Also needs L<Term::ReadLine::readline>, or C<--usepacklist>.
2574 root 1.18
2575     =item URI
2576    
2577     URI implements schemes as separate modules - the generic URL scheme is
2578     implemented in L<URI::_generic>, HTTP is implemented in L<URI::http>. If
2579 root 1.19 you need to use any of these schemes, you should include these manually,
2580     or use C<--usepacklist>.
2581 root 1.18
2582     =back
2583    
2584     =head2 RECIPES
2585    
2586     =over 4
2587    
2588     =item Linking everything in
2589    
2590     To link just about everything installed in the perl library into a new
2591     perl, try this:
2592    
2593     staticperl mkperl --strip ppi --incglob '*'
2594    
2595     =item Getting rid of netdb function
2596    
2597     The perl core has lots of netdb functions (C<getnetbyname>, C<getgrent>
2598     and so on) that few applications use. You can avoid compiling them in by
2599     putting the following fragment into a C<preconfigure> hook:
2600    
2601     preconfigure() {
2602     for sym in \
2603     d_getgrnam_r d_endgrent d_endgrent_r d_endhent \
2604     d_endhostent_r d_endnent d_endnetent_r d_endpent \
2605     d_endprotoent_r d_endpwent d_endpwent_r d_endsent \
2606     d_endservent_r d_getgrent d_getgrent_r d_getgrgid_r \
2607     d_getgrnam_r d_gethbyaddr d_gethent d_getsbyport \
2608     d_gethostbyaddr_r d_gethostbyname_r d_gethostent_r \
2609     d_getlogin_r d_getnbyaddr d_getnbyname d_getnent \
2610     d_getnetbyaddr_r d_getnetbyname_r d_getnetent_r \
2611     d_getpent d_getpbyname d_getpbynumber d_getprotobyname_r \
2612     d_getprotobynumber_r d_getprotoent_r d_getpwent \
2613     d_getpwent_r d_getpwnam_r d_getpwuid_r d_getsent \
2614     d_getservbyname_r d_getservbyport_r d_getservent_r \
2615     d_getspnam_r d_getsbyname
2616     # d_gethbyname
2617     do
2618     PERL_CONFIGURE="$PERL_CONFIGURE -U$sym"
2619     done
2620     }
2621    
2622     This mostly gains space when linking staticaly, as the functions will
2623     liekly not be linked in. The gain for dynamically-linked binaries is
2624     smaller.
2625    
2626     Also, this leaves C<gethostbyname> in - not only is it actually used
2627     often, the L<Socket> module also exposes it, so leaving it out usually
2628     gains little. Why Socket exposes a C function that is in the core already
2629     is anybody's guess.
2630    
2631     =back
2632    
2633 root 1.1 =head1 AUTHOR
2634    
2635     Marc Lehmann <schmorp@schmorp.de>
2636     http://software.schmorp.de/pkg/staticperl.html
2637