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