ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/App-Staticperl/bin/staticperl
Revision: 1.26
Committed: Mon Dec 13 18:08:01 2010 UTC (15 years, 9 months ago) by root
Branch: MAIN
Changes since 1.25: +17 -12 lines
Log Message:
*** empty log message ***

File Contents

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