ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/App-Staticperl/bin/staticperl
Revision: 1.10
Committed: Tue Dec 7 10:40:39 2010 UTC (15 years, 9 months ago) by root
Branch: MAIN
CVS Tags: rel-0_1
Changes since 1.9: +77 -75 lines
Log Message:
rel-0_1

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     postconfigure() { : ; }
52     postbuild() { : ; }
53     postinstall() { : ; }
54    
55     # now source user config, if any
56     [ -r /etc/staticperlrc ] && . /etc/staticperlrc
57     [ -r ~/.staticperlrc ] && . ~/.staticperlrc
58     [ -r "$STATICPERL/rc" ] && . "$STATICPERL/rc"
59    
60     #############################################################################
61     # support
62    
63     # set version in a way that Makefile.PL can extract
64     VERSION=VERSION; eval \
65     $VERSION=0.1
66    
67     BZ2=bz2
68     BZIP2=bzip2
69    
70     fatal() {
71     printf -- "\nFATAL: %s\n\n" "$*" >&2
72     exit 1
73     }
74    
75     verbose() {
76     printf -- "%s\n" "$*"
77     }
78    
79     verblock() {
80     verbose
81     verbose "***"
82     while read line; do
83     verbose "*** $line"
84     done
85     verbose "***"
86     verbose
87     }
88    
89     rcd() {
90     cd "$1" || fatal "$1: cannot enter"
91     }
92    
93     trace() {
94     prefix="$1"; shift
95     # "$@" 2>&1 | while read line; do
96     # echo "$prefix: $line"
97     # done
98     "$@"
99     }
100    
101     trap wait 0
102    
103     #############################################################################
104     # clean
105    
106     distclean() {
107     verblock <<EOF
108     deleting everything installed by this script
109     EOF
110    
111     rm -rf "$STATICPERL"
112     }
113    
114     #############################################################################
115     # download/configure/compile/install perl
116    
117     clean() {
118 root 1.10 cd "$STATICPERL/src/perl-$PERL_VERSION" 2>/dev/null || return
119 root 1.1
120     rm -f staticstamp.configure
121     make distclean >/dev/null 2>&1
122     }
123    
124     fetch() {
125     rcd "$STATICPERL"
126    
127     mkdir -p src
128     rcd src
129    
130 root 1.10 if ! [ -d "perl-$PERL_VERSION" ]; then
131     if ! [ -e "perl-$PERL_VERSION.tar.$BZ2" ]; then
132 root 1.1
133 root 1.10 URL="$CPAN/src/5.0/perl-$PERL_VERSION.tar.$BZ2"
134 root 1.1
135     verblock <<EOF
136     downloading perl
137     to manually download perl yourself, place
138 root 1.10 perl-$PERL_VERSION.tar.$BZ2 in $STATICPERL
139 root 1.1 trying $URL
140     EOF
141    
142 root 1.10 rm -f perl-$PERL_VERSION.tar.$BZ2~ # just to be on the safe side
143     wget -O perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
144     || curl >perl-$PERL_VERSION.tar.$BZ2~ "$URL" \
145     || fatal "$URL: unable to download"
146     mv perl-$PERL_VERSION.tar.$BZ2~ perl-$PERL_VERSION.tar.$BZ2
147 root 1.1 fi
148    
149     verblock <<EOF
150     unpacking perl
151     EOF
152    
153     mkdir -p unpack
154 root 1.10 $BZIP2 -d <perl-$PERL_VERSION.tar.bz2 | tar xpC unpack \
155     || fatal "perl-$PERL_VERSION.tar.bz2: error during unpacking"
156     mv unpack/perl-$PERL_VERSION perl-$PERL_VERSION
157 root 1.1 rmdir -p unpack
158     fi
159     }
160    
161     # similar to GNU-sed -i or perl -pi
162     sedreplace() {
163     sed -e "$1" <"$2" > "$2~" || fatal "error while running sed"
164     mv "$2~" "$2"
165     }
166    
167     configure() {
168     fetch
169    
170 root 1.10 rcd "$STATICPERL/src/perl-$PERL_VERSION"
171 root 1.1
172     [ -e staticstamp.configure ] && return
173    
174     verblock <<EOF
175 root 1.10 configuring $STATICPERL/src/perl-$PERL_VERSION
176 root 1.1 EOF
177    
178     clean
179    
180 root 1.10 rm -f "$PERL_PREFIX/staticstamp.install"
181 root 1.1
182     # I hate them
183     grep -q -- -fstack-protector Configure && \
184     sedreplace 's/-fstack-protector/-fno-stack-protector/g' Configure
185    
186     # 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     Runs F<make distclean> in the perl source directory (and potentially
1399     cleans up other intermediate files). This can be used to clean up
1400     intermediate files without removing the installed perl interpreter.
1401    
1402     =item F<staticperl distclean>
1403    
1404     This wipes your complete F<~/.staticperl> directory. Be careful with this,
1405     it nukes your perl download, perl sources, perl distribution and any
1406     installed modules. It is useful if you wish to start over "from scratch"
1407     or when you want to uninstall F<staticperl>.
1408    
1409     =back
1410    
1411     =head2 PHASE 2 COMMANDS: BUILDING PERL BUNDLES
1412    
1413     Building (linking) a new F<perl> binary is handled by a separate
1414     script. To make it easy to use F<staticperl> from a F<chroot>, the script
1415     is embedded into F<staticperl>, which will write it out and call for you
1416     with any arguments you pass:
1417    
1418     staticperl mkbundle mkbundle-args...
1419    
1420     In the oh so unlikely case of something not working here, you
1421 root 1.2 can run the script manually as well (by default it is written to
1422 root 1.1 F<~/.staticperl/mkbundle>).
1423    
1424     F<mkbundle> is a more conventional command and expect the argument
1425 root 1.4 syntax commonly used on UNIX clones. For example, this command builds
1426 root 1.1 a new F<perl> binary and includes F<Config.pm> (for F<perl -V>),
1427     F<AnyEvent::HTTPD>, F<URI> and a custom F<httpd> script (from F<eg/httpd>
1428     in this distribution):
1429    
1430     # first make sure we have perl and the required modules
1431     staticperl instcpan AnyEvent::HTTPD
1432    
1433     # now build the perl
1434     staticperl mkperl -M'"Config_heavy.pl"' -MAnyEvent::Impl::Perl \
1435     -MAnyEvent::HTTPD -MURI::http \
1436     --add 'eg/httpd httpd.pm'
1437    
1438     # finally, invoke it
1439     ./perl -Mhttpd
1440    
1441 root 1.2 As you can see, things are not quite as trivial: the L<Config> module has
1442     a hidden dependency which is not even a perl module (F<Config_heavy.pl>),
1443     L<AnyEvent> needs at least one event loop backend that we have to
1444 root 1.4 specify manually (here L<AnyEvent::Impl::Perl>), and the F<URI> module
1445 root 1.2 (required by L<AnyEvent::HTTPD>) implements various URI schemes as extra
1446     modules - since L<AnyEvent::HTTPD> only needs C<http> URIs, we only need
1447 root 1.4 to include that module. I found out about these dependencies by carefully
1448     watching any error messages about missing modules...
1449 root 1.2
1450     =head3 OPTION PROCESSING
1451    
1452 root 1.4 All options can be given as arguments on the command line (typically
1453     using long (e.g. C<--verbose>) or short option (e.g. C<-v>) style). Since
1454     specifying a lot of modules can make the command line very cumbersome,
1455 root 1.2 you can put all long options into a "bundle specification file" (with or
1456     without C<--> prefix) and specify this bundle file instead.
1457    
1458     For example, the command given earlier could also look like this:
1459    
1460     staticperl mkperl httpd.bundle
1461    
1462     And all options could be in F<httpd.bundle>:
1463 root 1.1
1464 root 1.2 use "Config_heavy.pl"
1465     use AnyEvent::Impl::Perl
1466     use AnyEvent::HTTPD
1467     use URI::http
1468     add eg/httpd httpd.pm
1469    
1470     All options that specify modules or files to be added are processed in the
1471 root 1.4 order given on the command line (that affects the C<--use> and C<--eval>
1472 root 1.2 options at the moment).
1473    
1474     =head3 MKBUNDLE OPTIONS
1475    
1476     =over 4
1477    
1478     =item --verbose | -v
1479    
1480     Increases the verbosity level by one (the default is C<1>).
1481    
1482     =item --quiet | -q
1483    
1484     Decreases the verbosity level by one.
1485    
1486     =item --strip none|pod|ppi
1487    
1488     Specify the stripping method applied to reduce the file of the perl
1489     sources included.
1490    
1491     The default is C<pod>, which uses the L<Pod::Strip> module to remove all
1492 root 1.4 pod documentation, which is very fast and reduces file size a lot.
1493 root 1.2
1494     The C<ppi> method uses L<PPI> to parse and condense the perl sources. This
1495 root 1.4 saves a lot more than just L<Pod::Strip>, and is generally safer, but
1496     is also a lot slower, so is best used for production builds. Note that
1497     this method doesn't optimise for raw file size, but for best compression
1498     (that means that the uncompressed file size is a bit larger, but the files
1499     compress better, e.g. with F<upx>).
1500 root 1.2
1501 root 1.7 Last not least, if you need accurate line numbers in error messages,
1502     or in the unlikely case where C<pod> is too slow, or some module gets
1503     mistreated, you can specify C<none> to not mangle included perl sources in
1504     any way.
1505 root 1.2
1506     =item --perl
1507    
1508     After writing out the bundle files, try to link a new perl interpreter. It
1509     will be called F<perl> and will be left in the current working
1510     directory. The bundle files will be removed.
1511    
1512 root 1.4 This switch is automatically used when F<staticperl> is invoked with the
1513 root 1.2 C<mkperl> command (instead of C<mkbundle>):
1514    
1515     # build a new ./perl with only common::sense in it - very small :)
1516     staticperl mkperl -Mcommon::sense
1517    
1518     =item --use module | -Mmodule
1519    
1520     Include the named module and all direct dependencies. This is done by
1521     C<require>'ing the module in a subprocess and tracing which other modules
1522     and files it actually loads. If the module uses L<AutoLoader>, then all
1523     splitfiles will be included as well.
1524    
1525     Example: include AnyEvent and AnyEvent::Impl::Perl.
1526    
1527     staticperl mkbundle --use AnyEvent --use AnyEvent::Impl::Perl
1528    
1529     Sometimes you want to load old-style "perl libraries" (F<.pl> files), or
1530     maybe other weirdly named files. To do that, you need to quote the name in
1531 root 1.4 single or double quotes. When given on the command line, you probably need
1532 root 1.2 to quote once more to avoid your shell interpreting it. Common cases that
1533     need this are F<Config_heavy.pl> and F<utf8_heavy.pl>.
1534    
1535     Example: include the required files for F<perl -V> to work in all its
1536     glory (F<Config.pm> is included automatically by this).
1537    
1538     # bourne shell
1539     staticperl mkbundle --use '"Config_heavy.pl"'
1540    
1541     # bundle specification file
1542     use "Config_heavy.pl"
1543    
1544     The C<-Mmodule> syntax is included as an alias that might be easier to
1545     remember than C<use>. Or maybe it confuses people. Time will tell. Or
1546     maybe not. Argh.
1547    
1548     =item --eval "perl code" | -e "perl code"
1549    
1550     Sometimes it is easier (or necessary) to specify dependencies using perl
1551     code, or maybe one of the modules you use need a special use statement. In
1552     that case, you can use C<eval> to execute some perl snippet or set some
1553     variables or whatever you need. All files C<require>'d or C<use>'d in the
1554     script are included in the final bundle.
1555    
1556     Keep in mind that F<mkbundle> will only C<require> the modules named
1557     by the C<--use> option, so do not expect the symbols from modules you
1558 root 1.4 C<--use>'d earlier on the command line to be available.
1559 root 1.2
1560     Example: force L<AnyEvent> to detect a backend and therefore include it
1561     in the final bundle.
1562    
1563     staticperl mkbundle --eval 'use AnyEvent; AnyEvent::detect'
1564    
1565     # or like this
1566     staticperl mkbundle -MAnyEvent --eval 'use AnyEvent; AnyEvent::detect'
1567    
1568     Example: use a separate "bootstrap" script that C<use>'s lots of modules
1569     and include this in the final bundle, to be executed automatically.
1570    
1571     staticperl mkbundle --eval 'do "bootstrap"' --boot bootstrap
1572    
1573     =item --boot filename
1574    
1575     Include the given file in the bundle and arrange for it to be executed
1576     (using a C<require>) before anything else when the new perl is
1577     initialised. This can be used to modify C<@INC> or anything else before
1578 root 1.4 the perl interpreter executes scripts given on the command line (or via
1579 root 1.2 C<-e>). This works even in an embedded interpreter.
1580    
1581     =item --add "file" | --add "file alias"
1582    
1583     Adds the given (perl) file into the bundle (and optionally call it
1584     "alias"). This is useful to include any custom files into the bundle.
1585    
1586     Example: embed the file F<httpd> as F<httpd.pm> when creating the bundle.
1587    
1588     staticperl mkperl --add "httpd httpd.pm"
1589    
1590     It is also a great way to add any custom modules:
1591    
1592     # specification file
1593     add file1 myfiles/file1
1594     add file2 myfiles/file2
1595     add file3 myfiles/file3
1596    
1597 root 1.8 =item --binadd "file" | --add "file alias"
1598    
1599     Just like C<--add>, except that it treats the file as binary and adds it
1600     without any processing.
1601    
1602     You should probably add a C</> prefix to avoid clashing with embedded
1603     perl files (whose paths do not start with C</>), and/or use a special
1604     directory, such as C</res/name>.
1605    
1606     You can later get a copy of these files by calling C<staticperl::find
1607     "alias">.
1608    
1609 root 1.2 =item --static
1610    
1611     When C<--perl> is also given, link statically instead of dynamically. The
1612     default is to link the new perl interpreter fully dynamic (that means all
1613     perl modules are linked statically, but all external libraries are still
1614     referenced dynamically).
1615    
1616     Keep in mind that Solaris doesn't support static linking at all, and
1617     systems based on GNU libc don't really support it in a usable fashion
1618     either. Try uClibc if you want to create fully statically linked
1619     executables, or try the C<--staticlibs> option to link only some libraries
1620     statically.
1621    
1622     =item any other argument
1623    
1624     Any other argument is interpreted as a bundle specification file, which
1625     supports most long options (without extra quoting), one option per line.
1626    
1627     =back
1628    
1629     =head2 F<STATCPERL> CONFIGURATION AND HOOKS
1630    
1631     During (each) startup, F<staticperl> tries to source the following shell
1632     files in order:
1633    
1634     /etc/staticperlrc
1635     ~/.staticperlrc
1636     $STATICPERL/rc
1637    
1638     They can be used to override shell variables, or define functions to be
1639     called at specific phases.
1640    
1641     Note that the last file is erased during F<staticperl distclean>, so
1642     generally should not be used.
1643    
1644     =head3 CONFIGURATION VARIABLES
1645    
1646     =head4 Variables you I<should> override
1647    
1648     =over 4
1649    
1650     =item C<EMAIL>
1651    
1652     The e-mail address of the person who built this binary. Has no good
1653     default, so should be specified by you.
1654    
1655     =item C<CPAN>
1656    
1657     The URL of the CPAN mirror to use (e.g. L<http://mirror.netcologne.de/cpan/>).
1658    
1659 root 1.6 =item C<EXTRA_MODULES>
1660 root 1.2
1661 root 1.6 Additional modules installed during F<staticperl install>. Here you can
1662     set which modules you want have to installed from CPAN.
1663 root 1.2
1664 root 1.10 Example: I really really need EV, AnyEvent, Coro and AnyEvent::AIO.
1665 root 1.2
1666 root 1.10 EXTRA_MODULES="EV AnyEvent Coro AnyEvent::AIO"
1667 root 1.2
1668 root 1.6 Note that you can also use a C<postinstall> hook to achieve this, and
1669     more.
1670 root 1.2
1671 root 1.10 =back
1672    
1673     =head4 Variables you might I<want> to override
1674    
1675     =over 4
1676    
1677     =item C<STATICPERL>
1678    
1679     The directory where staticperl stores all its files
1680     (default: F<~/.staticperl>).
1681    
1682 root 1.6 =item C<PERL_MM_USE_DEFAULT>, C<EV_EXTRA_DEFS>, ...
1683 root 1.2
1684     Usually set to C<1> to make modules "less inquisitive" during their
1685     installation, you can set any environment variable you want - some modules
1686     (such as L<Coro> or L<EV>) use environment variables for further tweaking.
1687    
1688 root 1.10 =item C<PERL_VERSION>
1689 root 1.6
1690 root 1.10 The perl version to install - default is currently C<5.12.2>, but C<5.8.9>
1691     is also a good choice (5.8.9 is much smaller than 5.12.2, while 5.10.1 is
1692     about as big as 5.12.2).
1693 root 1.2
1694 root 1.10 =item C<PERL_PREFIX>
1695 root 1.2
1696 root 1.6 The prefix where perl gets installed (default: F<$STATICPERL/perl>),
1697     i.e. where the F<bin> and F<lib> subdirectories will end up.
1698 root 1.2
1699 root 1.8 =item C<PERL_CONFIGURE>
1700    
1701     Additional Configure options - these are simply passed to the perl
1702     Configure script. For example, if you wanted to enable dynamic loading,
1703     you could pass C<-Dusedl>. To enable ithreads (Why would you want that
1704     insanity? Don't! Use L<forks> instead!) you would pass C<-Duseithreads>
1705     and so on.
1706    
1707     More commonly, you would either activate 64 bit integer support
1708     (C<-Duse64bitint>), or disable large files support (-Uuselargefiles), to
1709     reduce filesize further.
1710    
1711 root 1.6 =item C<PERL_CPPFLAGS>, C<PERL_OPTIMIZE>, C<PERL_LDFLAGS>, C<PERL_LIBS>
1712 root 1.2
1713 root 1.6 These flags are passed to perl's F<Configure> script, and are generally
1714     optimised for small size (at the cost of performance). Since they also
1715     contain subtle workarounds around various build issues, changing these
1716     usually requires understanding their default values - best look at the top
1717     of the F<staticperl> script for more info on these.
1718 root 1.2
1719     =back
1720    
1721 root 1.5 =head4 Variables you probably I<do not want> to override
1722 root 1.2
1723     =over 4
1724    
1725     =item C<MKBUNDLE>
1726    
1727     Where F<staticperl> writes the C<mkbundle> command to
1728     (default: F<$STATICPERL/mkbundle>).
1729 root 1.1
1730 root 1.2 =item C<STATICPERL_MODULES>
1731 root 1.1
1732 root 1.2 Additional modules needed by C<mkbundle> - should therefore not be changed
1733     unless you know what you are doing.
1734    
1735     =back
1736    
1737     =head3 OVERRIDABLE HOOKS
1738    
1739     In addition to environment variables, it is possible to provide some
1740     shell functions that are called at specific times. To provide your own
1741 root 1.4 commands, just define the corresponding function.
1742 root 1.2
1743     Example: install extra modules from CPAN and from some directories
1744     at F<staticperl install> time.
1745    
1746     postinstall() {
1747 root 1.5 rm -rf lib/threads* # weg mit Schaden
1748 root 1.2 instcpan IO::AIO EV
1749     instsrc ~/src/AnyEvent
1750     instsrc ~/src/XML-Sablotron-1.0100001
1751 root 1.5 instcpan Anyevent::AIO AnyEvent::HTTPD
1752 root 1.2 }
1753    
1754     =over 4
1755    
1756     =item postconfigure
1757    
1758     Called after configuring, but before building perl. Current working
1759     directory is the perl source directory.
1760    
1761     Could be used to tailor/patch config.sh (followed by F<./Configure -S>) or
1762     do any other modifications.
1763    
1764     =item postbuild
1765    
1766     Called after building, but before installing perl. Current working
1767     directory is the perl source directory.
1768    
1769     I have no clue what this could be used for - tell me.
1770    
1771     =item postinstall
1772    
1773     Called after perl and any extra modules have been installed in C<$PREFIX>,
1774     but before setting the "installation O.K." flag.
1775    
1776     The current working directory is C<$PREFIX>, but maybe you should not rely
1777     on that.
1778    
1779     This hook is most useful to customise the installation, by deleting files,
1780     or installing extra modules using the C<instcpan> or C<instsrc> functions.
1781    
1782     The script must return with a zero exit status, or the installation will
1783     fail.
1784 root 1.1
1785 root 1.2 =back
1786 root 1.1
1787 root 1.7 =head1 ANATOMY OF A BUNDLE
1788    
1789     When not building a new perl binary, C<mkbundle> will leave a number of
1790     files in the current working directory, which can be used to embed a perl
1791     interpreter in your program.
1792    
1793     Intimate knowledge of L<perlembed> and preferably some experience with
1794     embedding perl is highly recommended.
1795    
1796     C<mkperl> (or the C<--perl> option) basically does this to link the new
1797     interpreter (it also adds a main program to F<bundle.>):
1798    
1799     $Config{cc} $(cat bundle.ccopts) -o perl bundle.c $(cat bundle.ldopts)
1800    
1801     =over 4
1802    
1803     =item bundle.h
1804    
1805     A header file that contains the prototypes of the few symbols "exported"
1806     by bundle.c, and also exposes the perl headers to the application.
1807    
1808     =over 4
1809    
1810     =item staticperl_init ()
1811    
1812     Initialises the perl interpreter. You can use the normal perl functions
1813     after calling this function, for example, to define extra functions or
1814     to load a .pm file that contains some initialisation code, or the main
1815     program function:
1816    
1817     XS (xsfunction)
1818     {
1819     dXSARGS;
1820    
1821     // now we have items, ST(i) etc.
1822     }
1823    
1824     static void
1825     run_myapp(void)
1826     {
1827     staticperl_init ();
1828     newXSproto ("myapp::xsfunction", xsfunction, __FILE__, "$$;$");
1829     eval_pv ("require myapp::main", 1); // executes "myapp/main.pm"
1830     }
1831    
1832     =item staticperl_xs_init (pTHX)
1833    
1834     Sometimes you need direct control over C<perl_parse> and C<perl_run>, in
1835     which case you do not want to use C<staticperl_init> but call them on your
1836     own.
1837    
1838     Then you need this function - either pass it directly as the C<xs_init>
1839     function to C<perl_parse>, or call it from your own C<xs_init> function.
1840    
1841     =item staticperl_cleanup ()
1842    
1843     In the unlikely case that you want to destroy the perl interpreter, here
1844     is the corresponding function.
1845    
1846     =item PerlInterpreter *staticperl
1847    
1848     The perl interpreter pointer used by staticperl. Not normally so useful,
1849     but there it is.
1850    
1851     =back
1852    
1853     =item bundle.ccopts
1854    
1855     Contains the compiler options required to compile at least F<bundle.c> and
1856     any file that includes F<bundle.h> - you should probably use it in your
1857     C<CFLAGS>.
1858    
1859     =item bundle.ldopts
1860    
1861     The linker options needed to link the final program.
1862    
1863     =back
1864    
1865     =head1 RUNTIME FUNCTIONALITY
1866    
1867     Binaries created with C<mkbundle>/C<mkperl> contain extra functions, which
1868     are required to access the bundled perl sources, but might be useful for
1869     other purposes.
1870    
1871     In addition, for the embedded loading of perl files to work, F<staticperl>
1872     overrides the C<@INC> array.
1873    
1874     =over 4
1875    
1876     =item $file = staticperl::find $path
1877    
1878     Returns the data associated with the given C<$path>
1879     (e.g. C<Digest/MD5.pm>, C<auto/POSIX/autosplit.ix>), which is basically
1880     the UNIX path relative to the perl library directory.
1881    
1882     Returns C<undef> if the file isn't embedded.
1883    
1884 root 1.8 =item @paths = staticperl::list
1885 root 1.7
1886     Returns the list of all paths embedded in this binary.
1887    
1888     =back
1889    
1890 root 1.8 =head1 FULLY STATIC BINARIES - BUILDROOT
1891    
1892     To make truly static (Linux-) libraries, you might want to have a look at
1893     buildroot (L<http://buildroot.uclibc.org/>).
1894    
1895     Buildroot is primarily meant to set up a cross-compile environment (which
1896     is not so useful as perl doesn't quite like cross compiles), but it can also compile
1897     a chroot environment where you can use F<staticperl>.
1898    
1899     To do so, download buildroot, and enable "Build options => development
1900     files in target filesystem" and optionally "Build options => gcc
1901     optimization level (optimize for size)". At the time of writing, I had
1902     good experiences with GCC 4.4.x but not GCC 4.5.
1903    
1904     To minimise code size, I used C<-pipe -ffunction-sections -fdata-sections
1905     -finline-limit=8 -fno-builtin-strlen -mtune=i386>. The C<-mtune=i386>
1906     doesn't decrease codesize much, but it makes the file much more
1907     compressible.
1908    
1909     If you don't need Coro or threads, you can go with "linuxthreads.old" (or
1910     no thread support). For Coro, it is highly recommended to switch to a
1911     uClibc newer than 0.9.31 (at the time of this writing, I used the 20101201
1912     snapshot) and enable NPTL, otherwise Coro needs to be configured with the
1913     ultra-slow pthreads backend to work around linuxthreads bugs (it also uses
1914     twice the address space needed for stacks).
1915    
1916     If you use C<linuxthreads.old>, then you should also be aware that
1917     uClibc shares C<errno> between all threads when statically linking. See
1918     L<http://lists.uclibc.org/pipermail/uclibc/2010-June/044157.html> for a
1919     workaround (And L<https://bugs.uclibc.org/2089> for discussion).
1920    
1921 root 1.10 C<ccache> support is also recommended, especially if you want
1922     to play around with buildroot options. Enabling the C<miniperl>
1923     package will probably enable all options required for a successful
1924     perl build. F<staticperl> itself additionally needs either C<wget>
1925     (recommended, for CPAN) or C<curl>.
1926 root 1.8
1927     As for shells, busybox should provide all that is needed, but the default
1928     busybox configuration doesn't include F<comm> which is needed by perl -
1929     either make a custom busybox config, or compile coreutils.
1930    
1931     For the latter route, you might find that bash has some bugs that keep
1932     it from working properly in a chroot - either use dash (and link it to
1933     F</bin/sh> inside the chroot) or link busybox to F</bin/sh>, using it's
1934     built-in ash shell.
1935    
1936     Finally, you need F</dev/null> inside the chroot for many scripts to work
1937     - F<cp /dev/null output/target/dev> or bind-mounting your F</dev> will
1938     both provide this.
1939    
1940     After you have compiled and set up your buildroot target, you can copy
1941     F<staticperl> from the C<App::Staticperl> distribution or from your
1942     perl f<bin> directory (if you installed it) into the F<output/target>
1943     filesystem, chroot inside and run it.
1944    
1945 root 1.1 =head1 AUTHOR
1946    
1947     Marc Lehmann <schmorp@schmorp.de>
1948     http://software.schmorp.de/pkg/staticperl.html
1949