ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Perl-LibExtractor/bin/perl-libextractor
Revision: 1.8
Committed: Mon Sep 23 13:03:48 2013 UTC (13 years ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +4 -0 lines
Error occurred while calculating annotation data.
Log Message:
*** empty log message ***

File Contents

# Content
1 #!/opt/bin/perl
2
3 =head1 NAME
4
5 perl-libextractor - determine perl library subsets for building distributions
6
7 =head1 SYNOPSIS
8
9 perl-libextractor ...
10
11 General Options:
12
13 -v verbose
14 --version display version
15 -I path prepend path to @INC
16 --no-packlists do not use packlists
17
18 Selection:
19
20 -Mmodule load and trace module
21 --script progname add executable script
22 --eval | -e str trace execution of perl string
23 --perl add perl interpreter itself
24 --core-support add core support
25 --unicore add unicore database
26 --core add perl core library
27 --glob glob add library files select by glob
28 --filter pat,... apply include/exclude patterns
29 --runtime-only remove files not needed for execution
30
31 Modes:
32
33 --list list source and destination paths
34
35 --dstlist list destination paths
36
37 --srclist list source paths
38
39 --copy path copy files to a target path
40 --bindir path perl executable target ("exe")
41 --dlldir path shared library target ("dll")
42 --scriptdir path executable script target ("bin")
43 --libdir path perl library target ("lib")
44 --strip strip .pl and .pm files
45 --cache-dir path cache directory to use
46 --binstrip "..." strip binaries and dlls
47
48 =head1 DESCRIPTION
49
50 This program can be used to extract a subset of your perl installation,
51 with the intention of building software distributions. Or in other words,
52 this module finds all files necessary to run a perl program (library
53 files, perl executable, scripts).
54
55 The resulting set can then be displayed or copied to another directory,
56 while optionally stripping the perl sources to make them smaller.
57
58 =head2 OPTIONS
59
60 This manpage gives only rudimentary documentation for options that have an
61 equivalent in L<Perl::LibExtractor>, so look there for details.
62
63 Options are not processed in order specified on the commandline, but in
64 multiple phases (e.g., C<-I> gets executed before any C<-M> option).
65
66 =head3 GENERAL OPTIONS
67
68 These options configure basic settings.
69
70 =over 4
71
72 =item C<--verbose>
73
74 =item C<-v>
75
76 Increases verbosity - highly recommended for interactive use.
77
78 =item C<--version>
79
80 Display the version of L<Perl::LibExtractor>.
81
82 =item C<-I> I<path>
83
84 Prepends the given path to C<@INC> when searching perl library directories
85 (the last C<-I> option is prepended first).
86
87 =item C<--no-packlists>
88
89 Packlists allow to package all of a distribution, including resource files
90 not found through the normal tracing mechanism. This option disaables use
91 of packlists (normally highly recommended).
92
93 Some especially broken perls (Debian GNU/Linux...) have missing files,
94 so this option doesn't work with them, at least not for any packages
95 distributed by debian (packages installed through CPAN or any other
96 non-dpkg-mechanism work fine).
97
98 =back
99
100 =head3 SELECTION
101
102 These options specify and modify module selections. They are executed in
103 the order stated on the commandline, and when in doubt, you should use
104 them in the order documented here.
105
106 =over 4
107
108 =item C<-M>I<module>
109
110 Load the named module and trace direct dependencies
111 (e.g. F<-MCarp>). Same as C<add_mod> in L<Perl::LibExtractor>.
112
113 =item C<--script> I<progname>
114
115 Compile the (installed) script I<progname> and trace dependencies
116 (e.g. F<corelist>). Same as C<add_bin> in L<Perl::LibExtractor>.
117
118 The program should be installed in one of the standard paths for perl
119 programs - C<$Config{sitebin}>, C<$Config{vendorbin}> or C<$Config{bin}>,
120 or must be specified via an absolute path (starting with F</>).
121
122 =item C<--eval> I<string>
123
124 =item C<-e str> I<string>
125
126 Compile and execute the givne perl code, and trace dependencies (e.g. F<-e
127 "use AnyEvent; AnyEvent::detect">). Same as C<add_eval> in L<Perl::LibExtractor>.
128
129 =item C<--perl>
130
131 Adds the perl interpreter itself, including libperl if required to run
132 perl. Same as C<add_perl> in L<Perl::LibExtractor>.
133
134 =item C<--core-support>
135
136 Add all support files needed to support built-in features of perl (such
137 as C<ucfirst>), which is usually the minimum you should add from the core
138 library. Same as C<add_core_support> in L<Perl::LibExtractor>.
139
140 =item C<--unicore>
141
142 Add the whole unicore database, which is big, contains many, many files
143 and is usually not needed to run a program. Same as C<add_unicore> in
144 L<Perl::LibExtractor>.
145
146 =item C<--core>
147
148 Add the complete perl core library, which includes everything added
149 by F<--core-support> and F<--unicore>. Same as C<add_core> in
150 L<Perl::LibExtractor>.
151
152 Some especially broken perls (Debian GNU/Linux...) have missing files, so
153 this option doesn't work with them.
154
155 =item C<--glob glob>
156
157 Add all files from the perl library directories that match the given
158 extended glob pattern. Same as C<add_glob> in L<Perl::LibExtractor>, also
159 see there for the syntax of glob patterns.
160
161 Example: add AnyEvent.pm and all AnyEvent::xxx modules installed.
162
163 --glob Coro --glob "Coro::*"
164
165 =item C<--filter pat,...>
166
167 Apply a comma-separated series of extended glob patterns, prefixed by
168 C<+> (include) or C<-> (for exclude patterns). Same as C<filter> in
169 L<Perl::LibExtractor>, also see there for exact semantics and syntax.
170
171 Example: remove all F<*.al> files in F<auto/POSIX>, except F<memset.al>.
172
173 --filter "+/lib/auto/POSIX/memset.al,-/lib/auto/POSIX/*.al"
174
175 =item C<--runtime-only>
176
177 Remove all files not needed to run any scripts, such as debug info
178 files, link libraries, pod files and so on. Same as C<runtime_only> in
179 L<Perl::LibExtractor>.
180
181 =back
182
183 =head3 MODES
184
185 These options select a specific work mode. Work modes might have specific
186 options to control them further.
187
188 =over 4
189
190 =item C<--list>
191
192 Lists all selected files in two columns, first column is destination path,
193 second column is source path and first line is a header line.
194
195 =item C<--dstlist>
196
197 Same as C<--list>, but only list destination paths and has no header -
198 intended for scripts.
199
200 =item C<--srclist>
201
202 Same as C<--list>, but only list source paths and has no header -
203 intended for scripts.
204
205 =item C<--copy> I<path>
206
207 Copy all selected files to the respective position under the directory
208 I<path> - previous contents of the directory will be list.
209
210 This mode has the following suboptions:
211
212 =over 4
213
214 =item C<--exedir> I<path>
215
216 Specifies the subdirectory for binary executables (the perl interpreter itself), instead of
217 the default F<exe/>.
218
219 =item C<--dlldir> I<path>
220
221 Specifies the subdirectory for shared libraries, instead of
222 the default F<dll/>.
223
224 =item C<--bindir> I<path>
225
226 Specifies the subdirectry for perl scripts, instead of
227 the default F<bin/>.
228
229 =item C<--libdir> I<path>
230
231 Specifies the subdirectory for perl library files, instead of
232 the default F<lib/>.
233
234 =item C<--strip>
235
236 Strip all C<.pm>, C<.pl>, C<.al> files and perl executables, which
237 mostly means removal of unecessary whitespace and documentation - see
238 L<Perl::Strip> which is used.
239
240 =item C<--cache-dir> I<path>
241
242 Specify the cache dir to use - the default is F<~/.cache/perlstrip> for
243 cached stripped perl files (compatible to the C<perlstrip> program).
244
245 =item C<--binstrip> I<"...">
246
247 Use the specified program and arguments to strip executables, shared libraries and shared objects.
248
249 This is only necessary when your programs were compiled with debugging
250 info, but can be used to specify extra treatment for all binary files.
251
252 =back
253
254 =back
255
256 =head1 EXAMPLE
257
258 This is how the Deliantra client (L<http://www.deliantra.,net>) is being packages:
259
260 perl-libextractor \
261 --perl --core-support --script deliantra \
262 --runtime-only \
263 --copy distdir --strip --exedir . --dlldir . --bindir pm/bin --libdir pm \
264
265 The first line of arguments adds perl, support for core functions (the
266 Deliantra client does need the full unicode database or perl core) and
267 tells F<perl-libextractor> to parse the installed F<deliantra> script and
268 trace all it's dependencies. The script is installed by installed the
269 C<Deliantra::Client> module from CPAN.
270
271 This finds all required perl dependencies.
272
273 The second line of arguments (F<--runtime-only>) then removes all files
274 not required for execution, slimming down the distribution.
275
276 The last line tells F<perl-libextractor> to copy the resulting files to
277 the directory F<distdir>. The argument F<--strip> tells it to stirp all perl sources
278 (make them smaller by removing whitespace, comments and documentation, which saves about a megabyte).
279
280 The remaining arguments override the default subdirectories for the files,
281 as L<Urlader>, which is used for the binary distribution, works best if
282 dll's and executables are in the top dir.
283
284 After this, the script that builds the distribution does a lot more, for
285 example finding shared libraries (such as pango, SDL and so on), renaming
286 them on OS X to avoid the severe DLL Hell on that platform, and provides
287 a wrapper script that initialises perl so it loads its files from the
288 distribution dir and doesn't try to search anything anywhere else.
289
290 On GNU/Linux, the binaries and libraries are also patched to remove any
291 rpath that Debian might have compiled in and that would keep perl from
292 ignoring C<LD_LIBRARY_PATH>.
293
294 The wrapper script is called C<run>, and looks a bit like this:
295
296 @INC = ("pm", "."); # "." required by newer AutoLoader grrrr.
297 $ENV{PANGO_RC_FILE} = "pango.rc";
298 require "bin/deliantra";
299 exit 0;
300
301 The most important line is the first one, which tells F<perl> where to
302 look for library files.
303
304 =head1 SEE ALSO
305
306 L<App::Staticperl>, L<Urlader>, L<Perl::Strip>.
307
308 =head1 AUTHOR
309
310 Marc Lehmann <schmorp@schmorp.de>
311 http://software.schmorp.de/pkg/staticperl.html
312
313 =cut
314
315 use common::sense;
316
317 use Getopt::Long;
318 use List::Util ();
319 use File::Path ();
320 use File::Basename ();
321 use File::Copy ();
322
323 use Perl::LibExtractor;
324 use Perl::Strip;
325
326 our @INC;
327
328 my $USE_PACKLISTS = 1;
329 my $VERBOSE;
330
331 my $STRIP;
332 my $BINSTRIP;
333 my $CACHE;
334 my $CACHEDIR;
335
336 my %DIR = qw(exe exe dll dll bin bin lib lib);
337
338 $|=1;
339
340 sub usage {
341 require Pod::Usage;
342
343 Pod::Usage::pod2usage (-output => *STDOUT, -verbose => 1, -exitval => 1, -noperldoc => 1);
344 }
345
346 @ARGV
347 or usage;
348
349 Getopt::Long::Configure ("bundling", "no_auto_abbrev", "no_ignore_case");
350
351 my $ex;
352 my $set;
353 my (@phase0, @phase1, @phase2);
354
355 GetOptions
356 "verbose|v" => sub { ++$VERBOSE },
357 "version" => sub {
358 warn "This is perl-libextractor version $Perl::LibExtractor::VERSION\n";
359 },
360
361 "exedir=s" => \$DIR{exe},
362 "dlldir=s" => \$DIR{dll},
363 "bindir=s" => \$DIR{bin},
364 "libdir=s" => \$DIR{lib},
365
366 "I=s" => sub {
367 my $arg = $_[1];
368 unshift @phase0, sub { unshift @INC, $arg };
369 },
370 "no-packlists" => sub { $USE_PACKLISTS = 0 },
371
372 "M=s" => sub {
373 my $arg = $_[1];
374 push @phase1, sub { $ex->add_mod ($arg) };
375 },
376 "script=s" => sub {
377 my $arg = $_[1];
378 push @phase1, sub { $ex->add_bin ($arg) };
379 },
380 "eval|e=s" => sub {
381 my $arg = $_[1];
382 push @phase1, sub { $ex->add_eval ($arg) };
383 },
384 "perl" => sub {
385 push @phase1, sub { $ex->add_perl };
386 },
387 "core-support" => sub {
388 push @phase1, sub { $ex->add_core_support };
389 },
390 "unicore" => sub {
391 push @phase1, sub { $ex->add_unicore };
392 },
393 "core" => sub {
394 push @phase1, sub { $ex->add_core };
395 },
396 "glob=s" => sub {
397 my $arg = $_[1];
398 push @phase1, sub { $ex->add_glob ($arg) };
399 },
400 "filter=s" => sub {
401 my $arg = $_[1];
402 push @phase1, sub { $ex->filter (split /,/, $arg) };
403 },
404 "runtime-only" => sub {
405 push @phase1, sub { $ex->runtime_only };
406 },
407
408 "list" => sub {
409 push @phase2, \&mode_list;
410 },
411 "dstlist" => sub {
412 push @phase2, \&mode_dstlist;
413 },
414 "srclist" => sub {
415 push @phase2, \&mode_srclist;
416 },
417 "copy=s" => sub {
418 my $arg = $_[1];
419 push @phase2, sub { &mode_copy ($arg) };
420 },
421
422 "strip" => \$STRIP,
423 "cache-dir=s" => \$CACHEDIR,
424 "binstrip=s" => \$BINSTRIP,
425
426 or die "try $0 --help\n";
427
428 @phase2
429 or usage;
430
431 # for strip_copy
432 my $STRIPPER = do {
433 my @cache;
434
435 unless (defined $CACHEDIR) {
436 mkdir "$ENV{HOME}/.cache";
437 $CACHEDIR = "$ENV{HOME}/.cache/perlstrip";
438 }
439
440 new Perl::Strip cache => $CACHEDIR, optimise_size => 1
441 };
442
443 sub strip_copy($$) {
444 my ($src, $dst) = @_;
445
446 my $text = do {
447 open my $fh, "<:perlio", $src
448 or die "$src: $!\n";
449
450 local $/;
451 <$fh>
452 };
453
454 printf "$dst: %d ", length $text if $VERBOSE >= 2;
455
456 $text = $STRIPPER->strip ($text);
457
458 printf "to %d bytes... ", length $text if $VERBOSE >= 2;
459
460 open my $fh, ">:perlio", $dst
461 or die "$dst: $!\n";
462 length $text == syswrite $fh, $text
463 or die "$dst: $!\n";
464 close $fh;
465
466 print "ok\n" if $VERBOSE >= 2;
467 }
468
469 sub mode_list {
470 my @keys = sort keys %$set;
471 my $width = List::Util::max map length, @keys;
472
473 printf "%-*.*s %s\n", $width, $width, "SRC", "DST";
474 for (@keys) {
475 printf "%-*.*s %s\n", $width, $width, $_, $set->{$_}[0];
476 }
477 }
478
479 sub mode_dstlist {
480 print map "$_\n", sort keys %$set;
481 }
482
483 sub mode_srclist {
484 print map "$set->{$_}[0]\n", sort keys %$set;
485 }
486
487 sub mode_copy {
488 my $dst = shift;
489 print "deleting $dst.\n" if $VERBOSE;
490 File::Path::rmtree $dst, $VERBOSE >= 2, 0;
491
492 print "populating $dst...\n" if $VERBOSE;
493
494 my %mkdir;
495
496 while (my ($path, $info) = each %$set) {
497 $path =~ m%^([^/]+)(.*)/([^/]+)$%
498 or die "$path: malformed destination path, please report.\n";
499
500 my ($p1, $p2, $f) = ($1, $2, $3);
501
502 my $dstdir = "$dst/$DIR{$p1}$p2";
503
504 File::Path::mkpath $dstdir, $VERBOSE >= 2, 0777
505 unless $mkdir{$dstdir}++;
506
507 my $src = $info->[0];
508
509 if (
510 $STRIP
511 && ($f =~ /\.(?:pm|pl|ix|al)$/
512 || $p1 eq "bin")
513 ) {
514 strip_copy $src, "$dstdir/$f";
515
516 } else {
517 File::Copy::cp $src, "$dstdir/$f"
518 or die "$src => $dstdir/$f: $!";
519
520 if (
521 $f =~ /\.(?:bundle|dyld|so|dll|sl)$/ # TODO
522 || $p1 eq "exe"
523 || $p1 eq "dll"
524 ) {
525 if (defined $BINSTRIP) {
526 system "$BINSTRIP \Q$dstdir/$f";
527 }
528
529 chmod 0777 & ~umask, "$dstdir/$f";
530 }
531 }
532 }
533 }
534
535 $_->() for @phase0;
536
537 $ex = new Perl::LibExtractor use_packlists => $USE_PACKLISTS;
538
539 $_->() for @phase1;
540
541 $set = $ex->set;
542
543 $_->() for @phase2;