X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/faa9b3e727c7c57aa07598dc0ba2ada24eb3f9a8..7e7508dd748ff85aa295b729c2e34f5bc089692f:/Makefile.PL?ds=sidebyside diff --git a/Makefile.PL b/Makefile.PL index 6318d461..56b0852f 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,10 +1,13 @@ - +#!perl -w +use strict; use ExtUtils::MakeMaker; use Cwd; use Config; - -$lext=$Config{'so'}; # Get extensions of libraries -$aext=$Config{'_a'}; +use File::Spec; +use Getopt::Long; +use vars qw(%Recommends); +use ExtUtils::Manifest qw(maniread); +use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS); # # IM_INCPATH colon seperated list of paths to extra include paths @@ -21,79 +24,223 @@ $aext=$Config{'_a'}; # IM_CFLAGS Extra flags to pass to the compiler # IM_LFLAGS Extra flags to pass to the linker # IM_DFLAGS Extra flags to pass to the preprocessor - +# IM_SUPPRESS_PROMPT Suppress the prompt asking about gif support getenv(); # get environment variables + +my $lext=$Config{'so'}; # Get extensions of libraries +my $aext=$Config{'_a'}; + +my $help; # display help if set +my @enable; # list of drivers to enable +my @disable; # or list of drivers to disable +my @incpaths; # places to look for headers +my @libpaths; # places to look for libraries +my $noexif; # non-zero to disable EXIF parsing of JPEGs +my $no_gif_set_version; # disable calling EGifSetGifVersion +my $coverage; # build for coverage testing +GetOptions("help" => \$help, + "enable=s" => \@enable, + "disable=s" => \@disable, + "incpath=s", \@incpaths, + "libpath=s" => \@libpaths, + "verbose|v" => \$VERBOSE, + "nolog" => \$NOLOG, + "noexif" => \$noexif, + "nogifsetversion" => \$no_gif_set_version, + 'coverage' => \$coverage); + +if ($VERBOSE) { + print "Verbose mode\n"; + require Data::Dumper; + import Data::Dumper qw(Dumper); +} + +if ($help) { + usage(); +} + +my @defines; + +if ($NOLOG) { print "Logging not compiled into module\n"; } +else { + push @defines, [ IMAGER_LOG => 1, "Logging system" ]; +} + +if ($DEBUG_MALLOC) { + push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ]; + print "Malloc debugging enabled\n"; +} + +if (@enable && @disable) { + print STDERR "Only --enable or --disable can be used, not both, try --help\n"; + exit 1; +} + +my %definc; +my %deflib; +my @incs; # all the places to look for headers +my @libs; # all the places to look for libraries + init(); # initialize global data pathcheck(); # Check if directories exist +if (exists $ENV{IM_ENABLE}) { + my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE}; + for my $key (keys %formats) { + delete $formats{$key} unless $en{$key}; + } +} +if (@enable) { + my %en = map { $_ => 1 } map { split /,/ } @enable; + for my $key (keys %formats) { + delete $formats{$key} unless $en{$key}; + } +} +elsif (@disable) { + delete @formats{map { split /,/ } @disable}; +} + # Pick what libraries are used if ($MANUAL) { manual(); } else { automatic(); - if (exists $ENV{IM_ENABLE}) { - my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE}; - for my $key (keys %formats) { - delete $formats{$key} unless $en{$key}; - } - } } # Make sure there isn't a clash between the gif libraries. gifcheck(); -for $frm(values %formats) { - $F_DEFINE .= ' -D'.$frm->{def}; - $F_LIBS .= ' ' .$frm->{libfiles}; +my $lib_cflags = ''; +my $lib_lflags = ''; +my $F_LIBS = ''; +my $F_OBJECT = ''; +for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) { + my $frm = $formats{$frmkey}; + push @defines, [ $frm->{def}, 1, "$frmkey available" ]; $F_OBJECT .= ' ' .$frm->{objfiles}; + if ($frm->{cflags}) { + $lib_cflags .= ' ' .$frm->{cflags}; + ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () } + grep /^-I./, split ' ', $frm->{cflags}; + } + if ($frm->{lflags}) { + $lib_lflags .= ' ' . $frm->{lflags}; + } + else { + $F_LIBS .= ' ' .$frm->{libfiles}; + } + +} + +unless ($noexif) { + print "EXIF support enabled\n"; + push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ]; + $F_OBJECT .= ' imexif.o'; } -$F_INC = join(" ",map { (exists $definc{$_})?'':'-I'.$_ } @incs); -$F_LIBS = join(" ",map { '-L'.$_ } @libs).' '.$F_LIBS; +my $F_INC = join ' ', map "-I$_", map / / ? qq{"$_"} : $_, + grep !$definc{$_}, @incs; +$F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_, + grep !$deflib{$_}++, @libs) . $F_LIBS; -$OSLIBS = ''; -$OSDEF = "-DOS_$^O"; +my $OSLIBS = ''; +my $OSDEF = "-DOS_$^O"; if ($^O eq 'hpux') { $OSLIBS .= ' -ldld'; } if (defined $Config{'d_dlsymun'}) { $OSDEF .= ' -DDLSYMUN'; } -@objs = qw(Imager.o draw.o image.o io.o iolayer.o log.o - gaussian.o conv.o pnm.o raw.o feat.o font.o - filters.o dynaload.o stackmach.o datatypes.o - regmach.o trans2.o quant.o error.o convert.o - map.o tags.o palimg.o maskimg.o img16.o rotate.o); - -%opts=( - 'NAME' => 'Imager', - 'VERSION_FROM' => 'Imager.pm', - 'LIBS' => "$LFLAGS -lm $OSLIBS $F_LIBS", - 'DEFINE' => "$F_DEFINE $EXTDEF $OSDEF $CFLAGS", - 'INC' => "$DFLAGS $F_INC", - 'OBJECT' => join(' ', @objs, $F_OBJECT), - clean => { FILES=>'testout' }, - ); - -if ($] ge '5.005') { - $opts{AUTHOR} = 'Arnar M. Hrafnkelsson, addi@umich.edu'; +my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o + log.o gaussian.o conv.o pnm.o raw.o feat.o font.o + filters.o dynaload.o stackmach.o datatypes.o + regmach.o trans2.o quant.o error.o convert.o + map.o tags.o palimg.o maskimg.o img16.o rotate.o + bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o + imext.o scale.o rubthru.o render.o); + +$Recommends{Imager} = + { 'Parse::RecDescent' => 0 }; + +my %opts=( + 'NAME' => 'Imager', + 'VERSION_FROM' => 'Imager.pm', + 'LIBS' => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS", + 'DEFINE' => "$OSDEF $CFLAGS", + 'INC' => "$lib_cflags $DFLAGS $F_INC", + 'OBJECT' => join(' ', @objs, $F_OBJECT), + clean => { FILES=>'testout meta.tmp rubthru.c scale.c' }, + PM => gen_PM(), + PREREQ_PM => { 'Test::More' => 0.47 }, + ); + +if ($coverage) { + if ($Config{gccversion}) { + push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs'; + #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' }; + } + else { + die "Don't know the coverage C flags for your compiler\n"; + } +} + +# eval to prevent warnings about versions with _ in them +my $MM_ver = eval $ExtUtils::MakeMaker::VERSION; +if ($MM_ver > 6.06) { + $opts{AUTHOR} = 'Tony Cook , Arnar M. Hrafnkelsson'; $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images'; } +if ($MM_ver > 6.10) { + $opts{NO_META} = 1; +} + +make_imconfig(\@defines); if ($VERBOSE) { print Dumper(\%opts); } mkdir('testout',0777); # since we cannot include it in the archive. + +make_metafile(\%opts); + WriteMakefile(%opts); exit; sub MY::postamble { + my $self = shift; + my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)'; + my $mani = maniread; + + my @ims = grep /\.im$/, keys %$mani; ' dyntest.$(MYEXTLIB) : dynfilt/Makefile cd dynfilt && $(MAKE) $(PASTHRU) lib/Imager/Regops.pm : regmach.h regops.perl $(PERL) regops.perl regmach.h lib/Imager/Regops.pm -'; + +imconfig.h : Makefile.PL + $(ECHO) "imconfig.h out-of-date with respect to $?" + $(PERLRUN) Makefile.PL + $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <==" +'.qq! +lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl + $perl apidocs.perl lib/Imager/APIRef.pod + +!.join('', map _im_rule($perl, $_), @ims) + +} + +sub _im_rule { + my ($perl, $im) = @_; + + (my $c = $im) =~ s/\.im$/.c/; + return <; # eat one return - for $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) { + for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) { SWX: if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; } print "Enable $frm support: "; - $gz = ; + my $gz = ; chomp($gz); if ($gz =~ m/^(y|yes|n|no)/i) { $gz=substr(lc($gz),0,1); @@ -128,7 +275,8 @@ EOF # automatic configuration of helper libraries sub automatic { - for $frm(keys %formats) { + print "Automatic probing:\n" if $VERBOSE; + for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) { delete $formats{$frm} if !checkformat($frm); } } @@ -140,26 +288,6 @@ sub gifcheck { delete $formats{'ungif'}; } - RETR: - if ($formats{'gif'} or $formats{'ungif'}) { - print <; - chomp($resp); - if ($resp ne "n") { - delete $formats{'gif'}; - delete $formats{'ungif'}; - return; - } - } - for my $frm (qw(gif ungif)) { checkformat($frm) if ($MANUAL and $formats{$frm}); } @@ -186,12 +314,15 @@ EOFF # we need the version in a #ifdefable form - $F_DEFINE .= "-DIM_GIFMAJOR=$major -DIM_GIFMINOR=$minor"; + push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ]; + push @defines, [ IM_GIFMINOR => $minor ]; + push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ] + if $no_gif_set_version; } -sub gd { - my($path,$chk)=@_; +sub grep_directory { + my($path, $chk)=@_; # print "checking path $path\n"; if ( !opendir(DH,$path) ) { @@ -207,41 +338,60 @@ sub gd { sub checkformat { my $frm=shift; - my $libchk=$formats{$frm}{'libcheck'}; - my $incchk=$formats{$frm}{'inccheck'}; - my @l; - for my $lp (@libs) { - push(@l, gd($lp,$libchk)); + print " checkformat($frm)\n" if $VERBOSE; + + my $probe_array = $formats{$frm}{'code'}; + if ($probe_array) { + print " Calling probe function\n" if $VERBOSE; + if (ref $probe_array ne 'ARRAY') { + $probe_array = [ $probe_array ]; + } + for my $func (@$probe_array) { + return 1 if $func->($formats{$frm}, $frm); + } } - my @i; - for my $ip (@incs) { - push(@i, gd($ip,$incchk)); + my $lib_check=$formats{$frm}{'libcheck'}; + my $inc_check=$formats{$frm}{'inccheck'}; + + if ($lib_check) { + my @l; + for my $lp (@libs) { + push(@l, grep_directory($lp,$lib_check)); + } + + my @i; + for my $ip (@incs) { + push(@i, $ip) if $inc_check->($ip,$frm); + } + + printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found')); + $formats{$frm}{incdir} = \@i; + $formats{$frm}{libdir} = \@l; + return 1 if scalar(@i && @l); + } + else { + printf("%10s: not available\n", $frm); } - printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found')); - $formats{$frm}{incdir} = \@i; - $formats{$frm}{libdir} = \@l; - return scalar(@i && @l); + return 0; } - - sub pathcheck { if ($VERBOSE) { print "pathcheck\n"; print " Include paths:\n"; for (@incs) { print $_,"\n"; } } - @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed."),0) } @incs; + @incs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs; if ($VERBOSE) { print "\nLibrary paths:\n"; - for (@incs) { print $_,"\n"; } + for (@libs) { print $_,"\n"; } } - @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed."),0) } @libs; + @libs=grep { -d $_ && -r _ && -x _ or ( print(" $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs; print "\ndone.\n"; } @@ -260,22 +410,63 @@ sub pathcheck { sub init { - @definc{'/usr/include'}=(); - @incs=(qw(/usr/include /usr/local/include /usr/include/freetype /usr/local/include/freetype /usr/include/freetype2 /usr/local/include/freetype2), split /:/, $INCPATH ); - @libs=(split(/ /, $Config{'libpth'}), split(/:/, $LIBPATH) ); + my @definc = qw(/usr/include); + @definc{@definc}=(1) x @definc; + @incs=(split(/\Q$Config{path_sep}/, $INCPATH), + map { split /\Q$Config{path_sep}/} @incpaths ); + if ($Config{locincpth}) { + push @incs, grep -d, split ' ', $Config{locincpth}; + } if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) { push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE}; + } + if ($Config{incpath}) { + push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath}; + } + push @incs, grep -d, + qw(/sw/include + /usr/include/freetype2 + /usr/local/include/freetype2 + /usr/local/include/freetype1/freetype + /usr/include /usr/local/include /usr/include/freetype + /usr/local/include/freetype); + if ($Config{ccflags}) { + my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags}; + push @incs, @hidden; + @definc{@hidden} = (1) x @hidden; + } + + @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH), + map { split /\Q$Config{path_sep}/} @libpaths ); + if ($Config{loclibpth}) { + push @libs, grep -d, split ' ', $Config{loclibpth}; + } + + push @libs, grep -d, qw(/sw/lib), split(/ /, $Config{'libpth'}); + push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath}; + if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) { push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB}; } if ($^O eq 'cygwin') { push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api'; - push(@incs, '/usr/include/w32api') if -d '/usr/lib/w32api'; + push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api'; + } + if ($Config{ldflags}) { + # some builds of perl put -Ldir into ldflags without putting it in + # loclibpth, let's extract them + my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () } + split ' ', $Config{ldflags}; + push @libs, @hidden; + # don't mark them as seen - EU::MM will remove any libraries + # it can't find and it doesn't look for -L in ldflags + #@deflib{@hidden} = @hidden; } + push @libs, grep -d, qw(/usr/local/lib); $formats{'jpeg'}={ order=>'21', def=>'HAVE_LIBJPEG', - inccheck=>sub { $_[0] eq 'jpeglib.h' }, + inccheck=>sub { -e catfile($_[0], 'jpeglib.h') }, libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" }, libfiles=>'-ljpeg', objfiles=>'jpeg.o', @@ -287,7 +478,7 @@ sub init { $formats{'tiff'}={ order=>'23', def=>'HAVE_LIBTIFF', - inccheck=>sub { $_[0] eq 'tiffio.h' }, + inccheck=>sub { -e catfile($_[0], 'tiffio.h') }, libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" }, libfiles=>'-ltiff', objfiles=>'tiff.o', @@ -299,20 +490,21 @@ sub init { $formats{'png'}={ order=>'22', def=>'HAVE_LIBPNG', - inccheck=>sub { $_[0] eq 'png.h' }, + inccheck=>sub { -e catfile($_[0], 'png.h') }, libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" }, - libfiles=>'-lpng -lz', + libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz', objfiles=>'png.o', docs=>q{ Png stands for Portable Network Graphics and is intended as a replacement for gif on the web. It is patent free and - is recommended by the w3c, you need libpng to use these formats} + is recommended by the w3c, you need libpng to use these formats}, + code => \&png_probe, }; $formats{'gif'}={ order=>'20', def=>'HAVE_LIBGIF', - inccheck=>sub { $_[0] eq 'gif_lib.h' }, + inccheck=>sub { -e catfile($_[0], 'gif_lib.h') }, libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" }, libfiles=>'-lgif', objfiles=>'gif.o', @@ -327,7 +519,7 @@ sub init { $formats{'ungif'}={ order=>'21', def=>'HAVE_LIBGIF', - inccheck=>sub { $_[0] eq 'gif_lib.h' }, + inccheck=>sub { -e catfile($_[0], 'gif_lib.h') }, libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" }, libfiles=>'-lungif', objfiles=>'gif.o', @@ -341,7 +533,7 @@ sub init { $formats{'T1-fonts'}={ order=>'30', def=>'HAVE_LIBT1', - inccheck=>sub { $_[0] eq 't1lib.h' }, + inccheck=>sub { -e catfile($_[0], 't1lib.h') }, libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" }, libfiles=>'-lt1', objfiles=>'', @@ -352,24 +544,27 @@ sub init { for use in images.} }; - $formats{'TT-fonts'}={ - order=>'31', - def=>'HAVE_LIBTT', - inccheck=>sub { $_[0] eq 'freetype.h' }, - libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" }, - libfiles=>'-lttf', - objfiles=>'', - docs=>q{ - Truetype fonts are scalable fonts. They can include - kerning and hinting information and generally yield good - visual quality esp on low resultions. The freetype library is - used to rasterize for us. The only drawback is that there - are alot of badly designed fonts out there.} + $formats{'TT-fonts'}= + { + order=>'31', + def=>'HAVE_LIBTT', + inccheck=>sub { -e catfile($_[0], 'freetype.h') + && !-e catfile($_[0], 'fterrors.h') }, + libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" }, + libfiles=>'-lttf', + objfiles=>'', + code => \&freetype1_probe, + docs=>q{ +Truetype fonts are scalable fonts. They can include +kerning and hinting information and generally yield good +visual quality esp on low resultions. The freetype library is +used to rasterize for us. The only drawback is that there +are alot of badly designed fonts out there.} }; $formats{'w32'} = { order=>40, def=>'HAVE_WIN32', - inccheck=>sub { lc $_[0] eq 'windows.h' }, + inccheck=>sub { -e catfile($_[0], 'windows.h') }, libcheck=>sub { lc $_[0] eq 'gdi32.lib' || lc $_[0] eq 'libgdi32.a' }, libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '', @@ -380,18 +575,26 @@ Uses the Win32 GDI for rendering text. This currently only works on under normal Win32 and cygwin. DOCS }; - $formats{'freetype2'} = { - order=>'29', - def=>'HAVE_FT2', - inccheck=>sub { lc $_[0] eq 'ft2build.h' }, - libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" }, - libfiles=>'-lfreetype', - objfiles=>'freetyp2.o', - docs=><'29', + def=>'HAVE_FT2', + # we always use a probe function + #inccheck=>sub { -e catfile($_[0], 'ft2build.h') }, + #libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" }, + libfiles=>'-lfreetype', + objfiles=>'freetyp2.o', + docs=>< + [ + \&freetype2_probe_ftconfig, + \&freetype2_probe_scan + ], + }; + # Make fix indent for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/ /mg; } } @@ -426,14 +629,364 @@ sub getenv { IM_LFLAGS IM_DFLAGS); - if ($VERBOSE) { print "Verbose mode\n"; require Data::Dumper; import Data::Dumper qw(Dumper);} +} + +sub make_imconfig { + my ($defines) = @_; + + open CONFIG, "> imconfig.h" + or die "Cannot create imconfig.h: $!\n"; + print CONFIG <[2]) { + print CONFIG "\n/*\n $define->[2]\n*/\n\n"; + } + print CONFIG "#define $define->[0] $define->[1]\n"; + } + print CONFIG "\n#endif\n"; + close CONFIG; +} + +# use pkg-config to probe for libraries +# works around the junk that pkg-config dumps on FreeBSD +sub _pkg_probe { + my ($pkg) = @_; - if ($NOLOG) { print "Logging not compiled into module\n"; } - else { $EXTDEF.=' -DIMAGER_LOG'; } + is_exe('pkg-config') or return; - if ($DEBUG_MALLOC) { - $EXTDEF.=' -DIMAGER_DEBUG_MALLOC'; - print "Malloc debugging enabled\n"; + my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null'; + + !system("pkg-config $pkg --exists $redir"); +} + +# probes for freetype1 by scanning @incs for the includes and +# @libs for the libs. This is done separately because freetype's headers +# are stored in a freetype or freetype1 directory under PREFIX/include. +# +# we could find the files with the existing mechanism, but it won't set +# -I flags correctly. +# +# This could be extended to freetype2 too, but freetype-config catches +# that +sub freetype1_probe { + my ($frm, $frmkey) = @_; + + my $found_inc; + INCS: + for my $inc (@incs) { + for my $subdir (qw/freetype freetype1/) { + my $path = File::Spec->catfile($inc, $subdir, 'freetype.h'); + -e $path or next; + $path = File::Spec->catfile($inc, $subdir, 'fterrors.h'); + -e $path and next; + + $found_inc = File::Spec->catdir($inc, $subdir); + last INCS; + } + } + + my $found_lib; + LIBS: + for my $lib (@libs) { + my $a_path = File::Spec->catfile($lib, "libttf$aext"); + my $l_path = File::Spec->catfile($lib, "libttf.$lext"); + if (-e $a_path || -e $l_path) { + $found_lib = $lib; + last LIBS; + } + } + + return unless $found_inc && $found_lib; + printf("%10s: includes %s - libraries %s\n", $frmkey, + ($found_inc ? 'found' : 'not found'), + ($found_lib ? 'found' : 'not found')); + + $frm->{cflags} = "-I$found_inc"; + $frm->{libfiles} = "-lttf"; + + return 1; +} + +# probes for freetype2 by trying to run freetype-config +sub freetype2_probe_ftconfig { + my ($frm, $frmkey) = @_; + + is_exe('freetype-config') or return; + + my $cflags = `freetype-config --cflags` + and !$? or return; + chomp $cflags; + + my $lflags = `freetype-config --libs` + and !$? or return; + chomp $lflags; + + # before 2.1.5 freetype-config --cflags could output + # the -I options in the wrong order, causing a conflict with + # freetype1.x installed with the same --prefix + # + # can happen iff: + # - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags + # in that order + # - freetype 1.x headers are in prefix/include/freetype + my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags; + if (@incdirs == 2 + && $incdirs[1] eq "$incdirs[0]/freetype2" + && -e "$incdirs[0]/freetype/freetype.h" + && -e "$incdirs[0]/freetype/fterrid.h") { + print "** freetype-config provided -I options out of order, correcting\n" + if $VERBOSE; + $cflags = join(' ', grep(!/-I/, split ' ', $cflags), + map "-I$_", reverse @incdirs); + } + $frm->{cflags} = $cflags; + $frm->{lflags} = $lflags; + + printf "%10s: configured via freetype-config\n", $frmkey; + + return 1; +} + +# attempt to probe for freetype2 by scanning directories +# we can't use the normal scan since we need to find the directory +# containing most of the includes +sub freetype2_probe_scan { + my ($frm, $frmkey) = @_; + + my $found_inc; + my $found_inc2; + INCS: + for my $inc (@incs) { + my $path = File::Spec->catfile($inc, 'ft2build.h'); + -e $path or next; + + # try to find what it's including + my $ftheader; + open FT2BUILD, "< $path" + or next; + while () { + if (m!^\s*\#\s*include\s+<([\w/.]+)>! + || m!^\s*\#\s*include\s+"([\w/.]+)"!) { + $ftheader = $1; + last; + } + } + close FT2BUILD; + $ftheader + or next; + # non-Unix installs put this directly under the same directory in + # theory + if (-e File::Spec->catfile($inc, $ftheader)) { + $found_inc = $inc; + last INCS; + } + for my $subdir (qw/freetype2 freetype/) { + $path = File::Spec->catfile($inc, $subdir, 'fterrors.h'); + -e $path and next; + + $found_inc = $inc; + $found_inc2 = File::Spec->catdir($inc, $subdir); + last INCS; + } } + my $found_lib; + LIBS: + for my $lib (@libs) { + my $a_path = File::Spec->catfile($lib, "libfreetype$aext"); + my $l_path = File::Spec->catfile($lib, "libfreetype.$lext"); + if (-e $a_path || -e $l_path) { + $found_lib = $lib; + last LIBS; + } + } + + printf("%10s: includes %s - libraries %s\n", $frmkey, + ($found_inc ? 'found' : 'not found'), + ($found_lib ? 'found' : 'not found')); + + return unless $found_inc && $found_lib; + + $frm->{cflags} = _make_I($found_inc); + $frm->{cflags} .= " " . _make_I($found_inc2) if $found_inc2; + $frm->{libfiles} = "-lfreetype"; + + return 1; +} + +sub _make_I { + my ($inc_dir) = @_; + + $definc{$inc_dir} + and return ''; + + $inc_dir =~ / / ? qq!-I"$inc_dir"! : "-I$inc_dir"; } + +# probes for libpng via pkg-config +sub png_probe { + my ($frm, $frmkey) = @_; + + is_exe('pkg-config') or return; + + my $config; + for my $check_conf (qw(libpng libpng12 libpng10)) { + if (_pkg_probe($check_conf)) { + $config = $check_conf; + last; + } + } + $config or return; + + my $cflags = `pkg-config $config --cflags` + and !$? or return; + + my $lflags = `pkg-config $config --libs` + and !$? or return; + + chomp $cflags; + chomp $lflags; + $frm->{cflags} = $cflags; + $frm->{lflags} = $lflags; + + printf "%10s: configured via `pkg-config $config ...`\n", $frmkey; + + return 1; +} + +sub catfile { + return File::Spec->catfile(@_); +} + +sub is_exe { + my ($name) = @_; + + for my $dir (File::Spec->path) { + -x catfile($dir, "$name$Config{_exe}") + and return 1; + } + + return; +} + +sub usage { + print STDERR <parse_version($opts->{VERSION_FROM}) + or die "Could not extract version number from $opts->{VERSION_FROM}\n"; + + # we don't set this on older EU::MM and it corrupts META.yml + # so don't generate it + return unless $opts->{AUTHOR}; + + my $meta = <{NAME} +version: $version +version_from: $opts->{VERSION_FROM} +author: $opts->{AUTHOR} +abstract: $opts->{ABSTRACT} +installdirs: site +YAML + if (keys %{$Recommends{$opts->{NAME}}}) { + $meta .= "recommends:\n"; + while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) { + $meta .= " $module: $version\n"; + } + } + if ($opts->{PREREQ_PM}) { + $meta .= "requires:\n"; + while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) { + $meta .= " $module: $version\n"; + } + } + $meta .= <{NAME} version $version +YAML + my $save_meta; + if (open META, "< META.yml") { + my $old_meta = do { local $/; }; + close META; + + $save_meta = $old_meta ne $meta; + } + else { + ++$save_meta; + } + if ($save_meta) { + print "Updating META.yml\n"; + open META, "> META.yml" or die "Cannot create META.yml: $!"; + print META $meta; + close META; + } +} +