App-Staticperl
view release on metacpan or search on metacpan
NAME
staticperl - perl, libc, 100 modules, all in one standalone 500kb file
SYNOPSIS
staticperl help # print the embedded documentation
staticperl fetch # fetch and unpack perl sources
staticperl configure # fetch and then configure perl
staticperl build # configure and then build perl
staticperl install # build and then install perl
staticperl clean # clean most intermediate files (restart at configure)
staticperl distclean # delete everything installed by this script
staticperl perl ... # invoke the perlinterpreter
staticperl cpan # invoke CPAN shell
staticperl instsrc path... # install unpacked modules
staticperl instcpan modulename... # install modules from CPAN
staticperl mkbundle <bundle-args...> # see documentation
staticperl mkperl <bundle-args...> # see documentation
staticperl mkapp appname <bundle-args...> # see documentation
Typical Examples:
staticperl install # fetch, configure, build and install perl
staticperl cpan # run interactive cpan shell
staticperl mkperl -MConfig_heavy.pl # build a perl that supports -V
staticperl mkperl -MAnyEvent::Impl::Perl -MAnyEvent::HTTPD -MURI -MURI::http
# build a perl with the above modules linked in
staticperl mkapp myapp --boot mainprog mymodules
# build a binary "myapp" from mainprog and mymodules
DESCRIPTION
This script helps you to create single-file perl interpreters or
applications, or embedding a perl interpreter in your applications.
Single-file means that it is fully self-contained - no separate shared
objects, no autoload fragments, no .pm or .pl files are needed. And when
linking statically, you can create (or embed) a single file that
contains perl interpreter, libc, all the modules you need, all the
libraries you need and of course your actual program.
With uClibc and upx on x86, you can create a single 500kb binary that
contains perl and 100 modules such as POSIX, AnyEvent, EV, IO::AIO, Coro
and so on. Or any other choice of modules (and some other size :).
To see how this turns out, you can try out smallperl and bigperl, two
pre-built static and compressed perl binaries with many and even more
modules: just follow the links at <http://staticperl.schmorp.de/>.
The created files do not need write access to the file system (like PAR
does). In fact, since this script is in many ways similar to
PAR::Packer, here are the differences:
* The generated executables are much smaller than PAR created ones.
Shared objects and the perl binary contain a lot of extra info,
while the static nature of staticperl allows the linker to remove
all functionality and meta-info not required by the final
executable. Even extensions statically compiled into perl at build
time will only be present in the final executable when needed.
In addition, staticperl can strip perl sources much more effectively
than PAR.
* The generated executables start much faster.
There is no need to unpack files, or even to parse Zip archives
(which is slow and memory-consuming business).
* The generated executables don't need a writable filesystem.
staticperl loads all required files directly from memory. There is
no need to unpack files into a temporary directory.
* More control over included files, more burden.
PAR tries to be maintenance and hassle-free - it tries to include
more files than necessary to make sure everything works out of the
box. It mostly succeeds at this, but he extra files (such as the
unicode database) can take substantial amounts of memory and file
size.
With staticperl, the burden is mostly with the developer - only
direct compile-time dependencies and AutoLoader are handled
automatically. This means the modules to include often need to be
tweaked manually.
All this does not preclude more permissive modes to be implemented
in the future, but right now, you have to resolve hidden
dependencies manually.
* PAR works out of the box, staticperl does not.
Maintaining your own custom perl build can be a pain in the ass, and
while staticperl tries to make this easy, it still requires a custom
perl build and possibly fiddling with some modules. PAR is likely to
produce results faster.
environment variable.
Gtk2
See Pango, same problems, same solution.
Net::SSLeay
This module hasn't been significantly updated since OpenSSL is
called OpenSSL, and fails to properly link against dependent
libraries, most commonly, it forgets to specify -ldl when linking.
On GNU/Linux systems this usually goes undetected, as perl usually
links against -ldl itself and OpenSSL just happens to pick it up
that way, by chance.
For static builds, you either have to configure -ldl manually, or
you cna use the following snippet in your "postinstall" hook which
patches Net::SSLeay after installation, which happens to work most
of the time:
postinstall() {
# first install it
instcpan Net::SSLeay
# then add -ldl for future linking
chmod u+w "$PERL_PREFIX"/lib/auto/Net/SSLeay/extralibs.ld
echo " -ldl" >>"$PERL_PREFIX"/lib/auto/Net/SSLeay/extralibs.ld
}
Pango
In addition to the "MAN3PODS" problem in Glib, Pango also routes
around ExtUtils::MakeMaker by compiling its files on its own.
staticperl tries to patch ExtUtils::MM_Unix to route around Pango.
Term::ReadLine::Perl
Also needs Term::ReadLine::readline, or "--usepacklists".
URI URI implements schemes as separate modules - the generic URL scheme
is implemented in URI::_generic, HTTP is implemented in URI::http.
If you need to use any of these schemes, you should include these
manually, or use "--usepacklists".
RECIPES
Just link everything in
To link just about everything installed in the perl library into a
new perl, try this (the first time this runs it will take a long
time, as a lot of files need to be parsed):
staticperl mkperl -v --strip ppi --incglob '*'
If you don't mind the extra megabytes, this can be a very effective
way of creating bundles without having to worry about forgetting any
modules.
You get even more useful variants of this method by first selecting
everything, and then excluding stuff you are reasonable sure not to
need - bigperl <http://staticperl.schmorp.de/bigperl.html> uses this
approach.
Getting rid of netdb functions
The perl core has lots of netdb functions ("getnetbyname",
"getgrent" and so on) that few applications use. You can avoid
compiling them in by putting the following fragment into a
"preconfigure" hook:
preconfigure() {
for sym in \
d_getgrnam_r d_endgrent d_endgrent_r d_endhent \
d_endhostent_r d_endnent d_endnetent_r d_endpent \
d_endprotoent_r d_endpwent d_endpwent_r d_endsent \
d_endservent_r d_getgrent d_getgrent_r d_getgrgid_r \
d_getgrnam_r d_gethbyaddr d_gethent d_getsbyport \
d_gethostbyaddr_r d_gethostbyname_r d_gethostent_r \
d_getlogin_r d_getnbyaddr d_getnbyname d_getnent \
d_getnetbyaddr_r d_getnetbyname_r d_getnetent_r \
d_getpent d_getpbyname d_getpbynumber d_getprotobyname_r \
d_getprotobynumber_r d_getprotoent_r d_getpwent \
d_getpwent_r d_getpwnam_r d_getpwuid_r d_getsent \
d_getservbyname_r d_getservbyport_r d_getservent_r \
d_getspnam_r d_getsbyname
# d_gethbyname
do
PERL_CONFIGURE="$PERL_CONFIGURE -U$sym"
done
}
This mostly gains space when linking statically, as the functions
will likely not be linked in. The gain for dynamically-linked
binaries is smaller.
Also, this leaves "gethostbyname" in - not only is it actually used
often, the Socket module also exposes it, so leaving it out usually
gains little. Why Socket exposes a C function that is in the core
already is anybody's guess.
ADDITIONAL RESOURCES
Some guy has made a repository on github
(<https://github.com/gh0stwizard/staticperl-modules>) with some modules
patched to build with staticperl.
AUTHOR
Marc Lehmann <schmorp@schmorp.de>
http://software.schmorp.de/pkg/staticperl.html
( run in 1.614 second using v1.01-cache-2.11-cpan-b16cb0d3907 )