On Wed, Feb 26, 2003 at 06:11:48PM +0100, Markus Jansen wrote: > Hi Autrijus,
(Cc'ing the list for more insight.)
Thanks so much on detailed study on this matter. I see that I'm
really ignorant here, being a Win32 user for far too long. :-)
> packing everything but the kitchen sink (aka libc etc.) is definitely
> not my intention. But I think the $Config{lddlflags} is definitely made
> to cater for shared libraries which are available for more than one module -
> usually that stuff is separately installed before you install any
> depending modules from CPAN.
True. I must have been confused by the standard ActivePerl/Win32
behaviour, which is to install any shared libraries inside the auto/
path -- so for example, the PPM of DB_File and BerkeleyDB will contain
a libdb40.dll _each_, instead of sharing it somehow.
If I remember correctly, PerlApp's solution is to ask user to explicitly
include any shared libraries outside the auto/ path, and extract those
libraries verbatim to somewhere equivalent of LD_LIBRARY_PATH. It's
been ages since I last used it though, so I hope somebody more versed
in PerlApp could comment.
> A prominent series of examples is the LibXML:: modules.
> I guess that quite some of of them use the same library (e.g. libxml2.so),
> which are installed only once of course.
> The "native" path to those libraries is then compiled into the libraries -
> the only way to get this information I know is via ldd, but ldd tells
> this only if the path is really found.
Hmm? I thought the libraries only contain the shared object name, not
the "native path" as you call it. To wit:
psh$ ldd /usr/local/lib/perl5/5.8.0/i386-freebsd/auto/DB_File/DB_File.so
/usr/local/lib/perl5/5.8.0/i386-freebsd/auto/DB_File/DB_File.so:
libdb4.so.0 => /usr/local/lib/libdb4.so.0 (0x28144000)
psh$ $ENV{LD_LIBRARY_PATH} = "/tmp:/usr/local/lib"
psh$ cp /usr/local/lib/libdb4.so.0 /tmp/
psh$ ldd /usr/local/lib/perl5/5.8.0/i386-freebsd/auto/DB_File/DB_File.so
/usr/local/lib/perl5/5.8.0/i386-freebsd/auto/DB_File/DB_File.so:
libdb4.so.0 => /tmp/libdb4.so.0 (0x28144000)
So as long as it's somewhere in LD_LIBRARY_PATH, the path does not
matter.
> This is the reason why just copying the file into the PAR archive and even
> some pre-bootstrap unpacking into /tmp will not help at all.
>
> I. We need to identify the additional libraries we want to pack.
> I have found 2 alternatives:
>
> I.1. record the dependencies using e.g. ldd
>
> I.2. create symbolic links from the auto/... directory to those
> libraries contained in the $Config{lddlflags} directories,
> or simply copy them.
>
> However, this would introduce a "Perl module post-installation" step
> for PAR only.
I.1. is clearly the way to go, only that we need to determine it portably.
(and what about second- or third- level of dependency? can we safely
ignore them?)
> II. At present (having thought and read another day on this topic),
> I see 3 ways of implementing the load part:
>
> II. 1. store them in the PAR bag with special dependency and order information,
> and silently load them in the proper order before passing to
> DynaLoader::bootstrap
I'm not exactly sure how to load them before DynaLoader::bootstrap in
the Perl land. Does it needs C-level myldr magic (which will be
incovenient), or is there a simpler way for that?
> II. 2. An alternative to loading the libs before the bootstrap would be to
> set the LD_LIBRARY_PATH to an unpack directory, where they get their
> original file name.
Indeed, that's what I wanted.
> I have tried hard to do this from inside Perl (set LD_LIBRARY_PATH,
> pushing the library to @DynaLoader::dl_resolve_using, or pushing
> the new path to @DynaLoader::dl_library_path) - all of this does not
> help, but setting LD_LIBRARY_PATH before starting the Perl
> program of course helps :-(.
> I guess that augmenting LD_LIBRARY_PATH and calling ourself again
> is not something we really want ...
It can be less drastic than that. :-)
A quick experiment with myldr/main.c shows that setting it before
creating the perl interpreter does help:
--- myldr/main.c.orig Thu Feb 27 10:06:01 2003
+++ myldr/main.c Thu Feb 27 10:06:02 2003
@@ -59,6 +59,8 @@ int main( int argc, char **argv, char **
GV* tmpgv;
int options_count;
+ setenv("LD_LIBRARY_PATH", "/tmp", 1);
+
#if defined(USE_ITHREADS)
/* XXX Ideally, this should really be happening in perl_alloc() or
* perl_construct() to keep libperl.a transparently fork()-safe.
So instead of using File::Temp to determine the temporary directory,
we can predetermine it at C-level, augment LD_LIBRARY_PATH to include
it, and have the Perl-level code just look at the new
$ENV{LD_LIBRARY_PATH} as the temporary directory to write shared objects
(and potentially other files?) into.
Does it sound like a clean solution to you?
> II. 3. A third, hypothetical, ugly way would be to change the zero terminated
> paths in the Module's main shared library to the (necessarily shorter)
> PAR extraction path.
> Extraction of the additional libs would also require their original
> names, unless we change them, too (here we will have a real length
> problem ...).
Ugh. Let's not go there.
> For me, I.1. and II.1. still mark the proper ways to go ;-(
I'd welcome II.1 instead of II.2 if the 'silently load' bits is
explained better. :-)
Thanks,
/Autrijus/
pgp00000.pgp
Description: PGP signature
