ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/App-Staticperl/bin/staticperl
Revision: 1.11
Committed: Tue Dec 7 13:23:07 2010 UTC (15 years, 11 months ago) by root
Branch: MAIN
Changes since 1.10: +20 -9 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     CPAN=http://mirror.netcologne.de/cpan/ # which mirror to use
8     EMAIL="read the documentation <rtfm@example.org>"
9    
10     MKBUNDLE="$STATICPERL/mkbundle"
11    
12     # perl build variables
13 root 1.10 PERL_PREFIX="$STATICPERL/perl" # where the perl gets installed
14     PERL_VERSION=5.12.2 # 5.8.9 is also a good choice
15 root 1.8 PERL_CONFIGURE="" # additional Configure arguments
16 root 1.1 PERL_CPPFLAGS="-DPERL_DISABLE_PMC -DPERL_ARENA_SIZE=65536 -D_GNU_SOURCE -DNDEBUG -USITELIB_EXP -USITEARCHEXP -UARCHLIB_EXP"
17     PERL_OPTIMIZE="-Os -ffunction-sections -fdata-sections -finline-limit=8 -ffast-math"
18    
19     ARCH="$(uname -m)"
20    
21     case "$ARCH" in
22     i*86 | x86_64 | amd64 )
23     PERL_OPTIMIZE="$PERL_OPTIMIZE -mpush-args -mno-inline-stringops-dynamically -mno-align-stringops -mno-ieee-fp" # x86/amd64
24     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     # -z muldefs is to work around uclibc's pthread static linking bug
35     PERL_LDFLAGS="-Wl,--no-gc-sections -z muldefs"
36     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     [ -r /etc/staticperlrc ] && . /etc/staticperlrc
58     [ -r ~/.staticperlrc ] && . ~/.staticperlrc
59     [ -r "$STATICPERL/rc" ] && . "$STATICPERL/rc"
60    
61     #############################################################################
62     # support
63    
64     # set version in a way that Makefile.PL can extract
65     VERSION=VERSION; eval \
66     $VERSION=0.1
67    
68     BZ2=bz2
69     BZIP2=bzip2
70    
71     fatal() {
72     printf -- "\nFATAL: %s\n\n" "$*" >&2
73     exit 1
74     }
75    
76     verbose() {
77     printf -- "%s\n" "$*"
78     }
79    
80     verblock() {
81     verbose
82     verbose "***"
83     while read line; do
84     verbose "*** $line"
85     done
86     verbose "***"
87     verbose
88     }
89    
90     rcd() {
91     cd "$1" || fatal "$1: cannot enter"
92     }
93    
94     trace() {
95     prefix="$1"; shift
96     # "$@" 2>&1 | while read line; do
97     # echo "$prefix: $line"
98     # done
99     "$@"
100     }
101    
102     trap wait 0
103    
104     #############################################################################
105     # clean
106    
107     distclean() {
108     verblock <<EOF
109     deleting everything installed by this script
110     EOF
111    
112     rm -rf "$STATICPERL"
113     }
114    
115     #############################################################################
116     # download/configure/compile/install perl
117    
118     clean() {
119 root 1.11 rm -rf "$STATICPERL/src/perl-$PERL_VERSION"
120 root 1.1 }
121    
122     fetch() {
123     rcd "$STATICPERL"
124    
125     mkdir -p src
126     rcd src
127    
128 root 1.10 if ! [ -d "perl-$PERL_VERSION" ]; then
129     if ! [ -e "perl-$PERL_VERSION.tar.$BZ2" ]; then
130 root 1.1
131 root 1.10 URL="$CPAN/src/5.0/perl-$PERL_VERSION.tar.$BZ2"
132 root 1.1
133     verblock <<EOF
134     downloading perl
135     to manually download perl yourself, place
136 root 1.10 perl-$PERL_VERSION.tar.$BZ2 in $STATICPERL
137 root 1.1 trying $URL
138     EOF
139    
140 root 1.10 rm -f perl-$PERL_VERSION.tar.$BZ2~ # just to be on the safe side
141     wget -O perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
142     || curl >perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
143     || fatal "$URL: unable to download"
144     mv perl-$PERL_VERSION.tar.$BZ2~ perl-$PERL_VERSION.tar.$BZ2
145 root 1.1 fi
146    
147     verblock <<EOF
148     unpacking perl
149     EOF
150    
151     mkdir -p unpack
152 root 1.10 $BZIP2 -d <perl-$PERL_VERSION.tar.bz2 | tar xpC unpack \
153     || fatal "perl-$PERL_VERSION.tar.bz2: error during unpacking"
154     mv unpack/perl-$PERL_VERSION perl-$PERL_VERSION
155 root 1.1 rmdir -p unpack
156     fi
157     }
158    
159     # similar to GNU-sed -i or perl -pi
160     sedreplace() {
161     sed -e "$1" <"$2" > "$2~" || fatal "error while running sed"
162     mv "$2~" "$2"
163     }
164    
165     configure() {
166     fetch
167    
168 root 1.10 rcd "$STATICPERL/src/perl-$PERL_VERSION"
169 root 1.1
170     [ -e staticstamp.configure ] && return
171    
172     verblock <<EOF
173 root 1.10 configuring $STATICPERL/src/perl-$PERL_VERSION
174 root 1.1 EOF
175    
176     clean
177    
178 root 1.10 rm -f "$PERL_PREFIX/staticstamp.install"
179 root 1.1
180     # I hate them
181     grep -q -- -fstack-protector Configure && \
182     sedreplace 's/-fstack-protector/-fno-stack-protector/g' Configure
183    
184 root 1.11 preconfigure
185    
186 root 1.1 # trace configure \
187     sh Configure -Duselargefiles \
188     -Uuse64bitint \
189     -Dusemymalloc=n \
190     -Uusedl \
191     -Uusethreads \
192     -Uuseithreads \
193     -Uusemultiplicity \
194     -Duseperlio \
195     -Uusesfio \
196     -Uuseshrplib \
197     -Dcppflags="$PERL_CPPFLAGS" \
198     -Dccflags="-g2 -fno-strict-aliasing" \
199     -Doptimize="$PERL_OPTIMIZE" \
200     -Dldflags="$PERL_LDFLAGS" \
201     -Dlibs="$PERL_LIBS" \
202 root 1.10 -Dprefix="$PERL_PREFIX" \
203     -Dbin="$PERL_PREFIX/bin" \
204     -Dprivlib="$PERL_PREFIX/lib" \
205     -Darchlib="$PERL_PREFIX/lib" \
206 root 1.1 -Uusevendorprefix \
207 root 1.10 -Dsitelib="$PERL_PREFIX/lib" \
208     -Dsitearch="$PERL_PREFIX/lib" \
209 root 1.1 -Usitelibexp \
210     -Uman1dir \
211     -Uman3dir \
212     -Usiteman1dir \
213     -Usiteman3dir \
214     -Dpager=/usr/bin/less \
215     -Demail="$EMAIL" \
216     -Dcf_email="$EMAIL" \
217     -Dcf_by="$EMAIL" \
218 root 1.8 $PERL_CONFIGURE \
219 root 1.1 -dE || fatal "Configure failed"
220    
221     sedreplace '
222     s/-Wl,--no-gc-sections/-Wl,--gc-sections/g
223     s/ *-fno-stack-protector */ /g
224     ' config.sh
225    
226     sh Configure -S || fatal "Configure -S failed"
227    
228     postconfigure || fatal "postconfigure hook failed"
229    
230     touch staticstamp.configure
231     }
232    
233     build() {
234     configure
235    
236 root 1.10 rcd "$STATICPERL/src/perl-$PERL_VERSION"
237 root 1.1
238     verblock <<EOF
239 root 1.10 building $STATICPERL/src/perl-$PERL_VERSION
240 root 1.1 EOF
241    
242 root 1.10 rm -f "$PERL_PREFIX/staticstamp.install"
243 root 1.1
244     make || fatal "make: error while building perl"
245    
246     postbuild || fatal "postbuild hook failed"
247     }
248    
249     install() {
250 root 1.10 [ -e "$PERL_PREFIX/staticstamp.install" ] && return
251 root 1.1
252     build
253    
254     verblock <<EOF
255 root 1.10 installing $STATICPERL/src/perl-$PERL_VERSION
256     to $PERL_PREFIX
257 root 1.1 EOF
258    
259 root 1.10 rm -rf "$PERL_PREFIX"
260 root 1.1
261     make install || fatal "make install: error while installing"
262    
263 root 1.10 rcd "$PERL_PREFIX"
264 root 1.2
265 root 1.1 # create a "make install" replacement for CPAN
266 root 1.10 cat >"$PERL_PREFIX"/bin/cpan-make-install <<EOF
267 root 1.1 make install UNINST=1
268     if find blib/arch/auto -type f | grep -q -v .exists; then
269     echo Probably an XS module, rebuilding perl
270     make perl
271 root 1.10 rm -f "$PERL_PREFIX"/bin/perl
272 root 1.1 make -f Makefile.aperl inst_perl
273     make -f Makefile.aperl map_clean
274     fi
275     EOF
276 root 1.10 chmod 755 "$PERL_PREFIX"/bin/cpan-make-install
277 root 1.1
278 root 1.4 # trick CPAN into avoiding ~/.cpan completely
279 root 1.10 echo 1 >"$PERL_PREFIX/lib/CPAN/MyConfig.pm"
280 root 1.2
281 root 1.10 "$PERL_PREFIX"/bin/perl -MCPAN -e '
282 root 1.1 CPAN::Shell->o (conf => urllist => push => "'"$CPAN"'");
283 root 1.2 CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
284 root 1.1 CPAN::Shell->o (conf => q<init>);
285     CPAN::Shell->o (conf => q<cpan_home>, "'"$STATICPERL"'/cpan");
286     CPAN::Shell->o (conf => q<build_dir>, "'"$STATICPERL"'/cpan/build");
287     CPAN::Shell->o (conf => q<prefs_dir>, "'"$STATICPERL"'/cpan/prefs");
288     CPAN::Shell->o (conf => q<histfile> , "'"$STATICPERL"'/cpan/histfile");
289     CPAN::Shell->o (conf => q<keep_source_where>, "'"$STATICPERL"'/cpan/sources");
290 root 1.10 CPAN::Shell->o (conf => q<make_install_make_command>, "'"$PERL_PREFIX"'/bin/cpan-make-install");
291 root 1.1 CPAN::Shell->o (conf => q<prerequisites_policy>, q<follow>);
292     CPAN::Shell->o (conf => q<build_requires_install_policy>, q<no>);
293     CPAN::Shell->o (conf => q<commit>);
294     ' || fatal "error while initialising CPAN"
295    
296     NOCHECK_INSTALL=+
297 root 1.2 instcpan $STATICPERL_MODULES
298     [ $EXTRA_MODULES ] && instcpan $EXTRA_MODULES
299 root 1.1
300     postinstall || fatal "postinstall hook failed"
301    
302 root 1.10 touch "$PERL_PREFIX/staticstamp.install"
303 root 1.1 }
304    
305     #############################################################################
306     # install a module from CPAN
307    
308     instcpan() {
309     [ $NOCHECK_INSTALL ] || install
310    
311     verblock <<EOF
312     installing modules from CPAN
313     $@
314     EOF
315    
316     for mod in "$@"; do
317 root 1.10 "$PERL_PREFIX"/bin/perl -MCPAN -e 'notest install => "'"$mod"'"' \
318 root 1.1 || fatal "$mod: unable to install from CPAN"
319     done
320     rm -rf "$STATICPERL/build"
321     }
322    
323     #############################################################################
324     # install a module from unpacked sources
325    
326     instsrc() {
327     [ $NOCHECK_INSTALL ] || install
328    
329     verblock <<EOF
330     installing modules from source
331     $@
332     EOF
333    
334     for mod in "$@"; do
335     echo
336     echo $mod
337     (
338     rcd $mod
339     make -f Makefile.aperl map_clean >/dev/null 2>&1
340     make distclean >/dev/null 2>&1
341 root 1.10 "$PERL_PREFIX"/bin/perl Makefile.PL || fatal "$mod: error running Makefile.PL"
342 root 1.1 make || fatal "$mod: error building module"
343 root 1.10 "$PERL_PREFIX"/bin/cpan-make-install || fatal "$mod: error installing module"
344 root 1.1 make distclean >/dev/null 2>&1
345     exit 0
346     ) || exit $?
347     done
348     }
349    
350     #############################################################################
351     # main
352    
353     podusage() {
354     echo
355 root 1.10 if [ -e "$PERL_PREFIX/bin/perl" ]; then
356     "$PERL_PREFIX/bin/perl" -MPod::Usage -e \
357 root 1.1 'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
358     2>/dev/null && exit
359     fi
360     # try whatever perl we can find
361     perl -MPod::Usage -e \
362     'pod2usage -input => *STDIN, -output => *STDOUT, -verbose => '$1', -exitval => 0, -noperldoc => 1' <"$0" \
363     2>/dev/null && exit
364    
365     fatal "displaying documentation requires a working perl - try '$0 install' first"
366     }
367    
368     usage() {
369     podusage 0
370     }
371    
372     catmkbundle() {
373     {
374     read dummy
375 root 1.10 echo "#!$PERL_PREFIX/bin/perl"
376 root 1.1 cat
377     } <<'MKBUNDLE'
378     #!/opt/bin/perl
379    
380     #############################################################################
381     # cannot load modules till after the tracer BEGIN block
382    
383     our $VERBOSE = 1;
384     our $STRIP = "pod"; # none, pod or ppi
385     our $PERL = 0;
386     our $VERIFY = 0;
387     our $STATIC = 0;
388    
389     my $PREFIX = "bundle";
390     my $PACKAGE = "static";
391    
392     my %pm;
393 root 1.8 my %pmbin;
394 root 1.1 my @libs;
395     my @static_ext;
396     my $extralibs;
397    
398     @ARGV
399     or die "$0: use 'staticperl help' (or read the sources of staticperl)\n";
400    
401     $|=1;
402    
403     our ($TRACER_W, $TRACER_R);
404    
405     sub find_inc($) {
406     for (@INC) {
407     next if ref;
408     return $_ if -e "$_/$_[0]";
409     }
410    
411     undef
412     }
413    
414     BEGIN {
415     # create a loader process to detect @INC requests before we load any modules
416     my ($W_TRACER, $R_TRACER); # used by tracer
417    
418     pipe $R_TRACER, $TRACER_W or die "pipe: $!";
419     pipe $TRACER_R, $W_TRACER or die "pipe: $!";
420    
421     unless (fork) {
422     close $TRACER_R;
423     close $TRACER_W;
424    
425     unshift @INC, sub {
426     my $dir = find_inc $_[1]
427     or return;
428    
429     syswrite $W_TRACER, "-\n$dir\n$_[1]\n";
430    
431     open my $fh, "<:perlio", "$dir/$_[1]"
432     or warn "ERROR: $dir/$_[1]: $!\n";
433    
434     $fh
435     };
436    
437     while (<$R_TRACER>) {
438     if (/use (.*)$/) {
439     my $mod = $1;
440     eval "require $mod";
441     warn "ERROR: $@ (while loading '$mod')\n"
442     if $@;
443     syswrite $W_TRACER, "\n";
444     } elsif (/eval (.*)$/) {
445     my $eval = $1;
446     eval $eval;
447     warn "ERROR: $@ (in '$eval')\n"
448     if $@;
449     }
450     }
451    
452     exit 0;
453     }
454     }
455    
456     # module loading is now safe
457     use Config;
458    
459 root 1.7 sub scan_al {
460     my ($auto, $autodir, $ix) = @_;
461    
462     $pm{"$auto/$ix"} = "$autodir/$ix";
463    
464 root 1.8 open my $fh, "<:perlio", "$autodir/$ix"
465 root 1.7 or die "$autodir/$ix: $!";
466    
467     my $package;
468    
469     while (<$fh>) {
470     if (/^\s*sub\s+([^[:space:];]+)\s*;?\s*$/) {
471     my $al = "auto/$package/$1.al";
472     my $inc = find_inc $al;
473    
474     defined $inc or die "$al: autoload file not found, but should be there.\n";
475    
476     $pm{$al} = "$inc/$al";
477    
478     } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) {
479     ($package = $1) =~ s/::/\//g;
480     } elsif (/^\s*(?:#|1?\s*;?\s*$)/) {
481     # nop
482     } else {
483     warn "$autodir/$ix: unparsable line, please report: $_";
484     }
485     }
486     }
487    
488 root 1.1 sub trace_module {
489     syswrite $TRACER_W, "use $_[0]\n";
490    
491     for (;;) {
492     <$TRACER_R> =~ /^-$/ or last;
493     my $dir = <$TRACER_R>; chomp $dir;
494     my $name = <$TRACER_R>; chomp $name;
495    
496     $pm{$name} = "$dir/$name";
497    
498     if ($name =~ /^(.*)\.pm$/) {
499     my $auto = "auto/$1";
500     my $autodir = "$dir/$auto";
501    
502     if (-d $autodir) {
503     opendir my $dir, $autodir
504     or die "$autodir: $!\n";
505    
506     for (readdir $dir) {
507     # AutoLoader
508 root 1.7 scan_al $auto, $autodir, $_
509     if /\.ix$/;
510 root 1.1
511     # static ext
512     if (/\Q$Config{_a}\E$/o) {
513     push @libs, "$autodir/$_";
514     push @static_ext, $name;
515     }
516    
517     # extralibs.ld
518     if ($_ eq "extralibs.ld") {
519     open my $fh, "<:perlio", "$autodir/$_"
520     or die "$autodir/$_";
521    
522     local $/;
523     $extralibs .= " " . <$fh>;
524     }
525    
526     # dynamic object
527     warn "WARNING: found shared object - can't link statically ($_)\n"
528     if /\.\Q$Config{dlext}\E$/o;
529     }
530     }
531     }
532     }
533     }
534    
535     sub trace_eval {
536     syswrite $TRACER_W, "eval $_[0]\n";
537     }
538    
539     sub trace_finish {
540     close $TRACER_W;
541     close $TRACER_R;
542     }
543    
544     #############################################################################
545     # now we can use modules
546    
547     use common::sense;
548     use Digest::MD5;
549    
550     sub dump_string {
551     my ($fh, $data) = @_;
552    
553     if (length $data) {
554     for (
555     my $ofs = 0;
556     length (my $substr = substr $data, $ofs, 80);
557     $ofs += 80
558     ) {
559     $substr =~ s/([^\x20-\x21\x23-\x5b\x5d-\x7e])/sprintf "\\%03o", ord $1/ge;
560     $substr =~ s/\?/\\?/g; # trigraphs...
561     print $fh " \"$substr\"\n";
562     }
563     } else {
564     print $fh " \"\"\n";
565     }
566     }
567    
568     # required for @INC loading, unfortunately
569     trace_module "PerlIO::scalar";
570    
571     #trace_module "Term::ReadLine::readline"; # Term::ReadLine::Perl dependency
572     # URI is difficult
573     #trace_module "URI::http";
574     #trace_module "URI::_generic";
575    
576     sub cmd_boot {
577     $pm{"//boot"} = $_[0];
578     }
579    
580     sub cmd_add {
581 root 1.3 $_[0] =~ /^(.*)(?:\s+(\S+))$/
582 root 1.1 or die "$_[0]: cannot parse";
583    
584     my $file = $1;
585     my $as = defined $2 ? $2 : "/$1";
586    
587     $pm{$as} = $file;
588 root 1.8 $pmbin{$as} = 1 if $_[1];
589 root 1.1 }
590    
591     sub cmd_file {
592     open my $fh, "<", $_[0]
593     or die "$_[0]: $!\n";
594    
595     while (<$fh>) {
596     chomp;
597     my ($cmd, $args) = split / /, $_, 2;
598 root 1.2 $cmd =~ s/^-+//;
599 root 1.1
600     if ($cmd eq "strip") {
601     $STRIP = $args;
602     } elsif ($cmd eq "eval") {
603     trace_eval $_;
604     } elsif ($cmd eq "use") {
605     trace_module $_
606     for split / /, $args;
607     } elsif ($cmd eq "boot") {
608     cmd_boot $args;
609     } elsif ($cmd eq "static") {
610     $STATIC = 1;
611     } elsif ($cmd eq "add") {
612 root 1.8 cmd_add $args, 0;
613     } elsif ($cmd eq "addbin") {
614     cmd_add $args, 1;
615 root 1.1 } elsif (/^\s*#/) {
616     # comment
617     } elsif (/\S/) {
618     die "$_: unsupported directive\n";
619     }
620     }
621     }
622    
623     use Getopt::Long;
624    
625     Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case");
626    
627     GetOptions
628     "strip=s" => \$STRIP,
629     "verbose|v" => sub { ++$VERBOSE },
630     "quiet|q" => sub { --$VERBOSE },
631     "perl" => \$PERL,
632 root 1.2 "eval|e=s" => sub { trace_eval $_[1] },
633 root 1.1 "use|M=s" => sub { trace_module $_[1] },
634     "boot=s" => sub { cmd_boot $_[1] },
635 root 1.8 "add=s" => sub { cmd_add $_[1], 0 },
636     "addbin=s" => sub { cmd_add $_[1], 1 },
637 root 1.1 "static" => sub { $STATIC = 1 },
638 root 1.4 "<>" => sub { cmd_file $_[0] },
639 root 1.1 or exit 1;
640    
641     my $data;
642     my @index;
643     my @order = sort {
644     length $a <=> length $b
645     or $a cmp $b
646     } keys %pm;
647    
648     # sorting by name - better compression, but needs more metadata
649     # sorting by length - faster lookup
650     # usually, the metadata overhead beats the loss through compression
651    
652     for my $pm (@order) {
653     my $path = $pm{$pm};
654    
655     128 > length $pm
656     or die "$pm: path too long (only 128 octets supported)\n";
657    
658     my $src = ref $path
659     ? $$path
660     : do {
661 root 1.7 open my $pm, "<", $path
662 root 1.1 or die "$path: $!";
663    
664     local $/;
665    
666     <$pm>
667     };
668    
669 root 1.8 unless ($pmbin{$pm}) { # only do this unless the file is binary
670    
671     if ($pm =~ /^auto\/POSIX\/[^\/]+\.al$/) {
672     if ($src =~ /^ unimpl \"/m) {
673     warn "$pm: skipping (not implemented anyways).\n"
674     if $VERBOSE >= 2;
675     next;
676     }
677 root 1.1 }
678    
679 root 1.8 if ($STRIP =~ /ppi/i) {
680     require PPI;
681 root 1.1
682 root 1.8 my $ppi = PPI::Document->new (\$src);
683     $ppi->prune ("PPI::Token::Comment");
684     $ppi->prune ("PPI::Token::Pod");
685    
686     # prune END stuff
687     for (my $last = $ppi->last_element; $last; ) {
688     my $prev = $last->previous_token;
689    
690     if ($last->isa (PPI::Token::Whitespace::)) {
691     $last->delete;
692     } elsif ($last->isa (PPI::Statement::End::)) {
693     $last->delete;
694     last;
695     } elsif ($last->isa (PPI::Token::Pod::)) {
696     $last->delete;
697     } else {
698     last;
699     }
700    
701     $last = $prev;
702 root 1.1 }
703    
704 root 1.8 # prune some but not all insignificant whitespace
705     for my $ws (@{ $ppi->find (PPI::Token::Whitespace::) }) {
706     my $prev = $ws->previous_token;
707     my $next = $ws->next_token;
708 root 1.1
709 root 1.8 if (!$prev || !$next) {
710 root 1.1 $ws->delete;
711     } else {
712 root 1.8 if (
713     $next->isa (PPI::Token::Operator::) && $next->{content} =~ /^(?:,|=|!|!=|==|=>)$/ # no ., because of digits. == float
714     or $prev->isa (PPI::Token::Operator::) && $prev->{content} =~ /^(?:,|=|\.|!|!=|==|=>)$/
715     or $prev->isa (PPI::Token::Structure::)
716     # decrease size, decrease compressability
717     #or ($prev->isa (PPI::Token::Word::)
718     # && (PPI::Token::Symbol:: eq ref $next
719     # || $next->isa (PPI::Structure::Block::)
720     # || $next->isa (PPI::Structure::List::)
721     # || $next->isa (PPI::Structure::Condition::)))
722     ) {
723     $ws->delete;
724     } elsif ($prev->isa (PPI::Token::Whitespace::)) {
725     $ws->{content} = ' ';
726     $prev->delete;
727     } else {
728     $ws->{content} = ' ';
729     }
730 root 1.1 }
731     }
732    
733 root 1.8 # prune whitespace around blocks
734     if (0) {
735     # these usually decrease size, but decrease compressability more
736     for my $struct (PPI::Structure::Block::, PPI::Structure::Condition::) {
737     for my $node (@{ $ppi->find ($struct) }) {
738     my $n1 = $node->first_token;
739     my $n2 = $n1->previous_token;
740     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
741     $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
742     my $n1 = $node->last_token;
743     my $n2 = $n1->next_token;
744     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
745     $n2->delete if $n2 && $n2->isa (PPI::Token::Whitespace::);
746     }
747     }
748    
749     for my $node (@{ $ppi->find (PPI::Structure::List::) }) {
750 root 1.1 my $n1 = $node->first_token;
751     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
752     my $n1 = $node->last_token;
753     $n1->delete if $n1->isa (PPI::Token::Whitespace::);
754     }
755     }
756    
757 root 1.8 # reformat qw() lists which often have lots of whitespace
758     for my $node (@{ $ppi->find (PPI::Token::QuoteLike::Words::) }) {
759     if ($node->{content} =~ /^qw(.)(.*)(.)$/s) {
760     my ($a, $qw, $b) = ($1, $2, $3);
761     $qw =~ s/^\s+//;
762     $qw =~ s/\s+$//;
763     $qw =~ s/\s+/ /g;
764     $node->{content} = "qw$a$qw$b";
765     }
766 root 1.1 }
767 root 1.8
768     $src = $ppi->serialize;
769     } elsif ($STRIP =~ /pod/i && $pm ne "Opcode.pm") { # opcode parses it's own pod
770     require Pod::Strip;
771    
772     my $stripper = Pod::Strip->new;
773    
774     my $out;
775     $stripper->output_string (\$out);
776     $stripper->parse_string_document ($src)
777     or die;
778     $src = $out;
779 root 1.1 }
780    
781 root 1.8 if ($VERIFY && $pm =~ /\.pm$/ && $pm ne "Opcode.pm") {
782     if (open my $fh, "-|") {
783     <$fh>;
784     } else {
785     eval "#line 1 \"$pm\"\n$src" or warn "\n\n\n$pm\n\n$src\n$@\n\n\n";
786     exit 0;
787 root 1.1 }
788     }
789    
790 root 1.8 # if ($pm eq "Opcode.pm") {
791     # open my $fh, ">x" or die; print $fh $src;#d#
792     # exit 1;
793     # }
794 root 1.1 }
795    
796     warn "adding $pm\n"
797     if $VERBOSE >= 2;
798    
799     push @index, ((length $pm) << 25) | length $data;
800     $data .= $pm . $src;
801     }
802    
803     length $data < 2**25
804     or die "bundle too large (only 32MB supported)\n";
805    
806     my $varpfx = "bundle_" . substr +(Digest::MD5::md5_hex $data), 0, 16;
807    
808     #############################################################################
809     # output
810    
811     print "generating $PREFIX.h... ";
812    
813     {
814     open my $fh, ">", "$PREFIX.h"
815     or die "$PREFIX.h: $!\n";
816    
817     print $fh <<EOF;
818     /* do not edit, automatically created by mkstaticbundle */
819 root 1.8
820 root 1.1 #include <EXTERN.h>
821     #include <perl.h>
822     #include <XSUB.h>
823    
824     /* public API */
825     EXTERN_C PerlInterpreter *staticperl;
826 root 1.7 EXTERN_C void staticperl_xs_init (pTHX);
827 root 1.1 EXTERN_C void staticperl_init (void);
828     EXTERN_C void staticperl_cleanup (void);
829 root 1.8
830 root 1.1 EOF
831     }
832    
833     print "\n";
834    
835     #############################################################################
836     # output
837    
838     print "generating $PREFIX.c... ";
839    
840     open my $fh, ">", "$PREFIX.c"
841     or die "$PREFIX.c: $!\n";
842    
843     print $fh <<EOF;
844     /* do not edit, automatically created by mkstaticbundle */
845    
846     #include "bundle.h"
847    
848     /* public API */
849     PerlInterpreter *staticperl;
850    
851     EOF
852    
853     #############################################################################
854     # bundle data
855    
856     my $count = @index;
857    
858     print $fh <<EOF;
859     #include "bundle.h"
860    
861     /* bundle data */
862    
863     static const U32 $varpfx\_count = $count;
864     static const U32 $varpfx\_index [$count + 1] = {
865     EOF
866    
867     my $col;
868     for (@index) {
869     printf $fh "0x%08x,", $_;
870     print $fh "\n" unless ++$col % 10;
871    
872     }
873     printf $fh "0x%08x\n};\n", (length $data);
874    
875     print $fh "static const char $varpfx\_data [] =\n";
876     dump_string $fh, $data;
877    
878     print $fh ";\n\n";;
879    
880     #############################################################################
881     # bootstrap
882    
883     # boot file for staticperl
884     # this file will be eval'ed at initialisation time
885    
886     my $bootstrap = '
887     BEGIN {
888     package ' . $PACKAGE . ';
889    
890     PerlIO::scalar->bootstrap;
891    
892     @INC = sub {
893     my $data = find "$_[1]"
894     or return;
895    
896     $INC{$_[1]} = $_[1];
897    
898     open my $fh, "<", \$data;
899     $fh
900     };
901     }
902     ';
903    
904     $bootstrap .= "require '//boot';"
905     if exists $pm{"//boot"};
906    
907     $bootstrap =~ s/\s+/ /g;
908     $bootstrap =~ s/(\W) /$1/g;
909     $bootstrap =~ s/ (\W)/$1/g;
910    
911     print $fh "const char bootstrap [] = ";
912     dump_string $fh, $bootstrap;
913     print $fh ";\n\n";
914    
915     print $fh <<EOF;
916     /* search all bundles for the given file, using binary search */
917     XS(find)
918     {
919     dXSARGS;
920    
921     if (items != 1)
922     Perl_croak (aTHX_ "Usage: $PACKAGE\::find (\$path)");
923    
924     {
925     STRLEN namelen;
926     char *name = SvPV (ST (0), namelen);
927     SV *res = 0;
928    
929     int l = 0, r = $varpfx\_count;
930    
931     while (l <= r)
932     {
933     int m = (l + r) >> 1;
934     U32 idx = $varpfx\_index [m];
935     int comp = namelen - (idx >> 25);
936    
937     if (!comp)
938     {
939     int ofs = idx & 0x1FFFFFFU;
940     comp = memcmp (name, $varpfx\_data + ofs, namelen);
941    
942     if (!comp)
943     {
944     /* found */
945     int ofs2 = $varpfx\_index [m + 1] & 0x1FFFFFFU;
946    
947     ofs += namelen;
948     res = newSVpvn ($varpfx\_data + ofs, ofs2 - ofs);
949     goto found;
950     }
951     }
952    
953     if (comp < 0)
954     r = m - 1;
955     else
956     l = m + 1;
957     }
958    
959     XSRETURN (0);
960    
961     found:
962     ST (0) = res;
963     sv_2mortal (ST (0));
964     }
965    
966     XSRETURN (1);
967     }
968    
969     /* list all files in the bundle */
970     XS(list)
971     {
972     dXSARGS;
973    
974     if (items != 0)
975     Perl_croak (aTHX_ "Usage: $PACKAGE\::list");
976    
977     {
978     int i;
979    
980     EXTEND (SP, $varpfx\_count);
981    
982     for (i = 0; i < $varpfx\_count; ++i)
983     {
984     U32 idx = $varpfx\_index [i];
985    
986     PUSHs (newSVpvn ($varpfx\_data + (idx & 0x1FFFFFFU), idx >> 25));
987     }
988     }
989    
990     XSRETURN ($varpfx\_count);
991     }
992    
993     static char *args[] = {
994     "staticperl",
995     "-e",
996     "0"
997     };
998    
999     EOF
1000    
1001     #############################################################################
1002     # xs_init
1003    
1004     print $fh <<EOF;
1005 root 1.7 void
1006     staticperl_xs_init (pTHX)
1007 root 1.1 {
1008     EOF
1009    
1010     @static_ext = ("DynaLoader", sort @static_ext);
1011    
1012     # prototypes
1013     for (@static_ext) {
1014     s/\.pm$//;
1015     (my $cname = $_) =~ s/\//__/g;
1016     print $fh " EXTERN_C void boot_$cname (pTHX_ CV* cv);\n";
1017     }
1018    
1019     print $fh <<EOF;
1020     char *file = __FILE__;
1021     dXSUB_SYS;
1022    
1023     newXSproto ("$PACKAGE\::find", find, file, "\$");
1024     newXSproto ("$PACKAGE\::list", list, file, "");
1025     EOF
1026    
1027     # calls
1028     for (@static_ext) {
1029     s/\.pm$//;
1030    
1031     (my $cname = $_) =~ s/\//__/g;
1032     (my $pname = $_) =~ s/\//::/g;
1033    
1034     my $bootstrap = $pname eq "DynaLoader" ? "boot" : "bootstrap";
1035    
1036     print $fh " newXS (\"$pname\::$bootstrap\", boot_$cname, file);\n";
1037     }
1038    
1039     print $fh <<EOF;
1040     Perl_av_create_and_unshift_one (&PL_preambleav, newSVpv (bootstrap, sizeof (bootstrap) - 1));
1041     }
1042     EOF
1043    
1044     #############################################################################
1045     # optional perl_init/perl_destroy
1046    
1047     if ($PERL) {
1048     print $fh <<EOF;
1049    
1050     int
1051     main (int argc, char *argv [])
1052     {
1053     extern char **environ;
1054     int exitstatus;
1055    
1056     PERL_SYS_INIT3 (&argc, &argv, &environ);
1057     staticperl = perl_alloc ();
1058     perl_construct (staticperl);
1059    
1060     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1061    
1062 root 1.7 exitstatus = perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
1063 root 1.1 if (!exitstatus)
1064     perl_run (staticperl);
1065    
1066     exitstatus = perl_destruct (staticperl);
1067     perl_free (staticperl);
1068     PERL_SYS_TERM ();
1069    
1070     return exitstatus;
1071     }
1072     EOF
1073     } else {
1074     print $fh <<EOF;
1075    
1076     EXTERN_C void
1077     staticperl_init (void)
1078     {
1079     extern char **environ;
1080     int argc = sizeof (args) / sizeof (args [0]);
1081     char **argv = args;
1082    
1083     PERL_SYS_INIT3 (&argc, &argv, &environ);
1084     staticperl = perl_alloc ();
1085     perl_construct (staticperl);
1086     PL_origalen = 1;
1087     PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
1088 root 1.7 perl_parse (staticperl, staticperl_xs_init, argc, argv, environ);
1089 root 1.1
1090     perl_run (staticperl);
1091     }
1092    
1093     EXTERN_C void
1094     staticperl_cleanup (void)
1095     {
1096     perl_destruct (staticperl);
1097     perl_free (staticperl);
1098     staticperl = 0;
1099     PERL_SYS_TERM ();
1100     }
1101     EOF
1102     }
1103    
1104     print -s "$PREFIX.c", " octets (", (length $data) , " data octets).\n\n";
1105    
1106     #############################################################################
1107     # libs, cflags
1108    
1109     {
1110     print "generating $PREFIX.ccopts... ";
1111    
1112     my $str = "$Config{ccflags} $Config{optimize} $Config{cppflags} -I$Config{archlibexp}/CORE";
1113     $str =~ s/([\(\)])/\\$1/g;
1114    
1115     print "$str\n\n";
1116    
1117     open my $fh, ">$PREFIX.ccopts"
1118     or die "$PREFIX.ccopts: $!";
1119     print $fh $str;
1120     }
1121    
1122     {
1123     print "generating $PREFIX.ldopts... ";
1124    
1125     my $str = $STATIC ? "--static " : "";
1126    
1127     $str .= "$Config{ccdlflags} $Config{ldflags} @libs $Config{archlibexp}/CORE/$Config{libperl} $Config{perllibs}";
1128    
1129     my %seen;
1130     $str .= " $_" for grep !$seen{$_}++, ($extralibs =~ /(\S+)/g);
1131    
1132     $str =~ s/([\(\)])/\\$1/g;
1133    
1134     print "$str\n\n";
1135    
1136     open my $fh, ">$PREFIX.ldopts"
1137     or die "$PREFIX.ldopts: $!";
1138     print $fh $str;
1139     }
1140    
1141     if ($PERL) {
1142     system "$Config{cc} \$(cat bundle.ccopts\) -o perl bundle.c \$(cat bundle.ldopts\)";
1143    
1144     unlink "$PREFIX.$_"
1145     for qw(ccopts ldopts c h);
1146     }
1147    
1148     MKBUNDLE
1149     }
1150    
1151     bundle() {
1152     catmkbundle >"$MKBUNDLE~" || fatal "$MKBUNDLE~: cannot create"
1153     chmod 755 "$MKBUNDLE~" && mv "$MKBUNDLE~" "$MKBUNDLE"
1154 root 1.10 "$PERL_PREFIX/bin/perl" -- "$MKBUNDLE" "$@"
1155 root 1.1 }
1156    
1157     if [ $# -gt 0 ]; then
1158     while [ $# -gt 0 ]; do
1159     mkdir -p "$STATICPERL" || fatal "$STATICPERL: cannot create"
1160 root 1.10 mkdir -p "$PERL_PREFIX" || fatal "$PERL_PREFIX: cannot create"
1161 root 1.1
1162     command="${1#--}"; shift
1163     case "$command" in
1164     fetch | configure | build | install | clean | distclean)
1165     verblock <<EOF
1166     $command
1167     EOF
1168 root 1.10 ( "$command" )
1169 root 1.1 ;;
1170     instsrc )
1171 root 1.10 ( instsrc "$@" )
1172 root 1.1 exit
1173     ;;
1174     instcpan )
1175 root 1.10 ( instcpan "$@" )
1176 root 1.1 exit
1177     ;;
1178     cpan )
1179 root 1.10 ( install )
1180     "$PERL_PREFIX/bin/cpan" "$@"
1181 root 1.1 exit
1182     ;;
1183     mkbundle )
1184 root 1.10 ( install )
1185 root 1.1 bundle "$@"
1186     exit
1187     ;;
1188     mkperl )
1189 root 1.10 ( install )
1190 root 1.1 bundle --perl "$@"
1191     exit
1192     ;;
1193     help )
1194     podusage 2
1195     ;;
1196     * )
1197     exec 1>&2
1198     echo
1199     echo "Unknown command: $command"
1200     podusage 0
1201     ;;
1202     esac
1203     done
1204     else
1205     usage
1206     fi
1207    
1208     exit 0
1209    
1210     =head1 NAME
1211    
1212 root 1.7 staticperl - perl, libc, 100 modules, all in one 500kb file
1213 root 1.1
1214     =head1 SYNOPSIS
1215    
1216     staticperl help # print the embedded documentation
1217     staticperl fetch # fetch and unpack perl sources
1218     staticperl configure # fetch and then configure perl
1219     staticperl build # configure and then build perl
1220     staticperl install # build and then install perl
1221     staticperl clean # clean most intermediate files (restart at configure)
1222     staticperl distclean # delete everything installed by this script
1223     staticperl cpan # invoke CPAN shell
1224     staticperl instmod path... # install unpacked modules
1225     staticperl instcpan modulename... # install modules from CPAN
1226     staticperl mkbundle <bundle-args...> # see documentation
1227     staticperl mkperl <bundle-args...> # see documentation
1228    
1229     Typical Examples:
1230    
1231     staticperl install # fetch, configure, build and install perl
1232     staticperl cpan # run interactive cpan shell
1233     staticperl mkperl -M '"Config_heavy.pl"' # build a perl that supports -V
1234     staticperl mkperl -MAnyEvent::Impl::Perl -MAnyEvent::HTTPD -MURI -MURI::http
1235     # build a perl with the above modules linked in
1236    
1237     =head1 DESCRIPTION
1238    
1239     This script helps you creating single-file perl interpreters, or embedding
1240 root 1.4 a perl interpreter in your applications. Single-file means that it is
1241     fully self-contained - no separate shared objects, no autoload fragments,
1242     no .pm or .pl files are needed. And when linking statically, you can
1243     create (or embed) a single file that contains perl interpreter, libc, all
1244     the modules you need and all the libraries you need.
1245 root 1.1
1246 root 1.7 With F<uClibc> and F<upx> on x86, you can create a single 500kb binary
1247     that contains perl and 100 modules such as POSIX, AnyEvent, EV, IO::AIO,
1248     Coro and so on. Or any other choice of modules.
1249 root 1.1
1250 root 1.4 The created files do not need write access to the file system (like PAR
1251 root 1.1 does). In fact, since this script is in many ways similar to PAR::Packer,
1252     here are the differences:
1253    
1254     =over 4
1255    
1256     =item * The generated executables are much smaller than PAR created ones.
1257    
1258     Shared objects and the perl binary contain a lot of extra info, while
1259     the static nature of F<staticperl> allows the linker to remove all
1260     functionality and meta-info not required by the final executable. Even
1261     extensions statically compiled into perl at build time will only be
1262     present in the final executable when needed.
1263    
1264     In addition, F<staticperl> can strip perl sources much more effectively
1265     than PAR.
1266    
1267     =item * The generated executables start much faster.
1268    
1269     There is no need to unpack files, or even to parse Zip archives (which is
1270     slow and memory-consuming business).
1271    
1272     =item * The generated executables don't need a writable filesystem.
1273    
1274     F<staticperl> loads all required files directly from memory. There is no
1275     need to unpack files into a temporary directory.
1276    
1277     =item * More control over included files.
1278    
1279 root 1.4 PAR tries to be maintenance and hassle-free - it tries to include more
1280     files than necessary to make sure everything works out of the box. The
1281     extra files (such as the unicode database) can take substantial amounts of
1282     memory and file size.
1283 root 1.1
1284     With F<staticperl>, the burden is mostly with the developer - only direct
1285     compile-time dependencies and L<AutoLoader> are handled automatically.
1286     This means the modules to include often need to be tweaked manually.
1287    
1288     =item * PAR works out of the box, F<staticperl> does not.
1289    
1290     Maintaining your own custom perl build can be a pain in the ass, and while
1291     F<staticperl> tries to make this easy, it still requires a custom perl
1292     build and possibly fiddling with some modules. PAR is likely to produce
1293     results faster.
1294    
1295     =back
1296    
1297     =head1 HOW DOES IT WORK?
1298    
1299     Simple: F<staticperl> downloads, compile and installs a perl version of
1300     your choice in F<~/.staticperl>. You can add extra modules either by
1301     letting F<staticperl> install them for you automatically, or by using CPAN
1302     and doing it interactively. This usually takes 5-10 minutes, depending on
1303 root 1.4 the speed of your computer and your internet connection.
1304 root 1.1
1305     It is possible to do program development at this stage, too.
1306    
1307     Afterwards, you create a list of files and modules you want to include,
1308 root 1.4 and then either build a new perl binary (that acts just like a normal perl
1309 root 1.1 except everything is compiled in), or you create bundle files (basically C
1310     sources you can use to embed all files into your project).
1311    
1312     This step is very fast (a few seconds if PPI is not used for stripping,
1313     more seconds otherwise, as PPI is very slow), and can be tweaked and
1314     repeated as often as necessary.
1315    
1316     =head1 THE F<STATICPERL> SCRIPT
1317    
1318     This module installs a script called F<staticperl> into your perl
1319     binary directory. The script is fully self-contained, and can be used
1320     without perl (for example, in an uClibc chroot environment). In fact,
1321     it can be extracted from the C<App::Staticperl> distribution tarball as
1322     F<bin/staticperl>, without any installation.
1323    
1324     F<staticperl> interprets the first argument as a command to execute,
1325     optionally followed by any parameters.
1326    
1327     There are two command categories: the "phase 1" commands which deal with
1328     installing perl and perl modules, and the "phase 2" commands, which deal
1329     with creating binaries and bundle files.
1330    
1331     =head2 PHASE 1 COMMANDS: INSTALLING PERL
1332    
1333     The most important command is F<install>, which does basically
1334     everything. The default is to download and install perl 5.12.2 and a few
1335     modules required by F<staticperl> itself, but all this can (and should) be
1336     changed - see L<CONFIGURATION>, below.
1337    
1338     The command
1339    
1340     staticperl install
1341    
1342     Is normally all you need: It installs the perl interpreter in
1343     F<~/.staticperl/perl>. It downloads, configures, builds and installs the
1344     perl interpreter if required.
1345    
1346     Most of the following commands simply run one or more steps of this
1347     sequence.
1348    
1349 root 1.4 To force recompilation or reinstallation, you need to run F<staticperl
1350 root 1.1 distclean> first.
1351    
1352     =over 4
1353    
1354     =item F<staticperl fetch>
1355    
1356     Runs only the download and unpack phase, unless this has already happened.
1357    
1358     =item F<staticperl configure>
1359    
1360     Configures the unpacked perl sources, potentially after downloading them first.
1361    
1362     =item F<staticperl build>
1363    
1364     Builds the configured perl sources, potentially after automatically
1365     configuring them.
1366    
1367     =item F<staticperl install>
1368    
1369 root 1.4 Wipes the perl installation directory (usually F<~/.staticperl/perl>) and
1370     installs the perl distribution, potentially after building it first.
1371 root 1.1
1372     =item F<staticperl cpan> [args...]
1373    
1374 root 1.4 Starts an interactive CPAN shell that you can use to install further
1375     modules. Installs the perl first if necessary, but apart from that,
1376 root 1.1 no magic is involved: you could just as well run it manually via
1377     F<~/.staticperl/perl/bin/cpan>.
1378    
1379     Any additional arguments are simply passed to the F<cpan> command.
1380    
1381     =item F<staticperl instcpan> module...
1382    
1383     Tries to install all the modules given and their dependencies, using CPAN.
1384    
1385     Example:
1386    
1387     staticperl instcpan EV AnyEvent::HTTPD Coro
1388    
1389     =item F<staticperl instsrc> directory...
1390    
1391     In the unlikely case that you have unpacked perl modules around and want
1392 root 1.4 to install from these instead of from CPAN, you can do this using this
1393 root 1.1 command by specifying all the directories with modules in them that you
1394     want to have built.
1395    
1396     =item F<staticperl clean>
1397    
1398 root 1.11 Deletes the perl source directory (and potentially cleans up other
1399     intermediate files). This can be used to clean up files only needed for
1400     building perl, without removing the installed perl interpreter, or to
1401     force a re-build from scratch.
1402    
1403     At the moment, it doesn't delete downloaded tarballs.
1404 root 1.1
1405     =item F<staticperl distclean>
1406    
1407     This wipes your complete F<~/.staticperl> directory. Be careful with this,
1408     it nukes your perl download, perl sources, perl distribution and any
1409     installed modules. It is useful if you wish to start over "from scratch"
1410     or when you want to uninstall F<staticperl>.
1411    
1412     =back
1413    
1414     =head2 PHASE 2 COMMANDS: BUILDING PERL BUNDLES
1415    
1416     Building (linking) a new F<perl> binary is handled by a separate
1417     script. To make it easy to use F<staticperl> from a F<chroot>, the script
1418     is embedded into F<staticperl>, which will write it out and call for you
1419     with any arguments you pass:
1420    
1421     staticperl mkbundle mkbundle-args...
1422    
1423     In the oh so unlikely case of something not working here, you
1424 root 1.2 can run the script manually as well (by default it is written to
1425 root 1.1 F<~/.staticperl/mkbundle>).
1426    
1427     F<mkbundle> is a more conventional command and expect the argument
1428 root 1.4 syntax commonly used on UNIX clones. For example, this command builds
1429 root 1.1 a new F<perl> binary and includes F<Config.pm> (for F<perl -V>),
1430     F<AnyEvent::HTTPD>, F<URI> and a custom F<httpd> script (from F<eg/httpd>
1431     in this distribution):
1432    
1433     # first make sure we have perl and the required modules
1434     staticperl instcpan AnyEvent::HTTPD
1435    
1436     # now build the perl
1437     staticperl mkperl -M'"Config_heavy.pl"' -MAnyEvent::Impl::Perl \
1438     -MAnyEvent::HTTPD -MURI::http \
1439     --add 'eg/httpd httpd.pm'
1440    
1441     # finally, invoke it
1442     ./perl -Mhttpd
1443    
1444 root 1.2 As you can see, things are not quite as trivial: the L<Config> module has
1445     a hidden dependency which is not even a perl module (F<Config_heavy.pl>),
1446     L<AnyEvent> needs at least one event loop backend that we have to
1447 root 1.4 specify manually (here L<AnyEvent::Impl::Perl>), and the F<URI> module
1448 root 1.2 (required by L<AnyEvent::HTTPD>) implements various URI schemes as extra
1449     modules - since L<AnyEvent::HTTPD> only needs C<http> URIs, we only need
1450 root 1.4 to include that module. I found out about these dependencies by carefully
1451     watching any error messages about missing modules...
1452 root 1.2
1453     =head3 OPTION PROCESSING
1454    
1455 root 1.4 All options can be given as arguments on the command line (typically
1456     using long (e.g. C<--verbose>) or short option (e.g. C<-v>) style). Since
1457     specifying a lot of modules can make the command line very cumbersome,
1458 root 1.2 you can put all long options into a "bundle specification file" (with or
1459     without C<--> prefix) and specify this bundle file instead.
1460    
1461     For example, the command given earlier could also look like this:
1462    
1463     staticperl mkperl httpd.bundle
1464    
1465     And all options could be in F<httpd.bundle>:
1466 root 1.1
1467 root 1.2 use "Config_heavy.pl"
1468     use AnyEvent::Impl::Perl
1469     use AnyEvent::HTTPD
1470     use URI::http
1471     add eg/httpd httpd.pm
1472    
1473     All options that specify modules or files to be added are processed in the
1474 root 1.4 order given on the command line (that affects the C<--use> and C<--eval>
1475 root 1.2 options at the moment).
1476    
1477     =head3 MKBUNDLE OPTIONS
1478    
1479     =over 4
1480    
1481     =item --verbose | -v
1482    
1483     Increases the verbosity level by one (the default is C<1>).
1484    
1485     =item --quiet | -q
1486    
1487     Decreases the verbosity level by one.
1488    
1489     =item --strip none|pod|ppi
1490    
1491     Specify the stripping method applied to reduce the file of the perl
1492     sources included.
1493    
1494     The default is C<pod>, which uses the L<Pod::Strip> module to remove all
1495 root 1.4 pod documentation, which is very fast and reduces file size a lot.
1496 root 1.2
1497     The C<ppi> method uses L<PPI> to parse and condense the perl sources. This
1498 root 1.4 saves a lot more than just L<Pod::Strip>, and is generally safer, but
1499     is also a lot slower, so is best used for production builds. Note that
1500     this method doesn't optimise for raw file size, but for best compression
1501     (that means that the uncompressed file size is a bit larger, but the files
1502     compress better, e.g. with F<upx>).
1503 root 1.2
1504 root 1.7 Last not least, if you need accurate line numbers in error messages,
1505     or in the unlikely case where C<pod> is too slow, or some module gets
1506     mistreated, you can specify C<none> to not mangle included perl sources in
1507     any way.
1508 root 1.2
1509     =item --perl
1510    
1511     After writing out the bundle files, try to link a new perl interpreter. It
1512     will be called F<perl> and will be left in the current working
1513     directory. The bundle files will be removed.
1514    
1515 root 1.4 This switch is automatically used when F<staticperl> is invoked with the
1516 root 1.2 C<mkperl> command (instead of C<mkbundle>):
1517    
1518     # build a new ./perl with only common::sense in it - very small :)
1519     staticperl mkperl -Mcommon::sense
1520    
1521     =item --use module | -Mmodule
1522    
1523     Include the named module and all direct dependencies. This is done by
1524     C<require>'ing the module in a subprocess and tracing which other modules
1525     and files it actually loads. If the module uses L<AutoLoader>, then all
1526     splitfiles will be included as well.
1527    
1528     Example: include AnyEvent and AnyEvent::Impl::Perl.
1529    
1530     staticperl mkbundle --use AnyEvent --use AnyEvent::Impl::Perl
1531    
1532     Sometimes you want to load old-style "perl libraries" (F<.pl> files), or
1533     maybe other weirdly named files. To do that, you need to quote the name in
1534 root 1.4 single or double quotes. When given on the command line, you probably need
1535 root 1.2 to quote once more to avoid your shell interpreting it. Common cases that
1536     need this are F<Config_heavy.pl> and F<utf8_heavy.pl>.
1537    
1538     Example: include the required files for F<perl -V> to work in all its
1539     glory (F<Config.pm> is included automatically by this).
1540    
1541     # bourne shell
1542     staticperl mkbundle --use '"Config_heavy.pl"'
1543    
1544     # bundle specification file
1545     use "Config_heavy.pl"
1546    
1547     The C<-Mmodule> syntax is included as an alias that might be easier to
1548     remember than C<use>. Or maybe it confuses people. Time will tell. Or
1549     maybe not. Argh.
1550    
1551     =item --eval "perl code" | -e "perl code"
1552    
1553     Sometimes it is easier (or necessary) to specify dependencies using perl
1554     code, or maybe one of the modules you use need a special use statement. In
1555     that case, you can use C<eval> to execute some perl snippet or set some
1556     variables or whatever you need. All files C<require>'d or C<use>'d in the
1557     script are included in the final bundle.
1558    
1559     Keep in mind that F<mkbundle> will only C<require> the modules named
1560     by the C<--use> option, so do not expect the symbols from modules you
1561 root 1.4 C<--use>'d earlier on the command line to be available.
1562 root 1.2
1563     Example: force L<AnyEvent> to detect a backend and therefore include it
1564     in the final bundle.
1565    
1566     staticperl mkbundle --eval 'use AnyEvent; AnyEvent::detect'
1567    
1568     # or like this
1569     staticperl mkbundle -MAnyEvent --eval 'use AnyEvent; AnyEvent::detect'
1570    
1571     Example: use a separate "bootstrap" script that C<use>'s lots of modules
1572     and include this in the final bundle, to be executed automatically.
1573    
1574     staticperl mkbundle --eval 'do "bootstrap"' --boot bootstrap
1575    
1576     =item --boot filename
1577    
1578     Include the given file in the bundle and arrange for it to be executed
1579     (using a C<require>) before anything else when the new perl is
1580     initialised. This can be used to modify C<@INC> or anything else before
1581 root 1.4 the perl interpreter executes scripts given on the command line (or via
1582 root 1.2 C<-e>). This works even in an embedded interpreter.
1583    
1584     =item --add "file" | --add "file alias"
1585    
1586     Adds the given (perl) file into the bundle (and optionally call it
1587     "alias"). This is useful to include any custom files into the bundle.
1588    
1589     Example: embed the file F<httpd> as F<httpd.pm> when creating the bundle.
1590    
1591     staticperl mkperl --add "httpd httpd.pm"
1592    
1593     It is also a great way to add any custom modules:
1594    
1595     # specification file
1596     add file1 myfiles/file1
1597     add file2 myfiles/file2
1598     add file3 myfiles/file3
1599    
1600 root 1.8 =item --binadd "file" | --add "file alias"
1601    
1602     Just like C<--add>, except that it treats the file as binary and adds it
1603     without any processing.
1604    
1605     You should probably add a C</> prefix to avoid clashing with embedded
1606     perl files (whose paths do not start with C</>), and/or use a special
1607     directory, such as C</res/name>.
1608    
1609     You can later get a copy of these files by calling C<staticperl::find
1610     "alias">.
1611    
1612 root 1.2 =item --static
1613    
1614     When C<--perl> is also given, link statically instead of dynamically. The
1615     default is to link the new perl interpreter fully dynamic (that means all
1616     perl modules are linked statically, but all external libraries are still
1617     referenced dynamically).
1618    
1619     Keep in mind that Solaris doesn't support static linking at all, and
1620     systems based on GNU libc don't really support it in a usable fashion
1621     either. Try uClibc if you want to create fully statically linked
1622     executables, or try the C<--staticlibs> option to link only some libraries
1623     statically.
1624    
1625     =item any other argument
1626    
1627     Any other argument is interpreted as a bundle specification file, which
1628     supports most long options (without extra quoting), one option per line.
1629    
1630     =back
1631    
1632     =head2 F<STATCPERL> CONFIGURATION AND HOOKS
1633    
1634     During (each) startup, F<staticperl> tries to source the following shell
1635     files in order:
1636    
1637     /etc/staticperlrc
1638     ~/.staticperlrc
1639     $STATICPERL/rc
1640    
1641     They can be used to override shell variables, or define functions to be
1642     called at specific phases.
1643    
1644     Note that the last file is erased during F<staticperl distclean>, so
1645     generally should not be used.
1646    
1647     =head3 CONFIGURATION VARIABLES
1648    
1649     =head4 Variables you I<should> override
1650    
1651     =over 4
1652    
1653     =item C<EMAIL>
1654    
1655     The e-mail address of the person who built this binary. Has no good
1656     default, so should be specified by you.
1657    
1658     =item C<CPAN>
1659    
1660     The URL of the CPAN mirror to use (e.g. L<http://mirror.netcologne.de/cpan/>).
1661    
1662 root 1.6 =item C<EXTRA_MODULES>
1663 root 1.2
1664 root 1.6 Additional modules installed during F<staticperl install>. Here you can
1665     set which modules you want have to installed from CPAN.
1666 root 1.2
1667 root 1.10 Example: I really really need EV, AnyEvent, Coro and AnyEvent::AIO.
1668 root 1.2
1669 root 1.10 EXTRA_MODULES="EV AnyEvent Coro AnyEvent::AIO"
1670 root 1.2
1671 root 1.6 Note that you can also use a C<postinstall> hook to achieve this, and
1672     more.
1673 root 1.2
1674 root 1.10 =back
1675    
1676     =head4 Variables you might I<want> to override
1677    
1678     =over 4
1679    
1680     =item C<STATICPERL>
1681    
1682     The directory where staticperl stores all its files
1683     (default: F<~/.staticperl>).
1684    
1685 root 1.6 =item C<PERL_MM_USE_DEFAULT>, C<EV_EXTRA_DEFS>, ...
1686 root 1.2
1687     Usually set to C<1> to make modules "less inquisitive" during their
1688     installation, you can set any environment variable you want - some modules
1689     (such as L<Coro> or L<EV>) use environment variables for further tweaking.
1690    
1691 root 1.10 =item C<PERL_VERSION>
1692 root 1.6
1693 root 1.10 The perl version to install - default is currently C<5.12.2>, but C<5.8.9>
1694     is also a good choice (5.8.9 is much smaller than 5.12.2, while 5.10.1 is
1695     about as big as 5.12.2).
1696 root 1.2
1697 root 1.10 =item C<PERL_PREFIX>
1698 root 1.2
1699 root 1.6 The prefix where perl gets installed (default: F<$STATICPERL/perl>),
1700     i.e. where the F<bin> and F<lib> subdirectories will end up.
1701 root 1.2
1702 root 1.8 =item C<PERL_CONFIGURE>
1703    
1704     Additional Configure options - these are simply passed to the perl
1705     Configure script. For example, if you wanted to enable dynamic loading,
1706     you could pass C<-Dusedl>. To enable ithreads (Why would you want that
1707     insanity? Don't! Use L<forks> instead!) you would pass C<-Duseithreads>
1708     and so on.
1709    
1710     More commonly, you would either activate 64 bit integer support
1711     (C<-Duse64bitint>), or disable large files support (-Uuselargefiles), to
1712     reduce filesize further.
1713    
1714 root 1.6 =item C<PERL_CPPFLAGS>, C<PERL_OPTIMIZE>, C<PERL_LDFLAGS>, C<PERL_LIBS>
1715 root 1.2
1716 root 1.6 These flags are passed to perl's F<Configure> script, and are generally
1717     optimised for small size (at the cost of performance). Since they also
1718     contain subtle workarounds around various build issues, changing these
1719     usually requires understanding their default values - best look at the top
1720     of the F<staticperl> script for more info on these.
1721 root 1.2
1722     =back
1723    
1724 root 1.5 =head4 Variables you probably I<do not want> to override
1725 root 1.2
1726     =over 4
1727    
1728     =item C<MKBUNDLE>
1729    
1730     Where F<staticperl> writes the C<mkbundle> command to
1731     (default: F<$STATICPERL/mkbundle>).
1732 root 1.1
1733 root 1.2 =item C<STATICPERL_MODULES>
1734 root 1.1
1735 root 1.2 Additional modules needed by C<mkbundle> - should therefore not be changed
1736     unless you know what you are doing.
1737    
1738     =back
1739    
1740     =head3 OVERRIDABLE HOOKS
1741    
1742     In addition to environment variables, it is possible to provide some
1743     shell functions that are called at specific times. To provide your own
1744 root 1.4 commands, just define the corresponding function.
1745 root 1.2
1746     Example: install extra modules from CPAN and from some directories
1747     at F<staticperl install> time.
1748    
1749     postinstall() {
1750 root 1.5 rm -rf lib/threads* # weg mit Schaden
1751 root 1.2 instcpan IO::AIO EV
1752     instsrc ~/src/AnyEvent
1753     instsrc ~/src/XML-Sablotron-1.0100001
1754 root 1.5 instcpan Anyevent::AIO AnyEvent::HTTPD
1755 root 1.2 }
1756    
1757     =over 4
1758    
1759 root 1.11 =item preconfigure
1760    
1761     Called just before running F<./Configur> in the perl source
1762     directory. Current working directory is the perl source directory.
1763    
1764     This can be used to set any C<PERL_xxx> variables, which might be costly
1765     to compute.
1766    
1767 root 1.2 =item postconfigure
1768    
1769     Called after configuring, but before building perl. Current working
1770     directory is the perl source directory.
1771    
1772 root 1.11 Could be used to tailor/patch config.sh (followed by F<sh Configure -S>)
1773     or do any other modifications.
1774 root 1.2
1775     =item postbuild
1776    
1777     Called after building, but before installing perl. Current working
1778     directory is the perl source directory.
1779    
1780     I have no clue what this could be used for - tell me.
1781    
1782     =item postinstall
1783    
1784     Called after perl and any extra modules have been installed in C<$PREFIX>,
1785     but before setting the "installation O.K." flag.
1786    
1787     The current working directory is C<$PREFIX>, but maybe you should not rely
1788     on that.
1789    
1790     This hook is most useful to customise the installation, by deleting files,
1791     or installing extra modules using the C<instcpan> or C<instsrc> functions.
1792    
1793     The script must return with a zero exit status, or the installation will
1794     fail.
1795 root 1.1
1796 root 1.2 =back
1797 root 1.1
1798 root 1.7 =head1 ANATOMY OF A BUNDLE
1799    
1800     When not building a new perl binary, C<mkbundle> will leave a number of
1801     files in the current working directory, which can be used to embed a perl
1802     interpreter in your program.
1803    
1804     Intimate knowledge of L<perlembed> and preferably some experience with
1805     embedding perl is highly recommended.
1806    
1807     C<mkperl> (or the C<--perl> option) basically does this to link the new
1808     interpreter (it also adds a main program to F<bundle.>):
1809    
1810     $Config{cc} $(cat bundle.ccopts) -o perl bundle.c $(cat bundle.ldopts)
1811    
1812     =over 4
1813    
1814     =item bundle.h
1815    
1816     A header file that contains the prototypes of the few symbols "exported"
1817     by bundle.c, and also exposes the perl headers to the application.
1818    
1819     =over 4
1820    
1821     =item staticperl_init ()
1822    
1823     Initialises the perl interpreter. You can use the normal perl functions
1824     after calling this function, for example, to define extra functions or
1825     to load a .pm file that contains some initialisation code, or the main
1826     program function:
1827    
1828     XS (xsfunction)
1829     {
1830     dXSARGS;
1831    
1832     // now we have items, ST(i) etc.
1833     }
1834    
1835     static void
1836     run_myapp(void)
1837     {
1838     staticperl_init ();
1839     newXSproto ("myapp::xsfunction", xsfunction, __FILE__, "$$;$");
1840     eval_pv ("require myapp::main", 1); // executes "myapp/main.pm"
1841     }
1842    
1843     =item staticperl_xs_init (pTHX)
1844    
1845     Sometimes you need direct control over C<perl_parse> and C<perl_run>, in
1846     which case you do not want to use C<staticperl_init> but call them on your
1847     own.
1848    
1849     Then you need this function - either pass it directly as the C<xs_init>
1850     function to C<perl_parse>, or call it from your own C<xs_init> function.
1851    
1852     =item staticperl_cleanup ()
1853    
1854     In the unlikely case that you want to destroy the perl interpreter, here
1855     is the corresponding function.
1856    
1857     =item PerlInterpreter *staticperl
1858    
1859     The perl interpreter pointer used by staticperl. Not normally so useful,
1860     but there it is.
1861    
1862     =back
1863    
1864     =item bundle.ccopts
1865    
1866     Contains the compiler options required to compile at least F<bundle.c> and
1867     any file that includes F<bundle.h> - you should probably use it in your
1868     C<CFLAGS>.
1869    
1870     =item bundle.ldopts
1871    
1872     The linker options needed to link the final program.
1873    
1874     =back
1875    
1876     =head1 RUNTIME FUNCTIONALITY
1877    
1878     Binaries created with C<mkbundle>/C<mkperl> contain extra functions, which
1879     are required to access the bundled perl sources, but might be useful for
1880     other purposes.
1881    
1882     In addition, for the embedded loading of perl files to work, F<staticperl>
1883     overrides the C<@INC> array.
1884    
1885     =over 4
1886    
1887     =item $file = staticperl::find $path
1888    
1889     Returns the data associated with the given C<$path>
1890     (e.g. C<Digest/MD5.pm>, C<auto/POSIX/autosplit.ix>), which is basically
1891     the UNIX path relative to the perl library directory.
1892    
1893     Returns C<undef> if the file isn't embedded.
1894    
1895 root 1.8 =item @paths = staticperl::list
1896 root 1.7
1897     Returns the list of all paths embedded in this binary.
1898    
1899     =back
1900    
1901 root 1.8 =head1 FULLY STATIC BINARIES - BUILDROOT
1902    
1903     To make truly static (Linux-) libraries, you might want to have a look at
1904     buildroot (L<http://buildroot.uclibc.org/>).
1905    
1906     Buildroot is primarily meant to set up a cross-compile environment (which
1907     is not so useful as perl doesn't quite like cross compiles), but it can also compile
1908     a chroot environment where you can use F<staticperl>.
1909    
1910     To do so, download buildroot, and enable "Build options => development
1911     files in target filesystem" and optionally "Build options => gcc
1912     optimization level (optimize for size)". At the time of writing, I had
1913     good experiences with GCC 4.4.x but not GCC 4.5.
1914    
1915     To minimise code size, I used C<-pipe -ffunction-sections -fdata-sections
1916     -finline-limit=8 -fno-builtin-strlen -mtune=i386>. The C<-mtune=i386>
1917     doesn't decrease codesize much, but it makes the file much more
1918     compressible.
1919    
1920     If you don't need Coro or threads, you can go with "linuxthreads.old" (or
1921     no thread support). For Coro, it is highly recommended to switch to a
1922     uClibc newer than 0.9.31 (at the time of this writing, I used the 20101201
1923     snapshot) and enable NPTL, otherwise Coro needs to be configured with the
1924     ultra-slow pthreads backend to work around linuxthreads bugs (it also uses
1925     twice the address space needed for stacks).
1926    
1927     If you use C<linuxthreads.old>, then you should also be aware that
1928     uClibc shares C<errno> between all threads when statically linking. See
1929     L<http://lists.uclibc.org/pipermail/uclibc/2010-June/044157.html> for a
1930     workaround (And L<https://bugs.uclibc.org/2089> for discussion).
1931    
1932 root 1.10 C<ccache> support is also recommended, especially if you want
1933     to play around with buildroot options. Enabling the C<miniperl>
1934     package will probably enable all options required for a successful
1935     perl build. F<staticperl> itself additionally needs either C<wget>
1936     (recommended, for CPAN) or C<curl>.
1937 root 1.8
1938     As for shells, busybox should provide all that is needed, but the default
1939     busybox configuration doesn't include F<comm> which is needed by perl -
1940     either make a custom busybox config, or compile coreutils.
1941    
1942     For the latter route, you might find that bash has some bugs that keep
1943     it from working properly in a chroot - either use dash (and link it to
1944     F</bin/sh> inside the chroot) or link busybox to F</bin/sh>, using it's
1945     built-in ash shell.
1946    
1947     Finally, you need F</dev/null> inside the chroot for many scripts to work
1948     - F<cp /dev/null output/target/dev> or bind-mounting your F</dev> will
1949     both provide this.
1950    
1951     After you have compiled and set up your buildroot target, you can copy
1952     F<staticperl> from the C<App::Staticperl> distribution or from your
1953     perl f<bin> directory (if you installed it) into the F<output/target>
1954     filesystem, chroot inside and run it.
1955    
1956 root 1.1 =head1 AUTHOR
1957    
1958     Marc Lehmann <schmorp@schmorp.de>
1959     http://software.schmorp.de/pkg/staticperl.html
1960