ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/App-Staticperl/bin/staticperl
Revision: 1.19
Committed: Fri Dec 10 20:29:17 2010 UTC (15 years, 10 months ago) by root
Branch: MAIN
Changes since 1.18: +256 -103 lines
Log Message:
*** empty log message ***

File Contents

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