[rt #74043] handle static linking of libpng with libz
authorTony Cook <tony@develop-help.com>
Sat, 28 Apr 2012 02:45:13 +0000 (12:45 +1000)
committerTony Cook <tony@develop-help.com>
Sat, 28 Apr 2012 02:45:13 +0000 (12:45 +1000)
Changes
PNG/Changes
PNG/Makefile.PL
lib/Imager/Probe.pm

diff --git a/Changes b/Changes
index c717b58..53feb27 100644 (file)
--- a/Changes
+++ b/Changes
@@ -35,6 +35,23 @@ Bug fixes:
    directories and insert that into the library flags.
    https://rt.cpan.org/Ticket/Display.html?id=75869
 
+ - Imager::Probe can now probe for libraries with dependent libraries,
+   common for static linking, eg. libpng requires libz.
+   https://rt.cpan.org/Ticket/Display.html?id=74043
+
+ - libpng 1.5 specific probes were looking for libpng 1.4 filenames.
+
+ - added alternative probe configurations that try to link libz, to
+   handle a statically linked libpng.
+   https://rt.cpan.org/Ticket/Display.html?id=74043
+
+ - if a probe includes testcode, Imager::Probe now checks that code as
+   part of the process of checking each configuration rather than as a
+   post test of the found configuration.  This allows alternate
+   configurations to be checked if a matching but non-working
+   configuration is found.
+   https://rt.cpan.org/Ticket/Display.html?id=74043
+
 Other changes:
 
  - when reading or writing images via callbacks, the default callbacks
@@ -47,6 +64,8 @@ Other changes:
 
  - improve logging for creation of callback I/O layers.
 
+ - a little more documentation for Imager::Probe.
+
 Imager 0.89 - 18 Mar 2012
 ===========
 
index 00283e6..eb9f02a 100644 (file)
@@ -1,3 +1,12 @@
+Imager-File-PNG 0.84
+====================
+
+ - libpng 1.5 specific probes were looking for libpng 1.4 filenames.
+
+ - added alternative probe configurations that try to link libz, to
+   handle a statically linked libpng.
+   https://rt.cpan.org/Ticket/Display.html?id=74043
+
 Imager-File-PNG 0.83
 ====================
 
index ec5cdb3..bc73596 100644 (file)
@@ -38,7 +38,7 @@ else {
   $opts{TYPEMAPS} = [ Imager::ExtUtils->typemap ];
 
   # Imager required configure through use
-  my @Imager_req = ( Imager => "0.86" );
+  my @Imager_req = ( Imager => "0.90" );
   if ($MM_ver >= 6.46) {
     $opts{META_MERGE} =
       {
@@ -68,6 +68,30 @@ else {
 
 require Imager::Probe;
 
+my @alts =
+  (
+   {
+    altname => "v1.5",
+    incsuffix => "libpng15",
+    libbase => "png15",
+   },
+   {
+    altname => "v1.4",
+    incsuffix => "libpng14",
+    libbase => "png14",
+   },
+   {
+    altname => "v1.2",
+    incsuffix => "libpng12",
+    libbase => "png12",
+   },
+   {
+    altname => "v1.0",
+    incsuffix => "libpng10",
+    libbase => "png10",
+   },
+  );
+
 my %probe =
   (
    name => "PNG",
@@ -81,26 +105,18 @@ my %probe =
    libpath => \@libpaths,
    alternatives =>
    [
+    @alts,
     {
-     altname => "v1.5",
-     incsuffix => "libpng14",
-     libbase => "png14",
-    },
-    {
-     altname => "v1.4",
-     incsuffix => "libpng14",
-     libbase => "png14",
-    },
-    {
-     altname => "v1.2",
-     incsuffix => "libpng12",
-     libbase => "png12",
-    },
-    {
-     altname => "v1.0",
-     incsuffix => "libpng10",
-     libbase => "png10",
+     altname => "base (+libz)",
+     libbase => [ "png", "z" ],
     },
+    ( # a static libpng may require libz too
+     map +{
+          %$_,
+          altname => "$_->{altname} (+libz)",
+          libbase => [ $_->{libbase}, "z" ],
+         }, @alts
+    ),
    ],
   );
 
index 228c67c..6d05d36 100644 (file)
@@ -23,6 +23,11 @@ sub probe {
     $req->{altname} ||= "main";
     $result = _probe_check($req);
   }
+
+  if ($result && $req->{testcode}) {
+    $result = _probe_test($req, $result);
+  }
+
   if (!$result && $req->{alternatives}) {
   ALTCHECK:
     my $index = 1;
@@ -34,18 +39,24 @@ sub probe {
       for my $key (@alt_transfer) {
        exists $alt->{$key} and $work{$key} = $alt->{$key};
       }
-      $result = _probe_check(\%work)
+      $result = _probe_check(\%work);
+
+      if ($result && $req->{testcode}) {
+       $result = _probe_test(\%work, $result);
+      }
+
+      $result
        and last;
+
       ++$index;
     }
   }
 
   if (!$result && $req->{testcode}) {
     $result = _probe_fake($req);
-  }
-  $result or return;
 
-  if ($req->{testcode}) {
+    $result or return;
+
     $result = _probe_test($req, $result);
   }
 
@@ -186,29 +197,48 @@ sub _quotearg {
 sub _probe_check {
   my ($req) = @_;
 
-  my $libcheck = $req->{libcheck};
-  my $libbase = $req->{libbase};
-  if (!$libcheck && $req->{libbase}) {
-    # synthesize a libcheck
+  my @libcheck;
+  my @libbase;
+  if ($req->{libcheck}) {
+    if (ref $req->{libcheck} eq "ARRAY") {
+      push @libcheck, @{$req->{libcheck}};
+    }
+    else {
+      push @libcheck, $req->{libcheck};
+    }
+  }
+  elsif ($req->{libbase}) {
+    @libbase = ref $req->{libbase} ? @{$req->{libbase}} : $req->{libbase};
+
     my $lext=$Config{'so'};   # Get extensions of libraries
     my $aext=$Config{'_a'};
-    my $basename = _lib_basename($libbase);
-    $libcheck = sub {
-      -e File::Spec->catfile($_[0], "$basename$aext")
-       || -e File::Spec->catfile($_[0], "$basename.$lext")
-      };
+
+    for my $libbase (@libbase) {
+      my $basename = _lib_basename($libbase);
+      push @libcheck, sub {
+       -e File::Spec->catfile($_[0], "$basename$aext")
+         || -e File::Spec->catfile($_[0], "$basename.$lext")
+       };
+    }
+  }
+  else {
+    print "$req->{name}: No libcheck or libbase, nothing to search for\n"
+      if $req->{verbose};
+    return;
   }
 
-  my $found_libpath;
+  my @found_libpath;
   my @lib_search = _lib_paths($req);
   print "$req->{name}: Searching directories for libraries:\n"
     if $req->{verbose};
-  for my $path (@lib_search) {
-    print "$req->{name}:   $path\n" if $req->{verbose};
-    if ($libcheck->($path)) {
-      print "$req->{name}: Found!\n" if $req->{verbose};
-      $found_libpath = $path;
-      last;
+  for my $libcheck (@libcheck) {
+    for my $path (@lib_search) {
+      print "$req->{name}:   $path\n" if $req->{verbose};
+      if ($libcheck->($path)) {
+       print "$req->{name}: Found!\n" if $req->{verbose};
+        push @found_libpath, $path;
+       last;
+      }
     }
   }
 
@@ -231,17 +261,17 @@ sub _probe_check {
     $alt = " $req->{altname}:";
   }
   print "$req->{name}:$alt includes ", $found_incpath ? "" : "not ",
-    "found - libraries ", $found_libpath ? "" : "not ", "found\n";
+    "found - libraries ", @found_libpath == @libcheck ? "" : "not ", "found\n";
 
-  $found_libpath && $found_incpath
+  @found_libpath == @libcheck && $found_incpath
     or return;
 
-  my @libs = "-L$found_libpath";
+  my @libs = map "-L$_", @found_libpath;
   if ($req->{libopts}) {
     push @libs, $req->{libopts};
   }
-  elsif ($libbase) {
-    push @libs, _lib_option($libbase);
+  elsif (@libbase) {
+    push @libs, map _lib_option($_), @libbase;
   }
   else {
     die "$req->{altname}: inccheck but no libbase or libopts";
@@ -535,14 +565,19 @@ directory contains the required header files.
 C<libcheck> - a code reference that checks if the supplied library
 directory contains the required library files.  Note: the
 F<Makefile.PL> version of this was supplied all of the library file
-names instead.
+names instead.  C<libcheck> can also be an arrayref of library check
+code references, all of which must find a match for the library to be
+considered "found".
 
 =item *
 
 C<libbase> - if C<inccheck> is supplied, but C<libcheck> isn't, then a
 C<libcheck> that checks for C<lib>I<libbase>I<$Config{_a}> and
 C<lib>I<libbase>.I<$Config{so}> is created.  If C<libopts> isn't
-supplied then that can be synthesized as C<-l>C<<I<libbase>>>.
+supplied then that can be synthesized as C<< -lI<libbase>
+>>. C<libbase> can also be an arrayref of library base names to search
+for, in which case all of the libraries mentioned must be found for
+the probe to succeed.
 
 =item *
 
@@ -574,6 +609,14 @@ directories to check, or a reference to an array of such.
 C<libpath> - C<$Config{path_sep}> separated list of library file
 directories to check, or a reference to an array of such.
 
+=item *
+
+C<alternatives> - an optional array reference of alternate
+configurations (as hash referencesd) to test if the primary
+configuration isn't successful.  Each alternative should include an
+C<altname> key describing the alternative.  Any key not mentioned in
+an alternative defaults to the value from the main configuration.
+
 =back
 
 =cut