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