--- App-Staticperl/staticperl.pod 2011/06/26 17:26:52 1.43 +++ App-Staticperl/staticperl.pod 2019/03/19 15:24:49 1.63 @@ -1,6 +1,6 @@ =head1 NAME -staticperl - perl, libc, 100 modules, all in one 500kb file +staticperl - perl, libc, 100 modules, all in one standalone 500kb file =head1 SYNOPSIS @@ -13,7 +13,7 @@ staticperl distclean # delete everything installed by this script staticperl perl ... # invoke the perlinterpreter staticperl cpan # invoke CPAN shell - staticperl instmod path... # install unpacked modules + staticperl instsrc path... # install unpacked modules staticperl instcpan modulename... # install modules from CPAN staticperl mkbundle # see documentation staticperl mkperl # see documentation @@ -86,7 +86,7 @@ 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 state hidden dependencies +the future, but right now, you have to resolve hidden dependencies manually. =item * PAR works out of the box, F does not. @@ -204,7 +204,9 @@ Starts an interactive CPAN shell that you can use to install further modules. Installs the perl first if necessary, but apart from that, no magic is involved: you could just as well run it manually via -F<~/.staticperl/perl/bin/cpan>. +F<~/.staticperl/perl/bin/cpan>, except that F additionally +sets the environment variable C<$PERL> to the path of the perl +interpreter, which is handy in subshells. Any additional arguments are simply passed to the F command. @@ -348,7 +350,7 @@ All options that specify modules or files to be added are processed in the order given on the command line. -=head3 BUNDLE CREATION WORKFLOW / STATICPELR MKBUNDLE OPTIONS +=head3 BUNDLE CREATION WORKFLOW / STATICPERL MKBUNDLE OPTIONS F works by first assembling a list of candidate files and modules to include, then filtering them by include/exclude @@ -543,22 +545,22 @@ require myfiles::file2; my $res = do "myfiles/file3.pl"; -=item C<--binadd> F | C<--add> "F alias" +=item C<--addbin> F | C<--addbin> "F alias" Just like C<--add>, except that it treats the file as binary and adds it without any postprocessing (perl files might get stripped to reduce their size). -If you specify an alias you should probably add a C<&> prefix to avoid -clashing with embedded perl files (whose paths never start with C<&>), -and/or use a special directory prefix, such as C<&res/name>. +If you specify an alias you should probably add a C prefix to avoid +clashing with embedded perl files (whose paths never start with C), +and/or use a special directory prefix, such as C. -You can later get a copy of these files by calling C. An alternative way to embed binary files is to convert them to perl and use C to get the contents - this method is a bit cumbersome, but works -both inside and outside of a staticperl bundle: +both inside and outside of a staticperl bundle, without extra ado: # a "binary" file, call it "bindata.pl" <<'SOME_MARKER' @@ -568,6 +570,23 @@ # load the binary chomp (my $data = do "bindata.pl"); +=item C<--allow-dynamic> + +By default, when F hits a dynamic perl extension (e.g. a F<.so> +or F<.dll> file), it will stop with a fatal error. + +When this option is enabled, F packages the shared +object into the bundle instead, with a prefix of F +(e.g. F). What you do with that is currently up +to you, F has no special support for this at the moment, apart +from working around the lack of availability of F while +bootstrapping, at a speed cost. + +One way to deal with this is to write all files starting with F into +some directory and then C that path onto C<@INC>. + +#TODO: example + =back =item Step 2: filter all files using C<--include> and C<--exclude> options. @@ -735,7 +754,7 @@ Specifically, these are removed: -C and C can cause underaible +C and C can cause undesirable output, C, C, C and C can alter execution significantly, and C, C and C can affect input and output. @@ -783,6 +802,22 @@ # ldopts might now contain: # -lm -Wl,-Bstatic -lcrypt -Wl,-Bdynamic -lpthread +=item C<--extra-cflags> string + +Specifies extra compiler flags, used when compiling the bundle file. The +flags are appended to all the existing flags, so can be sued to override +settings. + +=item C<--extra-ldflags> string + +Specifies extra linker flags, used when linking the bundle. + +=item C<--extra-libs> string + +Extra linker flags, appended at the end when linking. The difference to +C<--extra-ldflags> is that the ldflags are appended to the flags, before +the objects and libraries, and the extra libs are added at the end. + =back =back @@ -892,20 +927,30 @@ =item C -The perl version to install - default is currently C<5.12.3>, but C<5.8.9> -is also a good choice (5.8.9 is much smaller than 5.12.3, while 5.10.1 is -about as big as 5.12.3). +The perl version to install - C<5.12.5> is a good choice for small builds, +but C<5.8.9> is also a good choice (5.8.9 is much smaller than 5.12.5), if +it builds on your system. + +You can also set this variable to the absolute URL of a tarball (F<.tar>, +F<.tar.gz>, F<.tar.bz2>, F<.tar.lzma> or F<.tar.xz>), or to the absolute +path of an unpacked perl source tree, which will be copied. + +The default is currently +F, i.e. the latest +stableperl release. =item C, C, ... Usually set to C<1> to make modules "less inquisitive" during their -installation, you can set any environment variable you want - some modules -(such as L or L) use environment variables for further tweaking. +installation. You can set (and export!) any environment variable you want +- some modules (such as L or L) use environment variables for +further tweaking. =item C -The prefix where perl gets installed (default: F<$STATICPERL/perl>), -i.e. where the F and F subdirectories will end up. +The directory where perl gets installed (default: F<$STATICPERL/perl>), +i.e. where the F and F subdirectories will end up. Previous +contents will be removed on installation. =item C @@ -931,10 +976,23 @@ Most of the variables override (or modify) the corresponding F variable, except C, which gets appended. -You should have a look near the beginning of the F script - -staticperl tries to default C to some psace-saving options -suitable for newer gcc versions. For other compilers or older versions you -need to adjust these, for example, in your F<~/.staticperlrc>. +The default for C is C<-Os> (assuming gcc), and for +C is C<-lm -lcrypt>, which should be good for most (but not +all) systems. + +For other compilers or more customised optimisation settings, you need to +adjust these, e.g. in your F<~/.staticperlrc>. + +With gcc on x86 and amd64, you can get more space-savings by using: + + -Os -ffunction-sections -fdata-sections -finline-limit=8 -mpush-args + -mno-inline-stringops-dynamically -mno-align-stringops + +And on x86 and pentium3 and newer (basically everything you might ever +want to run on), adding these is even better for space-savings (use +-mtune=core2 or something newer for much faster code, too): + + -fomit-frame-pointer -march=pentium3 -mtune=i386 =back @@ -1123,83 +1181,93 @@ =head1 RUNTIME FUNCTIONALITY -Binaries created with C/C contain extra functions, which -are required to access the bundled perl sources, but might be useful for -other purposes. +Binaries created with C/C contain extra functionality, +mostly related to the extra files bundled in the binary (the virtual +filesystem). All of this data is statically compiled into the binary, and +accessing means copying it from a read-only section of your binary. Data +pages in this way are usually freed by the operating system, as they aren't +used more then once. + +=head2 VIRTUAL FILESYSTEM + +Every bundle has a virtual filesystem. The only information stored in it +is the path and contents of each file that was bundled. + +=head3 LAYOUT + +Any path starting with an ampersand (F<&>) or exclamation mark (F) are +reserved by F. They must only be used as described in this +section. -In addition, for the embedded loading of perl files to work, F -overrides the C<@INC> array. +=over 4 + +=item ! + +All files that typically cannot be loaded from memory (such as dynamic +objects or shared libraries), but have to reside in the filesystem, are +prefixed with F. Typically these files get written out to some +(semi-)temporary directory shortly after program startup, or before being +used. + +=item !boot + +The bootstrap file, if specified during bundling. + +=item !auto/ + +Shared objects or dlls corresponding to dynamically-linked perl extensions +are stored with an F prefix. + +=item !lib/ + +External shared libraries are stored in this directory. + +=item any letter + +Any path starting with a letter is a perl library file. For example, +F corresponds to the file loaded by C, and +F corresponds to C. + +Obviously, module names shouldn't start with any other characters than +letters :) + +=back + +=head3 FUNCTIONS =over 4 -=item $file = staticperl::find $path +=item $file = static::find $path Returns the data associated with the given C<$path> -(e.g. C, C), which is basically -the UNIX path relative to the perl library directory. +(e.g. C, C). Returns C if the file isn't embedded. -=item @paths = staticperl::list +=item @paths = static::list Returns the list of all paths embedded in this binary. =back -=head1 FULLY STATIC BINARIES - UCLIBC AND BUILDROOT +=head2 EXTRA FEATURES -To make truly static (Linux-) libraries, you might want to have a look at -buildroot (L). +In addition, for the embedded loading of perl files to work, F +overrides the C<@INC> array. + +=head1 FULLY STATIC BINARIES - ALPINE LINUX -Buildroot is primarily meant to set up a cross-compile environment (which -is not so useful as perl doesn't quite like cross compiles), but it can also compile -a chroot environment where you can use F. - -To do so, download buildroot, and enable "Build options => development -files in target filesystem" and optionally "Build options => gcc -optimization level (optimize for size)". At the time of writing, I had -good experiences with GCC 4.4.x but not GCC 4.5. - -To minimise code size, I used C<-pipe -ffunction-sections -fdata-sections --finline-limit=8 -fno-builtin-strlen -mtune=i386>. The C<-mtune=i386> -doesn't decrease codesize much, but it makes the file much more -compressible (and the execution a lot slower...). - -If you don't need Coro or threads, you can go with "linuxthreads.old" (or -no thread support). For Coro, it is highly recommended to switch to a -uClibc newer than 0.9.31 (at the time of this writing, I used the 20101201 -snapshot) and enable NPTL, otherwise Coro needs to be configured with the -ultra-slow pthreads backend to work around linuxthreads bugs (it also uses -twice the address space needed for stacks). - -If you use C, then you should also be aware that -uClibc shares C between all threads when statically linking. See -L for a -workaround (and L for discussion). - -C support is also recommended, especially if you want -to play around with buildroot options. Enabling the C -package will probably enable all options required for a successful -perl build. F itself additionally needs either C -(recommended, for CPAN) or C. - -As for shells, busybox should provide all that is needed, but the default -busybox configuration doesn't include F which is needed by perl - -either make a custom busybox config, or compile coreutils. - -For the latter route, you might find that bash has some bugs that keep -it from working properly in a chroot - either use dash (and link it to -F inside the chroot) or link busybox to F, using it's -built-in ash shell. - -Finally, you need F inside the chroot for many scripts to work -- either F or bind-mounting your F -will provide this. - -After you have compiled and set up your buildroot target, you can copy -F from the C distribution or from your -perl F directory (if you installed it) into the F -filesystem, chroot inside and run it. +This section once contained a way to build fully static (including +uClibc) binaries with buildroot. Unfortunately, buildroot no longer +supports a compiler, so I recommend using alpine linux instead +(L). Get yourself a VM (e.g. with qemu), run an +older alpine linux verison in it (e.g. 2.4), copy staticperl inside and +use it. + +The reason you might want an older alpine linux is that uClibc can be +quite dependent on kernel versions, so the newest version of alpine linux +might need a newer kernel then you might want for, if you plan to run your +binaries on on other kernels. =head1 RECIPES / SPECIFIC MODULES @@ -1272,6 +1340,28 @@ See Pango, same problems, same solution. +=item 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 C 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 + } + =item Pango In addition to the C problem in Glib, Pango also routes around @@ -1348,7 +1438,14 @@ =back +=head1 ADDITIONAL RESOURCES + +Some guy has made a repository on github +(L) with some modules +patched to build with staticperl. + =head1 AUTHOR Marc Lehmann http://software.schmorp.de/pkg/staticperl.html +