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