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