ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Perl-LibExtractor/LibExtractor.pm
(Generate patch)

Comparing cvsroot/Perl-LibExtractor/LibExtractor.pm (file contents):
Revision 1.11 by root, Tue Jan 17 21:41:41 2012 UTC vs.
Revision 1.12 by root, Fri Jan 20 00:05:34 2012 UTC

67 67
68Creates a new extractor object. Each extractor object stores some 68Creates a new extractor object. Each extractor object stores some
69configuration options and a subset of files that can be queried at any 69configuration options and a subset of files that can be queried at any
70time,. 70time,.
71 71
72Binary executables (such as the perl interpreter) are stored inside
73F<bin/>, perl scripts are stored under F<script/>, perl library files are
74stored under F<lib/> and shared libraries are stored under F<dll/>.
75
72The following key-value pairs exist, with default values as specified. 76The following key-value pairs exist, with default values as specified.
73 77
74=over 4 78=over 4
75
76=item exedir => "bin"
77
78The prefix to use for the suggested target path for perl executables
79(scripts). Defaults to F<bin>.
80
81=item libdir => "lib"
82
83The prefix to use for the suggested target path of perl library
84files (F<.pm>, F<.pl>, dynamic objects, autoloader index and files
85etc.). Defaults to F<lib>.
86
87=item bindir => "bin"
88
89The prefix to use for the suggested target path for (non-perl)
90executables. Defaults to F<bin>.
91
92=item dlldir => "bin"
93
94The prefix to use for the suggested target path of any shared
95libraries. Defaults to F<bin>.
96 79
97=item inc => \@INC without "." 80=item inc => \@INC without "."
98 81
99An arrayref with paths to perl library directories. The default is 82An arrayref with paths to perl library directories. The default is
100C<\@INC>, with F<.> removed. 83C<\@INC>, with F<.> removed.
117 100
118sub new { 101sub new {
119 my ($class, %kv) = @_; 102 my ($class, %kv) = @_;
120 103
121 my $self = bless { 104 my $self = bless {
122 exedir => "bin",
123 libdir => "lib",
124 bindir => "bin",
125 dlldir => "bin",
126 inc => [grep $_ ne ".", @INC], 105 inc => [grep $_ ne ".", @INC],
127 use_packlist => 1, 106 use_packlist => 1,
128 %kv, 107 %kv,
129 set => {}, 108 set => {},
130 }, $class; 109 }, $class;
131 110
299 278
300 my $lib = $self->{lib}; 279 my $lib = $self->{lib};
301 my $path; 280 my $path;
302 281
303 for (@$add) { 282 for (@$add) {
304 $path = "$self->{libdir}/$_"; 283 $path = "lib/$_";
305 284
306 $self->{set}{$path} ||= do { 285 $self->{set}{$path} ||= do {
307 my @info; 286 my @info;
308 287
309 $info[I_SRC] = $lib->{$_} 288 $info[I_SRC] = $lib->{$_}
310 or croak "$_: unable to locate file in perl library"; 289 or croak "$_: unable to locate file in perl library";
311 290
312 if ($self->{use_packlist} && exists $self->{packlist}{$_}) { 291 if ($self->{use_packlist} && exists $self->{packlist}{$_}) {
313 $self->{set}{"$self->{libdir}/$_"} ||= [$self->{lib}{$_} or die] 292 $self->{set}{"lib/$_"} ||= [$self->{lib}{$_} or die]
314 for @{ $self->{packlist}{$_} }; 293 for @{ $self->{packlist}{$_} };
315 294
316# for (grep /\.pm$/, @{ $self->{packlist}{$_} }) { 295# for (grep /\.pm$/, @{ $self->{packlist}{$_} }) {
317# s/\.pm$//; 296# s/\.pm$//;
318# s%/%::%g; 297# s%/%::%g;
333 # auto dir exists, scan it for cool stuff 312 # auto dir exists, scan it for cool stuff
334 313
335 # 1. shared object, others are of no interest to us 314 # 1. shared object, others are of no interest to us
336 my $so = "$auto$base.$Config{dlext}"; 315 my $so = "$auto$base.$Config{dlext}";
337 if (my $src = $lib->{$so}) { 316 if (my $src = $lib->{$so}) {
338 $so = "$self->{libdir}/$so"; 317 $so = "lib/$so";
339 push @{ $info[I_DEP] }, $so; $self->{set}{$so} = [$src]; 318 push @{ $info[I_DEP] }, $so; $self->{set}{$so} = [$src];
340 } 319 }
341 320
342 # 2. autoloader/autosplit 321 # 2. autoloader/autosplit
343 my $ix = "${auto}autosplit.ix"; 322 my $ix = "${auto}autosplit.ix";
344 if (my $src = $lib->{$ix}) { 323 if (my $src = $lib->{$ix}) {
345 $ix = "$self->{libdir}/$ix"; 324 $ix = "lib/$ix";
346 push @{ $info[I_DEP] }, $ix; $self->{set}{$ix} = [$src]; 325 push @{ $info[I_DEP] }, $ix; $self->{set}{$ix} = [$src];
347 326
348 open my $fh, "<:perlio", $src 327 open my $fh, "<:perlio", $src
349 or croak "$src: $!"; 328 or croak "$src: $!";
350 329
354 if (/^\s*sub\s+ ([^[:space:];]+) \s* (?:\([^)]*\))? \s*;?\s*$/x) { 333 if (/^\s*sub\s+ ([^[:space:];]+) \s* (?:\([^)]*\))? \s*;?\s*$/x) {
355 my $al = "auto/$package/$1.al"; 334 my $al = "auto/$package/$1.al";
356 my $src = $lib->{$al} 335 my $src = $lib->{$al}
357 or croak "$al: autoload file not found, but should be there."; 336 or croak "$al: autoload file not found, but should be there.";
358 337
359 $al = "$self->{libdir}/$al"; 338 $al = "lib/$al";
360 push @{ $info[I_DEP] }, $al; $self->{set}{$al} = [$src]; 339 push @{ $info[I_DEP] }, $al; $self->{set}{$al} = [$src];
361 340
362 } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) { 341 } elsif (/^\s*package\s+([^[:space:];]+)\s*;?\s*$/) {
363 ($package = $1) =~ s/::/\//g; 342 ($package = $1) =~ s/::/\//g;
364 } elsif (/^\s*(?:#|1?\s*;?\s*$)/) { 343 } elsif (/^\s*(?:#|1?\s*;?\s*$)/) {
457 $self->_trace ("use $_", "{ package $pkg; use $_ }") 436 $self->_trace ("use $_", "{ package $pkg; use $_ }")
458 unless $self->{add_mod}{$_}++; 437 unless $self->{add_mod}{$_}++;
459 } 438 }
460} 439}
461 440
462=item $extractor->add_script ($name[, $name...]) 441=item $extractor->add_bin ($name[, $name...])
463 442
464Adds the given (perl) program(s) to the file set, that is, a program 443Adds the given (perl) program(s) to the file set, that is, a program
465installed by some perl module, written in perl (an example would be the 444installed by some perl module, written in perl (an example would be the
466L<perl-libextract> program that is part of the C<Perl::LibExtractor> 445L<perl-libextract> program that is part of the C<Perl::LibExtractor>
467distribution). 446distribution).
468 447
469Example: add the deliantra client program installed by the 448Example: add the deliantra client program installed by the
470L<Deliantra::Client> module. 449L<Deliantra::Client> module and put it under F<bin/deliantra>.
471 450
472 $extractor->add_script ("deliantra"); 451 $extractor->add_bin ("deliantra");
473 452
474=cut 453=cut
475 454
476sub add_script { 455sub add_bin {
477 my $self = shift; 456 my $self = shift;
478 457
479 exe: 458 exe:
480 for my $exe (@_) { 459 for my $exe (@_) {
481 for my $dir ($Config{sitebinexp}, $Config{vendorbinexp}, $Config{binexp}) { 460 for my $dir ($Config{sitebinexp}, $Config{vendorbinexp}, $Config{binexp}) {
482 if (open my $fh, "<:perlio", "$dir/$exe") { 461 if (open my $fh, "<:perlio", "$dir/$exe") {
483 462 if (-f $fh) {
484 my $file = do { local $/; readline $fh }; 463 my $file = do { local $/; readline $fh };
485 464
486 $self->_trace_flush if exists $self->{trace_check}; 465 $self->_trace_flush if exists $self->{trace_check};
487 $self->{trace_check} = $file; 466 $self->{trace_check} = $file;
488 467
489 $self->{set}{"$self->{bindir}/$exe"} = ["$dir/$exe"]; 468 $self->{set}{"bin/$exe"} = ["$dir/$exe"];
490 next exe; 469 next exe;
470 }
491 } 471 }
492 } 472 }
493 473
494 croak "add_script ($exe): executable not found"; 474 croak "add_bin ($exe): executable not found";
495 } 475 }
496} 476}
497 477
498=item $extractor->add_eval ($string) 478=item $extractor->add_eval ($string)
499 479
531=item $extractor->add_perl 511=item $extractor->add_perl
532 512
533Adds the perl binary itself to the file set, including the libperl dll, if 513Adds the perl binary itself to the file set, including the libperl dll, if
534needed. 514needed.
535 515
536For example, on UNIX systems, this usually adds a F<bin/perl> and possibly 516For example, on UNIX systems, this usually adds a F<exe/perl> and possibly
537some F<lib/libperl.so.XXX>. 517some F<dll/libperl.so.XXX>.
538 518
539=cut 519=cut
540 520
541sub add_perl { 521sub add_perl {
542 my ($self) = @_; 522 my ($self) = @_;
543 523
544 $self->{set}{"$self->{exedir}/perl$Config{_exe}"} = [_perl_path]; 524 $self->{set}{"exe/perl$Config{_exe}"} = [_perl_path];
545 525
546 # on debian, we have the special case of a perl binary linked against 526 # on debian, we have the special case of a perl binary linked against
547 # a static libperl.a (which is not available), but the Config says to use 527 # a static libperl.a (which is not available), but the Config says to use
548 # a shared library, which is in the wrong directory, too (which breaks 528 # a shared library, which is in the wrong directory, too (which breaks
549 # every other perl installation on the system - they are so stupid). 529 # every other perl installation on the system - they are so stupid).
564 } else { 544 } else {
565 $libperl = $Config{libperl}; 545 $libperl = $Config{libperl};
566 $libpath = $self->{lib}{"CORE/$libperl"}; 546 $libpath = $self->{lib}{"CORE/$libperl"};
567 } 547 }
568 548
569 $self->{set}{"$self->{dlldir}/$libperl"} = $libpath 549 $self->{set}{"dll/$libperl"} = $libpath
570 if length $libpath && -e $libpath; 550 if length $libpath && -e $libpath;
571 } 551 }
572} 552}
573 553
574=item $extractor->add_core_support 554=item $extractor->add_core_support
648 628
649 for (@{ 629 for (@{
650 $self->_read_packlist ($Config{privlibexp}, ".packlist") 630 $self->_read_packlist ($Config{privlibexp}, ".packlist")
651 }) { 631 }) {
652 $self->{set}{$_} ||= [ 632 $self->{set}{$_} ||= [
653 "$self->{libdir}/" 633 "lib/"
654 . ($lib->{$_} or croak "$_: unable to locate file in perl library") 634 . ($lib->{$_} or croak "$_: unable to locate file in perl library")
655 ]; 635 ];
656 } 636 }
657} 637}
658 638
672path inside the file set, almost the same as in the shell. For example, 652path inside the file set, almost the same as in the shell. For example,
673F</bin/perl*> would match all files whose names starting with F<perl> 653F</bin/perl*> would match all files whose names starting with F<perl>
674inside the F<bin> directory in the set. 654inside the F<bin> directory in the set.
675 655
676If the F</> is missing, then the pattern is interpreted as a module name 656If the F</> is missing, then the pattern is interpreted as a module name
677(a F<.pm> file). For example, F<Coro> matches the file F<libdir/Coro.pm> 657(a F<.pm> file). For example, F<Coro> matches the file F<lib/Coro.pm> ,
678(where F<libdir> is the perl library directory), while F<Coro::*> would 658while F<Coro::*> would match F<lib/Coro/*.pm>.
679match F<libdir/Coro/*.pm>.
680 659
681=item * 660=item *
682 661
683A single star matches anything inside a single directory component. For 662A single star matches anything inside a single directory component. For
684example, F</lib/Coro/*.pm> would match all F<.pm> files inside the 663example, F</lib/Coro/*.pm> would match all F<.pm> files inside the
704 s/\\\*/[^\/]*/g; 683 s/\\\*/[^\/]*/g;
705 s/\\\?/[^\/]/g; 684 s/\\\?/[^\/]/g;
706 685
707 unless (s%^\\/%%) { 686 unless (s%^\\/%%) {
708 s%\\:\\:%/%g; 687 s%\\:\\:%/%g;
709 $_ = (quotemeta $_[0]{libdir}) . "/$_\\.pm"; 688 $_ = "lib/$_\\.pm";
710 } 689 }
711 690
712 $_ .= '$'; 691 $_ .= '$';
713 s/(?: \[\^\/\] | \. ) \*\$$//x; # remove ** at end 692 s/(?: \[\^\/\] | \. ) \*\$$//x; # remove ** at end
714 693
756 735
757Any files not matched by any expression will simply stay in the set. 736Any files not matched by any expression will simply stay in the set.
758 737
759For example, to remove most of the useless autoload functions by the POSIX 738For example, to remove most of the useless autoload functions by the POSIX
760module (they either do the same thing as a builtin or always raise an 739module (they either do the same thing as a builtin or always raise an
761error), you would use this (assuming a default C<libdir>): 740error), you would use this:
762 741
763 $extractor->filter ("-/lib/auto/POSIX/*.al"); 742 $extractor->filter ("-/lib/auto/POSIX/*.al");
764 743
765This does not remove all autoload files, only the ones not defined by a 744This does not remove all autoload files, only the ones not defined by a
766subclass (e.g. it leaves C<POSIX::SigRt::xxx> alone). 745subclass (e.g. it leaves C<POSIX::SigRt::xxx> alone).
812 $self->_trace_flush; 791 $self->_trace_flush;
813 792
814 my $set = $self->{set}; 793 my $set = $self->{set};
815 794
816 # delete all static libraries, also windows stuff 795 # delete all static libraries, also windows stuff
817 delete @$set{ grep m%^\Q$self->{libdir}\E/auto/(?:.+/)?([^\/]+)/\1(?:\Q$Config{_a}\E|\.pdb|\.exp)$%s, keys %$set }; 796 delete @$set{ grep m%^lib/auto/(?:.+/)?([^\/]+)/\1(?:\Q$Config{_a}\E|\.pdb|\.exp)$%s, keys %$set };
818 797
819 # delete all extralibs.ld and extralibs.all (no clue what the latter is for) 798 # delete all extralibs.ld and extralibs.all (no clue what the latter is for)
820 delete @$set{ grep m%^\Q$self->{libdir}\E/auto/.*/extralibs\.(?:ld|all)$%s, keys %$set }; 799 delete @$set{ grep m%^lib/auto/.*/extralibs\.(?:ld|all)$%s, keys %$set };
821 800
822 # delete all .pod, .h, .html files (hopefully none of them are used at runtime) 801 # delete all .pod, .h, .html files (hopefully none of them are used at runtime)
823 delete @$set{ grep m%^\Q$self->{libdir}\E/.*\.(?:pod|h|html)$%s, keys %$set }; 802 delete @$set{ grep m%^lib/.*\.(?:pod|h|html)$%s, keys %$set };
824 803
825 # delete unneeded unicore files 804 # delete unneeded unicore files
826 delete @$set{ grep m%^\Q$self->{libdir}\E/unicore/(?:mktables(?:\.lst)?|.*\.txt)$%s, keys %$set }; 805 delete @$set{ grep m%^lib/unicore/(?:mktables(?:\.lst)?|.*\.txt)$%s, keys %$set };
827} 806}
828 807
829=back 808=back
830 809
831=head2 RESULT SET 810=head2 RESULT SET
879 858
880To package he deliantra client (L<Deliantra::Client>), finding all 859To package he deliantra client (L<Deliantra::Client>), finding all
881(perl) files needed to run it is a first step. This can be done by using 860(perl) files needed to run it is a first step. This can be done by using
882something like the following code snippet: 861something like the following code snippet:
883 862
884 my $ex = new Perl::LibExtractor 863 my $ex = new Perl::LibExtractor;
885 exedir => ".", dlldir => ".",
886 libdir => "pm", bindir => "pm/bin";
887 864
888 $ex->add_perl; 865 $ex->add_perl;
889 $ex->add_core_support; 866 $ex->add_core_support;
890 $ex->add_script ("deliantra"); 867 $ex->add_bin ("deliantra");
891 $ex->add_mod ("AnyEvent::Impl::EV"); 868 $ex->add_mod ("AnyEvent::Impl::EV");
892 $ex->add_mod ("AnyEvent::Impl::Perl"); 869 $ex->add_mod ("AnyEvent::Impl::Perl");
893 $ex->add_mod ("Urlader"); 870 $ex->add_mod ("Urlader");
894 $ex->filter ("-/*/auto/POSIX/**.al"); 871 $ex->filter ("-/*/auto/POSIX/**.al");
895 $ex->runtime_only; 872 $ex->runtime_only;
896 873
897Let's first find out about the choice of paths for the subset. The
898Deliantra client binary packages use L<Urlader> nowadays, and there it is
899convenient to have F<perl> and any shared libraries directly in the root
900of the distribution.
901
902The perl library files are put into a directory named F<pm>, simply
903because it's shorter than F<lib>, and in the future, some files might go
904into F<lib>.
905
906And finally, the F<deliantra> script itself is put into the perl library
907directory, because it is not run directly - the installed client uses the
908system fonts and other resources, while the binary package is supposed
909to use the files packaged with it. To achieve this, a wrapper script is
910created, called F<run>; which displays a splash screen and configures the
911environment. A simplified version of it could look like this:
912
913 @INC = ("pm", "."); # "." required by newer AutoLoader grrrr.
914 $ENV{PANGO_RC_FILE} = "pango.rc";
915 require "bin/deliantra";
916 exit 0;
917
918First it sets the perl library directory to F<pm> and F<.> (the latter 874First it sets the perl library directory to F<pm> and F<.> (the latter
919to work around some AutoLoader bugs), so perl uses only the perl library 875to work around some AutoLoader bugs), so perl uses only the perl library
920files that came with the binary package. 876files that came with the binary package.
921 877
922Then it sets some environment variable to override the system default 878Then it sets some environment variable to override the system default

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines