view release on metacpan or search on metacpan
print "\nWelcome to Alien::PNG module installation";
print "\n-----------------------------------------\n\n";
#### check what options we have for our platform
my $rv; my @candidates = ();
if(defined($ENV{PNG_INST_DIR})) {
print "Gonna use PNG_INST_DIR environment variable...\n";
print "(PNG_INST_DIR=$ENV{PNG_INST_DIR})\n";
if (-d $ENV{PNG_INST_DIR}) {
my @pnginst = File::Spec->splitdir($ENV{PNG_INST_DIR});
if($rv=check_config_script(File::Spec->catdir(@pnginst, 'bin', 'libpng-config'))) {
push @candidates, $rv;
}
elsif($rv=check_config_script(File::Spec->catdir(@pnginst, 'libpng-config'))) {
push @candidates, $rv;
}
}
else {
warn "###WARN### Non-existing directory '$ENV{PNG_INST_DIR}' - skipping";
}
}
if($rv=check_config_script("libpng-config")) {
push @candidates, $rv;
};
if ($rv = check_win32_pkgconfig()) {
push @candidates, $rv;
}
if($rv=check_prebuilt_binaries($build->os_type)) {
push @candidates, @{$rv};
};
Revision history for Perl module Alien::PNG
0.4 Tue Apr 21 2020
- use pkgconfig on Windows to use installed libpng [FROGGS]
0.2 Wed Apr 15 2020
- switch to function form of tempfile() [plicease]
0.1 Sun Apr 18 2010
- initial release [FROGGS]
NAME
Alien::PNG - building, finding and using PNG binaries
VERSION
Version 0.4
SYNOPSIS
Alien::PNG tries (in given order) during its installation:
* Locate an already installed PNG via 'libpng-config' script.
* Check for PNG libs in directory specified by PNG_INST_DIR variable.
In this case the module performs PNG library detection via
'$PNG_INST_DIR/bin/libpng-config' script.
* Download prebuilt PNG binaries (if available for your platform).
* Build PNG binaries from source codes (if possible on your system).
Later you can use Alien::PNG in your module that needs to link agains
PNG and/or related libraries like this:
# Sample Makefile.pl
use ExtUtils::MakeMaker;
* If you use prebuild binaries and/or binaries built from sources it
happens that some of the dynamic libraries (*.so, *.dll) will not
automaticly loadable as they will be stored somewhere under perl
module's 'share' directory. To handle this scenario Alien::PNG
offers some special functionality (see below).
METHODS
config()
This function is the main public interface to this module. Basic
functionality works in a very similar maner to 'libpng-config' script:
Alien::PNG->config('prefix'); # gives the same string as 'libpng-config --prefix'
Alien::PNG->config('version'); # gives the same string as 'libpng-config --version'
Alien::PNG->config('libs'); # gives the same string as 'libpng-config --libs'
Alien::PNG->config('cflags'); # gives the same string as 'libpng-config --cflags'
On top of that this function supports special parameters:
Alien::PNG->config('ld_shared_libs');
Returns a list of full paths to shared libraries (*.so, *.dll) that will
be required for running the resulting binaries you have linked with PNG
libs.
Alien::PNG->config('ld_paths');
linked with PNG libs.
Alien::PNG->config('ld_shlib_map');
Returns a reference to hash of value pairs '<libnick>' =>
'<full_path_to_shlib'>, where '<libnick>' is shortname for PNG related
library like: PNG.
NOTE: config('ld_<something>') return an empty list/hash if you have
decided to use PNG libraries already installed on your system. This
concerns 'libpng-config' detection and detection via
'$PNG_INST_DIR/bin/libpng-config'.
check_header()
This function checks the availability of given header(s) when using
compiler options provided by "Alien::PNG->config('cflags')".
Alien::PNG->check_header('png.h');
Alien::PNG->check_header('png.h', 'pngconf.h');
Returns 1 if all given headers are available, 0 otherwise.
get_header_version()
Tries to find a header file specified as a param in PNG prefix direcotry
and based on "#define" macros inside this header file tries to get a
version triplet.
Alien::PNG->get_header_version('png.h');
Returns string like '1.2.3' or undef if not able to find and parse
version info.
BUGS
Please post issues and bugs at
<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Alien-PNG>
AUTHOR
Tobias Leich
inc/My/Builder.pm view on Meta::CPAN
sub extract_binaries {
my ($self, $download, $build_out) = @_;
# do extract binaries
my $bp = $self->notes('build_params');
my $archive = catfile($download, File::Fetch->new(uri => $bp->{url})->file);
print "Extracting $archive...\n";
my $ae = Archive::Extract->new( archive => $archive );
die "###ERROR###: Cannot extract $archive ", $ae->error unless $ae->extract(to => $build_out);
# fix hardcoded prefix path in bin/libpng-config
my ($version, $prefix, $incdir, $libdir) = find_PNG_dir(rel2abs($build_out));
sed_inplace("$prefix/bin/libpng-config", 's/^prefix=.*/prefix=\''.quotemeta($prefix).'\'/');
}
sub extract_sources {
my ($self, $download, $patches, $build_src) = @_;
my $bp = $self->notes('build_params');
foreach my $pack (@{$bp->{members}}) {
my $srcdir = catfile($build_src, $pack->{dirname});
my $unpack = 'y';
$unpack = $self->prompt("Dir '$srcdir' exists, wanna replace with clean sources?", "n") if (-d $srcdir);
if (lc($unpack) eq 'y') {
inc/My/Builder.pm view on Meta::CPAN
# try to find PNG root dir
my ($version, $prefix, $incdir, $libdir) = find_PNG_dir(rel2abs($build_out));
die "###ERROR### Cannot find PNG directory in 'sharedir'" unless $version;
$self->config_data('share_subdir', abs2rel($prefix, rel2abs('sharedir')));
# set defaults
my $cfg = {
# defaults
version => $version,
prefix => '@PrEfIx@',
libs => '-L' . $self->get_path('@PrEfIx@/lib') . ' -lpng',
cflags => '-I' . $self->get_path('@PrEfIx@/include') . ' -D_GNU_SOURCE=1', # -Dmain=SDL_main
shared_libs => [ ],
};
# overwrite values available via libpng-config
my $bp = $self->config_data('build_prefix') || $prefix;
my $devnull = File::Spec->devnull();
my $script = rel2abs("$prefix/bin/libpng-config");
foreach my $p (qw(version prefix L_opts libs I_opts cflags)) {
my $o=`$script --$p 2>$devnull`;
if ($o) {
$o =~ s/[\r\n]*$//;
$o =~ s/\Q$prefix\E/\@PrEfIx\@/g;
$cfg->{$p} = $o;
if($p eq 'libs') {
$cfg->{$p} = $cfg->{L_opts} . ' ' . $cfg->{$p};
delete $cfg->{L_opts};
inc/My/Builder.pm view on Meta::CPAN
$_ =~ s/^\Q$prefix\E/\@PrEfIx\@/ foreach (@shlibs);
$cfg->{ld_shared_libs} = [ @shlibs ];
# set ld_paths and ld_shlib_map
my %tmp = ();
my %shlib_map = ();
foreach my $full (@shlibs) {
my ($v, $d, $f) = splitpath($full);
$tmp{ catpath($v, $d, '') } = 1;
# available shared libs detection
if ($f =~ /^(lib)?(png12)/) {
$shlib_map{png12} = $full unless $shlib_map{png12};
}
elsif ($f =~ /^(lib)?(tiff|jpeg|png)[^a-zA-Z]/) {
$shlib_map{$2} = $full unless $shlib_map{$2};
}
};
$cfg->{ld_paths} = [ keys %tmp ];
$cfg->{ld_shlib_map} = \%shlib_map;
# write config
$self->config_data('additional_cflags', '-I' . $self->get_path('@PrEfIx@/include') . ' ' .
$self->get_additional_cflags);
$self->config_data('additional_libs', $self->get_additional_libs);
inc/My/Utility.pm view on Meta::CPAN
use File::Find qw(find);
use File::Copy qw(cp);
use Cwd qw(realpath);
#### packs with prebuilt binaries
# - all regexps has to match: arch_re ~ $Config{archname}, cc_re ~ $Config{cc}, os_re ~ $^O
# - the order matters, we offer binaries to user in the same order (1st = preffered)
my $prebuilt_binaries = [
{
title => "Binaries Win/32bit PNG-1.2.40 (20100328) RECOMMENDED",
url => 'http://froggs.de/libpng/Win32_libpng-1.2.40_bin-20100328.zip',
sha1sum => 'f414f5c5d3cb8cafb4fec7f4bdf2ab4146da9630',
arch_re => qr/^MSWin32-x86-multi-thread$/,
os_re => qr/^MSWin32$/,
cc_re => qr/gcc/,
},
];
#### tarballs with source codes
my $source_packs = [
## the first set for source code build will be a default option
{
title => "Source code build: PNG-1.4.1",
members => [
# {
# pack => 'zlib',
# dirname => 'zlib-1.2.4',
# url => 'http://www.zlib.net/zlib-1.2.4.tar.gz',
# sha1sum => '22965d40e5ca402847f778d4d10ce4cba17459d1',
# },
{
pack => 'libpng',
dirname => 'libpng-1.4.1',
url => 'http://downloads.sourceforge.net/libpng/libpng-1.4.1.tar.gz',
sha1sum => '7a3488f5844068d67074f2507dd8a7ed9c69ff04',
},
],
},
];
sub check_config_script
{
my $script = shift || 'libpng-config';
print "Gonna check config script...\n";
print "(scriptname=$script)\n";
my $devnull = File::Spec->devnull();
my $cflags = `$script --cflags 2>$devnull`;
$cflags =~ s/^-I//;
$cflags =~ s/[\s\n\r]*$//;
my ($version) = find_PNG_dir($cflags);
return if($? >> 8);
my $prefix = `$script --prefix 2>$devnull`;
return if($? >> 8);
inc/My/Utility.pm view on Meta::CPAN
}
sub check_win32_pkgconfig
{
return unless $^O eq 'MSWin32';
my ($prefix) = map { s/\/perl\/lib$/\/c/; $_ } grep { /\/perl\/lib$/ } @INC;
return unless $prefix;
my $pcfiledir = "$prefix/lib/pkgconfig";
my $pkgconfig = "$pcfiledir/libpng.pc";
return unless -f $pkgconfig;
print "Gonna check win32 pkgconfig...\n";
print "(path=$pkgconfig)\n";
my $devnull = File::Spec->devnull();
my %pc_var = (
pcfiledir => $pcfiledir,
);
open(DAT, $pkgconfig) || return;
inc/My/Utility.pm view on Meta::CPAN
$pc_var{$name} = $value;
}
for my $name (keys %pc_var) {
$pc_var{$name} =~ s/^\Q$prefix\E/\@PrEfIx\@/;
}
return unless $pc_var{version};
# find and set ld_shared_libs
my @shlibs = find_file("$prefix/bin", qr/libpng(\d.*)\.dll$/);
$_ =~ s/^\Q$prefix\E/\@PrEfIx\@/ foreach @shlibs;
$pc_var{ld_shared_libs} = \@shlibs;
# set ld_paths and ld_shlib_map
my %tmp = ();
my %shlib_map = ();
foreach my $full (@shlibs) {
my ($v, $d, $f) = splitpath($full);
$tmp{ catpath($v, $d, '') } = 1;
# available shared libs detection
if ($f =~ /^(lib)?(png12)/) {
$shlib_map{png12} = $full unless $shlib_map{png12};
}
elsif ($f =~ /^(lib)?(tiff|jpeg|png)[^a-zA-Z]/) {
$shlib_map{$2} = $full unless $shlib_map{$2};
}
};
$pc_var{ld_paths} = [ keys %tmp ];
$pc_var{ld_shlib_map} = \%shlib_map;
return {
title => "Already installed PNG-$pc_var{version} path=$pkgconfig",
buildtype => 'use_win32_pkgconfig',
win32_pkgconfig => \%pc_var,
inc/My/Utility.pm view on Meta::CPAN
$re ||= qr/.*/;
find({ wanted => sub { push @files, rel2abs($_) if /$re/ }, follow => 1, no_chdir => 1 , follow_skip => 2}, $dir);
return @files;
}
sub find_PNG_dir {
my $root = shift;
my ($version, $prefix, $incdir, $libdir);
return unless $root;
# try to find png.h
my ($found) = find_file($root, qr/png\.h$/i ); # take just the first one
return unless $found;
# get version info
open(DAT, $found) || return;
my @raw=<DAT>;
close(DAT);
my ($v_maj) = grep(/^#define[ \t]+PNG_LIBPNG_VER_MAJOR[ \t]+[0-9]+/, @raw);
$v_maj =~ s/^#define[ \t]+PNG_LIBPNG_VER_MAJOR[ \t]+([0-9]+)[.\r\n]*$/$1/;
my ($v_min) = grep(/^#define[ \t]+PNG_LIBPNG_VER_MINOR[ \t]+[0-9]+/, @raw);
$v_min =~ s/^#define[ \t]+PNG_LIBPNG_VER_MINOR[ \t]+([0-9]+)[.\r\n]*$/$1/;
my ($v_pat) = grep(/^#define[ \t]+PNG_LIBPNG_VER_RELEASE[ \t]+[0-9]+/, @raw);
$v_pat =~ s/^#define[ \t]+PNG_LIBPNG_VER_RELEASE[ \t]+([0-9]+)[.\r\n]*$/$1/;
return if (($v_maj eq '')||($v_min eq '')||($v_pat eq ''));
$version = "$v_maj.$v_min.$v_pat";
# get prefix dir
my ($v, $d, $f) = splitpath($found);
my @pp = reverse splitdir($d);
shift(@pp) if(defined($pp[0]) && $pp[0] eq '');
shift(@pp) if(defined($pp[0]) && $pp[0] =~ /libpng\d+/);
if(defined($pp[0]) && $pp[0] eq 'include') {
shift(@pp);
@pp = reverse @pp;
return (
$version,
catpath($v, catdir(@pp), ''),
catpath($v, catdir(@pp, 'include'), ''),
catpath($v, catdir(@pp, 'lib'), ''),
);
}
lib/Alien/PNG.pm view on Meta::CPAN
our $VERSION = '0.4';
$VERSION = eval $VERSION;
=head1 SYNOPSIS
Alien::PNG tries (in given order) during its installation:
=over
=item * Locate an already installed PNG via 'libpng-config' script.
=item * Check for PNG libs in directory specified by PNG_INST_DIR variable.
In this case the module performs PNG library detection via
'$PNG_INST_DIR/bin/libpng-config' script.
=item * Download prebuilt PNG binaries (if available for your platform).
=item * Build PNG binaries from source codes (if possible on your system).
=back
Later you can use Alien::PNG in your module that needs to link agains PNG
and/or related libraries like this:
lib/Alien/PNG.pm view on Meta::CPAN
'share' directory. To handle this scenario Alien::PNG offers some special
functionality (see below).
=back
=head1 METHODS
=head2 config()
This function is the main public interface to this module. Basic
functionality works in a very similar maner to 'libpng-config' script:
Alien::PNG->config('prefix'); # gives the same string as 'libpng-config --prefix'
Alien::PNG->config('version'); # gives the same string as 'libpng-config --version'
Alien::PNG->config('libs'); # gives the same string as 'libpng-config --libs'
Alien::PNG->config('cflags'); # gives the same string as 'libpng-config --cflags'
On top of that this function supports special parameters:
Alien::PNG->config('ld_shared_libs');
Returns a list of full paths to shared libraries (*.so, *.dll) that will be
required for running the resulting binaries you have linked with PNG libs.
Alien::PNG->config('ld_paths');
Returns a list of full paths to directories with shared libraries (*.so, *.dll)
that will be required for running the resulting binaries you have linked with
PNG libs.
Alien::PNG->config('ld_shlib_map');
Returns a reference to hash of value pairs '<libnick>' => '<full_path_to_shlib'>,
where '<libnick>' is shortname for PNG related library like: PNG.
NOTE: config('ld_<something>') return an empty list/hash if you have decided to
use PNG libraries already installed on your system. This concerns 'libpng-config'
detection and detection via '$PNG_INST_DIR/bin/libpng-config'.
=head2 check_header()
This function checks the availability of given header(s) when using compiler
options provided by "Alien::PNG->config('cflags')".
Alien::PNG->check_header('png.h');
Alien::PNG->check_header('png.h', 'pngconf.h');
Returns 1 if all given headers are available, 0 otherwise.
=head2 get_header_version()
Tries to find a header file specified as a param in PNG prefix direcotry and
based on "#define" macros inside this header file tries to get a version triplet.
Alien::PNG->get_header_version('png.h');
Returns string like '1.2.3' or undef if not able to find and parse version info.
=head1 BUGS
Please post issues and bugs at L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Alien-PNG>
=head1 AUTHOR
Tobias Leich
lib/Alien/PNG.pm view on Meta::CPAN
The full text of the license can be found in the
LICENSE file included with this module.
=cut
### get config params
sub config
{
my $package = shift;
my @params = @_;
return _png_config_via_script(@params) if Alien::PNG::ConfigData->config('script');
return _png_config_via_win32_pkgconfig(@params) if Alien::PNG::ConfigData->config('win32_pkgconfig');
return _png_config_via_config_data(@params) if Alien::PNG::ConfigData->config('config');
}
### get version info from given header file
sub get_header_version {
my ($package, $header) = @_;
return unless $header;
# try to find header
my $root = Alien::PNG->config('prefix');
#warn 'Finding in '.$root.'/include';
lib/Alien/PNG.pm view on Meta::CPAN
unlink $obj;
return 1;
}
else {
print STDERR "###TEST FAILED### for: " . join(', ', @header) . "\n";
return 0;
}
}
### internal functions
sub _png_config_via_script
{
my $param = shift;
my @add_libs = @_;
my $devnull = File::Spec->devnull();
my $script = Alien::PNG::ConfigData->config('script');
return unless ($script && ($param =~ /[a-z0-9_]*/i));
my $val = `$script --$param 2>$devnull`;
$val =~ s/[\r\n]*$//;
if($param eq 'cflags') {
$val .= ' ' . Alien::PNG::ConfigData->config('additional_cflags');
}
elsif($param eq 'libs') {
$val .= ' ' . join(' ', @add_libs) if scalar @add_libs;
$val .= ' ' . Alien::PNG::ConfigData->config('additional_libs');
}
return $val;
}
sub _png_config_via_win32_pkgconfig
{
my $param = shift;
my @add_libs = @_;
my $devnull = File::Spec->devnull();
my $pkgconfig = Alien::PNG::ConfigData->config('win32_pkgconfig');
return unless ($pkgconfig && ($param =~ /[a-z0-9_]*/i));
my ($prefix) = grep { /\/perl\/lib$/ } @INC;
return unless $prefix;
$prefix =~ s/\/perl\/lib$/\/c/;
lib/Alien/PNG.pm view on Meta::CPAN
elsif (ref $pkgconfig->{$param} eq 'HASH') {
map { $pkgconfig->{$param}{$_} =~ s/\@PrEfIx\@/$prefix/g } keys %{$pkgconfig->{$param}};
}
else {
$pkgconfig->{$param} =~ s/\@PrEfIx\@/$prefix/g;
}
$pkgconfig->{$param};
}
sub _png_config_via_config_data
{
my $param = shift;
my @add_libs = @_;
my $share_dir = dist_dir('Alien-PNG');
my $subdir = Alien::PNG::ConfigData->config('share_subdir');
return unless $subdir;
my $real_prefix = catdir($share_dir, $subdir);
return unless ($param =~ /[a-z0-9_]*/i);
my $val = Alien::PNG::ConfigData->config('config')->{$param};
return unless $val;
t/001_load.t view on Meta::CPAN
# t/001_load.t - test module loading and basic functionality
use Test::More tests => 1;
BEGIN { use_ok( 'Alien::PNG' ); }
diag( "Testing Alien::PNG $Alien::PNG::VERSION, Perl $], $^X" );
diag( "Build type: " . (Alien::PNG::ConfigData->config('build_params')->{buildtype} || 'n.a.') );
diag( "Detected libpng-config script: " . (Alien::PNG::ConfigData->config('build_params')->{script} || 'n.a.') );
diag( "Build option used:\n\t" . (Alien::PNG::ConfigData->config('build_params')->{title} || 'n.a.') );
diag( "URL: " . (Alien::PNG::ConfigData->config('build_params')->{url} || 'n.a.') );
diag( "SHA1: " . (Alien::PNG::ConfigData->config('build_params')->{sha1sum} || 'n.a.') );
t/003_check_header.t view on Meta::CPAN
# t/003_check_headers.t - test check_header() functionality
use Test::More tests => 2;
use Alien::PNG;
diag("Testing basic headers png.h + pngconf.h");
is( Alien::PNG->check_header('png.h'), 1, "Testing availability of 'png.h'" );
is( Alien::PNG->check_header('png.h', 'pngconf.h'), 1, "Testing availability of 'png.h, pngconf.h'" );
t/004_get_header_version.t view on Meta::CPAN
# t/004_config.t
use Test::More tests => 1;
use Alien::PNG;
like( Alien::PNG->get_header_version('png.h'), qr/([0-9]+\.)*[0-9]+/, "Testing png.h" );
diag 'Core version: '.Alien::PNG->get_header_version('png.h');