Fri Oct 03 09:08:13 2014: Request 63939 was acted upon.
Transaction: Correspondence added by LAMPRECHT
       Queue: PAR-Packer
     Subject: The behaviour of "pp --link ..." is subtly different between OSX 
and Linux.
   Broken in: 1.008
    Severity: Normal
       Owner: Nobody
  Requestors: philk...@cpan.org
      Status: open
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=63939 >


The naming schema for shared libs on darwin is 

libname.x.x.x.dylib

The attached patch changes _find_shlib and _chase_lib to use the extension 
.dylib instead of of $Config{dlext} which has the value '.bundle' (there are 
different types of dynamically linked libs).
It also changes the regexes used to derive the correct name 'libname.x.dylib' 
from the forms  -l libname.dylib ; -l libname.x.x.x.dylib;  
/path/to/libname.dylib etc.
Files that are named .*\.bundle (these do not follow the version numbering 
schema of .dylib files)
can still be referenced by their full name.
I'm a pp user and not an expert concerning MacOSX. So anyone who could review 
would be welcome.

Cheers, Christoph
> 
> Looks like the heuristic in methods _find_shlib and _chase_lib 
> of PAR::Packer is wrong for OSX.  Sorry, I know next to nothing 
> about OSX - does it use ELF for objects and shared libraries?
> If so, what is the SONAME of X?
> 
> Can you run the following script with a single argument:
> the value of pp's --link option where the problem shows?
> 
> use PAR::Packer;
> my ($link) = @ARGV;
> my $pp = PAR::Packer->new;
> print $pp->_find_shlib($link, "foobar");
> 
> If it complains about "Environment variable LD_LIBRARY_PATH 
> does not exist", just set LD_LIBRARY_PATH to the built-in library
> search path (e.g. /lib:/usr/lib on Linux, Solaris).

diff --git a/lib/PAR/Packer.pm b/lib/PAR/Packer.pm
index 2017f6c..b85bc2c 100644
--- a/lib/PAR/Packer.pm
+++ b/lib/PAR/Packer.pm
@@ -1448,6 +1448,8 @@ sub _check_par {
 sub _chase_lib {
    my ($self, $file) = @_;
 
+   if ($^O eq q/darwin/){return _chase_lib_darwin(@_)} 
+
    while ($Config::Config{d_symlink} and -l $file) {
        if ($file =~ /^(.*?\.\Q$Config{dlext}\E\.\d+)\..*/) {
            return $1 if -e $1;
@@ -1470,6 +1472,35 @@ sub _chase_lib {
    return $file;
 }
 
+sub _chase_lib_darwin{
+   my ($self, $file) = @_;
+
+   while (-l $file) {
+       if ($file =~ /^(.*?\.\d+)(\.\d+)*\.dylib$/) {
+           my $name = $1 . q/.dylib/;
+           return $name if -e $name;
+       }
+
+       return $file if $file =~ /\D\.\d+\.dylib$/;
+
+       my $dir = File::Basename::dirname($file);
+       $file = readlink($file);
+
+       unless (File::Spec->file_name_is_absolute($file)) {
+           $file = File::Spec->rel2abs($file, $dir);
+       }
+   }
+
+   if ($file =~ /^(.*?\.\d+)(\.\d+)*\.dylib$/) {
+       my $name = $1 . q/.dylib/;
+       return $name if -e $name;
+   }
+
+   return $file;
+
+}
+
+
 sub _find_shlib {
     my ($self, $file, $script_name) = @_;
 
@@ -1497,14 +1528,14 @@ sub _find_shlib {
           . " does not exist.\n";
         return;
     }
-
+    my $dlext = ($^O eq 'darwin') ? 'dylib' : ($Config{dlext} // '');
     $file = File::Basename::basename($file);
     for my $dir (File::Basename::dirname($0),
         split(/\Q$Config{path_sep}\E/, $libpthname))
     {
         my $abs = File::Spec->catfile($dir, $file);
         return $self->_chase_lib($abs) if -e $abs;
-        $abs = File::Spec->catfile($dir, "$file.$Config{dlext}");
+        $abs = File::Spec->catfile($dir, "$file.$dlext");
         return $self->_chase_lib($abs) if -e $abs;
     }
 
utas-mbp:~ chris$ perl -MPAR::Packer -e 'print $PAR::Packer::VERSION'
1.022

utas-mbp:pptest chris$ cat > test.pl
print "PID: $$\n";
print "PAR_TEMP: ",$ENV{PAR_TEMP}, "\n";
use DBD::Pg;

system qq/lsof -p $$ | grep libpq /;
while( 1 ){sleep 5};



utas-mbp:pptest chris$ pp -o test -l 
/opt/local/lib/postgresql93/libpq.5.6.dylib test.pl
utas-mbp:pptest chris$ ./test
PID: 416
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-bd93cb56c5d7783d814fe8bbb37720f2c98d740a
test    416 chris  txt    REG                1,2    147476 1235950 
/opt/local/lib/postgresql93/libpq.5.6.dylib


# the packed executable still uses the systems lib
# the correct file is extracted in our cache-dir but the name is wrong
# so it won't get loaded (should be libpq.5.dylib): 

utas-mbp:~ chris$ ls 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-bd93cb56c5d7783d814fe8bbb37720f2c98d740a
 | grep libpq
libpq.5.6.dylib



# With Patched Packer.pm:
utas-mbp:pptest chris$ pp -o test -l libpq test.pl
Can't find libpq. Environment variable DYLD_LIBRARY_PATH does not exist.
utas-mbp:pptest chris$ export DYLD_LIBRARY_PATH=/opt/local/lib/postgresql93/
utas-mbp:pptest chris$ pp -o test -l libpq test.pl
utas-mbp:pptest chris$ ./test
PID: 371
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-dc89f0112a238b2b842d8d4f4e95baf2bd31ebb9
test    371 chris  txt    REG                1,1    147476 1502680 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-dc89f0112a238b2b842d8d4f4e95baf2bd31ebb9/libpq.5.dylib
^C
utas-mbp:pptest chris$ pp -o test -lpq test.pl
Unknown option: lpq
utas-mbp:pptest chris$ 
utas-mbp:pptest chris$ pp -o test -l pq test.pl
utas-mbp:pptest chris$ ./test
PID: 384
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-ebfb6618b3d0d3e9f0267d9f9ad8feda90a4b3a8
test    384 chris  txt    REG                1,1    147476 1503982 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-ebfb6618b3d0d3e9f0267d9f9ad8feda90a4b3a8/libpq.5.dylib
^C
utas-mbp:pptest chris$ pp -o test -l libpq.5.6.dylib test.pl
utas-mbp:pptest chris$ ./test
PID: 393
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-c419a78fda3a47f5d1133b65163b3eaa3539c823
test    393 chris  txt    REG                1,1    147476 1505279 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-c419a78fda3a47f5d1133b65163b3eaa3539c823/libpq.5.dylib
^C
utas-mbp:pptest chris$ pp -o test -l libpq.dylib test.pl
utas-mbp:pptest chris$ ./test
PID: 402
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-dbce9b62835facfe961713d5dbe13c03274d40d4
test    402 chris  txt    REG                1,1    147476 1506575 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-dbce9b62835facfe961713d5dbe13c03274d40d4/libpq.5.dylib
^C
utas-mbp:pptest chris$ pp -o test -l 
/opt/local/lib/postgresql93/libpq.5.6.dylib test.pl
utas-mbp:pptest chris$ ./test
PID: 411
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-15c3bd67b417a2e74de810a7fc03a50d7bb99b69
test    411 chris  txt    REG                1,1    147476 1507875 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-15c3bd67b417a2e74de810a7fc03a50d7bb99b69/libpq.5.dylib
^C
utas-mbp:pptest chris$ pp -o test -l /opt/local/lib/postgresql93/libpq.dylib 
test.pl
utas-mbp:pptest chris$ ./test
PID: 420
PAR_TEMP: 
/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T//par-6368726973/cache-53b72d8635b1ad3d625a281db44177d3b2571168
test    420 chris  txt    REG                1,1    147476 1509171 
/private/var/folders/52/p5_rmm7x2nx7t773fwkdyhj00000gp/T/par-6368726973/cache-53b72d8635b1ad3d625a281db44177d3b2571168/libpq.5.dylib
^C
utas-mbp:pptest chris$ 

Reply via email to