Hi,

Having read through the thread, my somewhat Windows specific view on this is 
that there is only one case where the current PAR implementation does not work.

That is where a shared library is loaded in a completely none standard manner 
for the operating system concerned.
This is the case with Gtk2, and to a lesser extend with Wx (you can alter Wx 
within Perl so that libs are loaded using current PAR implementation).

I don't recall any other genuine cases reported to this list, though there may 
be some.
For example, Image::Magick uses standard methods to load its dependencies so it 
is just a matter of packing the correct ones to 'shlib'.

In general, the only shared libraries that can have common names within a Perl 
process are the XS modules themselves. Dependent shared libraries - i.e. those 
linked to XS modules by standard dynamic linking, must have unique file names.

For the example
sys/libfoo.dll, glib/libfoo.dll, and a bork/libfoo.dll
in windows at least, in general, the first libfoo.dll your process attempts to 
load is the libfoo.dll you get.

Note that in Windows 'side by side' loading works from the perspective of DLLs 
too
e.g. If I have process perl.exe that loads
../auto/My/Module/Module.dll

and Module.dll has a dependency on ModuleExtra.dll, then if 
../auto/My/Module/ModuleExtra.dll exists, that will get loaded .
If later in my prog I do "loadlibrary('ModuleExtra.dll') then I will just get 
an increase in the ref count to ./auto/My/Module/ModuleExtra.dll.

So, the current implementation of mangling XS module library names and 
extracting dependent libs from shlib to the cache root works for everything 
except odd cases.

In the odd case of Gtk2, the only way to cope with its behaviour is to extract 
to a standard 'tree' (as pointed out earlier in thread).

We could change everything about PAR to cope with Gtk2, but if we do so, it 
might be a good idea to take a step back and think about wider alterations to 
current PAR.

Why not take recent work on Archive::Unzip::Burst and incorporate that in a 
reworked PAR - say PAR::Burst

PAR::Burst would then just extract everything to cache directory with no name 
mangling and a simple tree structure like

inc
shlib
script

'inc' gets added to @INC, shlib to library paths, script folder is added to 
'PATH' and perms mask is 0755.

End users can add whatever else thy like to zip structure.

Of course, this would mean that foo.par packed under PAR would be different to 
foo.par packed under PAR::Burst - so PAR::Burst would need a fallback method 
whereby after extraction, if we don't have 'PAR::Burst' structure, start again 
with PAR. This would make older .par files take slightly longer to load, but it 
would still work until all dependencies were converted to PAR::Burst


For PAR::Burst::Packer, the goal would be to incorporate the unzip code 
directly within the compiled executable, removing the need to load Perl at all 
until after the extract is complete.
In addition to increased speed, this would give us the huge advantage that when 
the initial executable stub has extracted the zip tree, we can then in the 
extracted second executable simply mangle the arguments and call
perl_parse on the path to the extracted script - removing any BEGIN, eval, do  -e 
wrapper. We would have to prepend a BEGIN block to the script to set up necessary PATHS / 
@INC but this would still make the script code that followed run exactly as if it have 
been called as "perl myscript.pl". A big win I think.

I would quite like to work on this if there is any agreement that any of it 
represents a reasonable idea.

Regards


Mark






Steffen Mueller wrote:

Hi Glenn, hi all,

Glenn Linderman schrieb:
Now if a library was not originally part of the <perl-install> tree, it is an open question where it should be installed... and maybe that is what you are referring to?

Unless I'm grossly mistaken, that's exactly what Scott is referring to.

So then in the PAR case we have <par-cache-for-this-app>/(lib|bin|script) and you are suggesting that anything that is included from other parts of the original file system should be placed in <par-cache-for-this-app>? I'd have suggested placing them in <par-cache-for-this-app>/script -- the script and any non-perl stuff should go there?

I don't see any reason to put non-perl stuff in script, to be honest. Maybe this is a Windows thing where people generally put dlls next to the executables in PATH?

My suggestion would be the following:
- For any Perl stuff, use the original paths and names.
- For shared libraries added with -l, use shlib/ORIGINALNAME or whatever that path's called. Add that to LD_LIBRARY_PATH and -- on Windows -- to PATH. - For data files added with -a, use the main cache directory and the original file name.

Now, what happens if filenames of external shared objects clash? There might be a sys/libfoo.so, a glib/libfoo.so, and a bork/libfoo.so required by the same program, as far as I know. (Is that right?)

We can't possibly recover those paths by looking at them unless we test against something like m|\blib/((?:[^/]+/)*[^/]+.so)$| on Linux and use $1 for extraction. But that's not going to work. And I digress...

So maybe -l should accept syntax similar to -a, except it places things under /shlib instead of / (i.e. -l/usr/lib/sys/foo;sys/foo).

Cheers,
Steffen



Reply via email to