]> git.imager.perl.org - imager.git/blob - Makefile.PL
link zlib in using the default installed library name on Win32 instead of as libz.
[imager.git] / Makefile.PL
1 #!perl -w
2 use strict;
3 use ExtUtils::MakeMaker;
4 use Cwd;
5 use Config;
6 use File::Spec;
7 use Getopt::Long;
8 use vars qw(%Recommends %BuildRequires);
9 use ExtUtils::Manifest qw(maniread);
10 use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
11
12 #
13 # IM_INCPATH      colon seperated list of paths to extra include paths
14 # IM_LIBPATH      colon seperated list of paths to extra library paths
15 #
16 # IM_VERBOSE      turns on verbose mode for the library finding and such
17 # IM_MANUAL       to manually select which libraries are used and which not
18 # IM_ENABLE       to programmatically select which libraries are used
19 #                 and which are not
20 # IM_NOLOG        if true logging will not be compiled into the module
21 # IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
22 #                 do not use IM_DEBUG_MALLOC in production - this slows
23 #                 everything down by alot
24 # IM_CFLAGS       Extra flags to pass to the compiler
25 # IM_LFLAGS       Extra flags to pass to the linker
26 # IM_DFLAGS       Extra flags to pass to the preprocessor
27 # IM_SUPPRESS_PROMPT  Suppress the prompt asking about gif support
28
29 getenv();     # get environment variables
30
31 my $lext=$Config{'so'};   # Get extensions of libraries
32 my $aext=$Config{'_a'};
33
34 my $help; # display help if set
35 my @enable; # list of drivers to enable
36 my @disable; # or list of drivers to disable
37 my @incpaths; # places to look for headers
38 my @libpaths; # places to look for libraries
39 my $noprobe; # non-zero to disable newer probes
40 my $noexif; # non-zero to disable EXIF parsing of JPEGs
41 my $no_gif_set_version; # disable calling EGifSetGifVersion
42 GetOptions("help" => \$help,
43            "enable=s" => \@enable,
44            "disable=s" => \@disable,
45            "incpath=s", \@incpaths,
46            "libpath=s" => \@libpaths,
47            "noprobe" => \$noprobe,
48            "verbose|v" => \$VERBOSE,
49            "nolog" => \$NOLOG,
50            "noexif" => \$noexif,
51            "nogifsetversion" => \$no_gif_set_version);
52
53 if ($VERBOSE) { 
54   print "Verbose mode\n"; 
55   require Data::Dumper; 
56   import Data::Dumper qw(Dumper);
57 }
58
59 if ($help) {
60   usage();
61 }
62
63 my @defines;
64
65 if ($NOLOG)   { print "Logging not compiled into module\n"; }
66 else { 
67   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
68 }
69
70 if ($DEBUG_MALLOC) {
71   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
72   print "Malloc debugging enabled\n";
73 }
74
75 if (@enable && @disable) {
76   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
77   exit 1;
78 }
79
80 my %definc;
81 my %deflib;
82 my @incs; # all the places to look for headers
83 my @libs; # all the places to look for libraries
84
85 init();       # initialize global data
86 pathcheck();  # Check if directories exist
87 distcheck();  # for building dists
88
89 if (exists $ENV{IM_ENABLE}) {
90   my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
91   for my $key (keys %formats) {
92     delete $formats{$key} unless $en{$key};
93   }
94 }
95 if (@enable) {
96   my %en = map { $_ => 1 } map { split /,/ } @enable;
97   for my $key (keys %formats) {
98     delete $formats{$key} unless $en{$key};
99   }
100 }
101 elsif (@disable) {
102   delete @formats{map { split /,/ } @disable};
103 }
104
105 # Pick what libraries are used
106 if ($MANUAL) {
107   manual();
108 } else {
109   automatic();
110 }
111
112 # Make sure there isn't a clash between the gif libraries.
113 gifcheck();
114
115 my $lib_cflags = '';
116 my $lib_lflags = '';
117 my $F_LIBS = '';
118 my $F_OBJECT = '';
119 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
120   my $frm = $formats{$frmkey};
121   push @defines, [ $frm->{def}, 1, "$frmkey available" ];
122   $F_OBJECT .= ' '  .$frm->{objfiles};
123   if ($frm->{cflags}) {
124     $lib_cflags   .= ' '  .$frm->{cflags};
125     ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
126       grep /^-I./, split ' ', $frm->{cflags};
127   }
128   if ($frm->{lflags}) {
129     $lib_lflags .= ' ' . $frm->{lflags};
130   }
131   else {
132     $F_LIBS   .= ' '  .$frm->{libfiles};
133   }
134
135 }
136
137 unless ($noexif) {
138   print "EXIF support enabled\n";
139   push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
140   $F_OBJECT .= ' imexif.o';
141 }
142
143 my $F_INC  = join ' ', map "-I$_", map / / ? qq{"$_"} : $_, 
144   grep !$definc{$_}, @incs;
145 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_, 
146                grep !$deflib{$_}++, @libs) . $F_LIBS;
147
148 my $OSLIBS = '';
149 my $OSDEF  = "-DOS_$^O";
150
151 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
152 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
153
154 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
155               log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
156               filters.o dynaload.o stackmach.o datatypes.o
157               regmach.o trans2.o quant.o error.o convert.o
158               map.o tags.o palimg.o maskimg.o img16.o rotate.o
159               bmp.o tga.o rgb.o color.o fills.o imgdouble.o limits.o hlines.o
160               imext.o scale.o rubthru.o);
161
162 $Recommends{Imager} =
163   { 'Parse::RecDescent' => 0 };
164 $BuildRequires{Imager} =
165   { 'Test::More' => 0.47 };
166
167 my %opts=(
168           'NAME'         => 'Imager',
169           'VERSION_FROM' => 'Imager.pm',
170           'LIBS'         => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
171           'DEFINE'       => "$OSDEF $CFLAGS",
172           'INC'          => "$lib_cflags $DFLAGS $F_INC",
173           'OBJECT'       => join(' ', @objs, $F_OBJECT),
174           clean          => { FILES=>'testout meta.tmp rubthru.c scale.c' },
175           PM             => gen_PM(),
176           PREREQ_PM      => $BuildRequires{Imager},
177          );
178
179 # eval to prevent warnings about versions with _ in them
180 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
181 if ($MM_ver > 6.06) {
182   $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
183   $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
184 }
185 if ($MM_ver > 6.10) {
186   $opts{NO_META} = 1;
187 }
188
189 make_imconfig(\@defines);
190
191 if ($VERBOSE) { print Dumper(\%opts); }
192 mkdir('testout',0777); # since we cannot include it in the archive.
193
194 make_metafile(\%opts);
195
196 WriteMakefile(%opts);
197
198 exit;
199
200
201 sub MY::postamble {
202     my $self = shift;
203     my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
204     my $mani = maniread;
205
206     my @ims = grep /\.im$/, keys %$mani;
207 '
208 dyntest.$(MYEXTLIB) : dynfilt/Makefile
209         cd dynfilt && $(MAKE) $(PASTHRU)
210
211 lib/Imager/Regops.pm : regmach.h regops.perl
212         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
213
214 imconfig.h : Makefile.PL
215         $(ECHO) "imconfig.h out-of-date with respect to $?"
216         $(PERLRUN) Makefile.PL
217         $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
218 '.qq!
219 lib/Imager/APIRef.pod : \$(C_FILES) apidocs.perl
220         $perl apidocs.perl lib/Imager/APIRef.pod
221
222 !.join('', map _im_rule($perl, $_), @ims)
223
224 }
225
226 sub _im_rule {
227   my ($perl, $im) = @_;
228
229   (my $c = $im) =~ s/\.im$/.c/;
230   return <<MAKE;
231
232 $c: $im imtoc.perl
233         $perl imtoc.perl $im $c
234
235 MAKE
236
237 }
238
239 # manual configuration of helper libraries
240
241 sub manual {
242   print <<EOF;
243
244       Please answer the following questions about
245       which formats are avaliable on your computer
246
247 press <return> to continue
248 EOF
249
250   <STDIN>; # eat one return
251
252   for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
253   SWX:
254     if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
255     print "Enable $frm support: ";
256     my $gz = <STDIN>;
257     chomp($gz);
258     if ($gz =~ m/^(y|yes|n|no)/i) {
259       $gz=substr(lc($gz),0,1);
260       if ($gz eq 'n') {
261         delete $formats{$frm};
262       }
263     } else { goto SWX; }
264   }
265 }
266
267
268 # automatic configuration of helper libraries
269
270 sub automatic {
271   print "Automatic probing:\n" if $VERBOSE;
272   for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
273     delete $formats{$frm} if !checkformat($frm);        
274   }
275 }
276
277
278 sub gifcheck {
279   if ($formats{'gif'} and $formats{'ungif'}) {
280     print "ungif and gif can not coexist - removing ungif support\n";
281     delete $formats{'ungif'};
282   }
283
284   for my $frm (qw(gif ungif)) {
285     checkformat($frm) if ($MANUAL and $formats{$frm});
286   }
287
288   my @dirs;
289   for my $frm (grep $formats{$_}, qw(gif ungif)) {
290     push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
291   }
292   my $minor = 0;
293   my $major = 0;
294   FILES: for my $dir (@dirs) {
295     my $h = "$dir/gif_lib.h";
296     open H, "< $h" or next;
297     while (<H>) {
298       if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
299         $major = $1;
300         $minor = $2;
301         close H;
302         last FILES;
303       }
304     }
305     close H;
306   }
307
308   # we need the version in a #ifdefable form
309
310   push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
311   push @defines, [ IM_GIFMINOR => $minor ];
312   push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
313     if $no_gif_set_version;
314 }
315
316
317 sub gd {
318   my($path,$chk)=@_;
319
320 #    print "checking path $path\n";
321   if ( !opendir(DH,$path) ) {
322     warn "Cannot open dir $path: $!\n";
323     return;
324   }
325   my @l=grep { $chk->($_) } readdir(DH);
326   #    print @l;
327   close(DH);
328   return map $path, @l;
329 }
330
331
332 sub checkformat {
333   my $frm=shift;
334
335   print "  checkformat($frm)\n" if $VERBOSE;
336   
337   my $code = $formats{$frm}{'code'};
338   if ($code && !$noprobe) {
339     print "    Calling probe function\n" if $VERBOSE;
340     return 1 if $code->($formats{$frm}, $frm);
341   }
342
343   my $libchk=$formats{$frm}{'libcheck'};
344   my $incchk=$formats{$frm}{'inccheck'};
345
346   my @l;
347   for my $lp (@libs) {
348     push(@l, gd($lp,$libchk));
349   }
350
351   my @i;
352   for my $ip (@incs) {
353     push(@i, $ip) if $incchk->($ip,$frm);
354   }
355
356   printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
357   $formats{$frm}{incdir} = \@i;
358   $formats{$frm}{libdir} = \@l;
359   return scalar(@i && @l);
360 }
361
362
363 sub pathcheck {
364   if ($VERBOSE) {
365     print "pathcheck\n";
366     print "  Include paths:\n";
367     for (@incs) { print $_,"\n"; }
368   }
369   @incs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
370
371   if ($VERBOSE) {
372     print "\nLibrary paths:\n";
373     for (@libs) { print $_,"\n"; }
374   }
375   @libs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
376   print "\ndone.\n";
377 }
378
379
380 # Format data initialization
381
382 # format definition is:
383 # defines needed
384 # default include path
385 # files needed for include (boolean perl code)
386 # default lib path
387 # libs needed
388 # files needed for link (boolean perl code)
389 # object files needed for the format
390
391
392 sub init {
393
394   my @definc = qw(/usr/include);
395   @definc{@definc}=(1) x @definc;
396   @incs=(split(/\Q$Config{path_sep}/, $INCPATH),
397         map { split /\Q$Config{path_sep}/} @incpaths );
398   if ($Config{locincpth}) {
399     push @incs, grep -d, split ' ', $Config{locincpth};
400   }
401   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
402     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
403   }
404   push @incs, grep -d,
405       qw(/sw/include 
406          /usr/include/freetype2
407          /usr/local/include/freetype2
408          /usr/local/include/freetype1/freetype
409          /usr/include /usr/local/include /usr/include/freetype
410          /usr/local/include/freetype);
411   if ($Config{ccflags}) {
412     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
413     push @incs, @hidden;
414     @definc{@hidden} = (1) x @hidden;
415   }
416
417   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
418     map { split /\Q$Config{path_sep}/} @libpaths );
419   if ($Config{loclibpth}) {
420     push @libs, grep -d, split ' ', $Config{loclibpth};
421   }
422   
423   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
424   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
425   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
426     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
427   }
428   if ($^O eq 'cygwin') {
429     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
430     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
431   }
432   if ($Config{ldflags}) {
433     # some builds of perl put -Ldir into ldflags without putting it in
434     # loclibpth, let's extract them
435     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
436       split ' ', $Config{ldflags};
437     push @libs, @hidden;
438     # don't mark them as seen - EU::MM will remove any libraries
439     # it can't find and it doesn't look for -L in ldflags
440     #@deflib{@hidden} = @hidden;
441   }
442   push @libs, grep -d, qw(/usr/local/lib);
443
444   $formats{'jpeg'}={
445                     order=>'21',
446                     def=>'HAVE_LIBJPEG',
447                     inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
448                     libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
449                     libfiles=>'-ljpeg',
450                     objfiles=>'jpeg.o',
451                     docs=>q{
452                             In order to use jpeg with this module you need to have libjpeg
453                             installed on your computer}
454                    };
455
456   $formats{'tiff'}={
457                     order=>'23',
458                     def=>'HAVE_LIBTIFF',
459                     inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
460                     libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
461                     libfiles=>'-ltiff',
462                     objfiles=>'tiff.o',
463                     docs=>q{
464                             In order to use tiff with this module you need to have libtiff
465                             installed on your computer}
466                    };
467
468   $formats{'png'}={
469                    order=>'22',
470                    def=>'HAVE_LIBPNG',
471                    inccheck=>sub { -e catfile($_[0], 'png.h') },
472                    libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
473                    libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
474                    objfiles=>'png.o',
475                    docs=>q{
476                            Png stands for Portable Network Graphics and is intended as
477                            a replacement for gif on the web. It is patent free and
478                            is recommended by the w3c, you need libpng to use these formats},
479                    code => \&png_probe,
480                   };
481
482   $formats{'gif'}={
483                    order=>'20',
484                    def=>'HAVE_LIBGIF',
485                    inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
486                    libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
487                    libfiles=>'-lgif',
488                    objfiles=>'gif.o',
489                    docs=>q{
490                            gif is the de facto standard for webgraphics at the moment,
491                            it does have some patent problems. If you have giflib and
492                            are not in violation with the unisys patent you should use
493                            this instead of the 'ungif' option.  Note that they cannot
494                            be in use at the same time}
495                   };
496
497   $formats{'ungif'}={
498                      order=>'21',
499                      def=>'HAVE_LIBGIF',
500                      inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
501                      libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
502                      libfiles=>'-lungif',
503                      objfiles=>'gif.o',
504                      docs=>q{
505                              gif is the de facto standard for webgraphics at the moment,
506                              it does have some patent problems. If you have libungif and
507                              want to create images free from LZW patented compression you
508                              should use this option instead of the 'gif' option}
509                     };
510
511   $formats{'T1-fonts'}={
512                         order=>'30',
513                         def=>'HAVE_LIBT1',
514                         inccheck=>sub { -e catfile($_[0], 't1lib.h') },
515                         libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
516                         libfiles=>'-lt1',
517                         objfiles=>'',
518                         docs=>q{
519                                 postscript t1 fonts are scalable fonts. They can include 
520                                 ligatures and kerning information and generally yield good
521                                 visual quality. We depend on libt1 to rasterize the fonts
522                                 for use in images.}
523                        };
524
525   $formats{'TT-fonts'}=
526     {
527      order=>'31',
528      def=>'HAVE_LIBTT',
529      inccheck=>sub { -e catfile($_[0], 'freetype.h')
530                        && !-e catfile($_[0], 'fterrors.h') },
531      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
532      libfiles=>'-lttf',
533      objfiles=>'',
534      code => \&freetype1_probe,
535      docs=>q{
536 Truetype fonts are scalable fonts. They can include 
537 kerning and hinting information and generally yield good
538 visual quality esp on low resultions. The freetype library is
539 used to rasterize for us. The only drawback is that there
540 are alot of badly designed fonts out there.}
541                        };
542   $formats{'w32'} = {
543                      order=>40,
544                      def=>'HAVE_WIN32',
545                      inccheck=>sub { -e catfile($_[0], 'windows.h') },
546                      libcheck=>sub { lc $_[0] eq 'gdi32.lib' 
547                                        || lc $_[0] eq 'libgdi32.a' },
548                      libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
549                      objfiles=>'win32.o',
550                      docs => <<DOCS
551 Uses the Win32 GDI for rendering text.
552
553 This currently only works on under normal Win32 and cygwin.
554 DOCS
555                     };
556   $formats{'freetype2'} = {
557                            order=>'29',
558                            def=>'HAVE_FT2',
559                            inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
560                            libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
561                            libfiles=>'-lfreetype',
562                            objfiles=>'freetyp2.o',
563                            docs=><<DOCS,
564 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
565 scalable.  It also supports a variety of other fonts.
566 DOCS
567                            code => \&freetype2_probe,
568                           };
569
570   # Make fix indent
571   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
572 }
573
574
575
576 sub gen {
577   my $V = $ENV{$_[0]};
578   defined($V) ? $V : "";
579 }
580
581
582 # Get information from environment variables
583
584 sub getenv {
585
586   ($VERBOSE,
587    $INCPATH,
588    $LIBPATH,
589    $NOLOG,
590    $DEBUG_MALLOC,
591    $MANUAL,
592    $CFLAGS,
593    $LFLAGS,
594    $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
595                                 IM_INCPATH
596                                 IM_LIBPATH
597                                 IM_NOLOG
598                                 IM_DEBUG_MALLOC
599                                 IM_MANUAL
600                                 IM_CFLAGS
601                                 IM_LFLAGS
602                                 IM_DFLAGS);
603
604 }
605
606 sub make_imconfig {
607   my ($defines) = @_;
608
609   open CONFIG, "> imconfig.h"
610     or die "Cannot create imconfig.h: $!\n";
611   print CONFIG <<EOS;
612 /* This file is automatically generated by Makefile.PL.
613    Don't edit this file, since any changes will be lost */
614
615 #ifndef IMAGER_IMCONFIG_H
616 #define IMAGER_IMCONFIG_H
617 EOS
618   for my $define (@$defines) {
619     if ($define->[2]) {
620       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
621     }
622     print CONFIG "#define $define->[0] $define->[1]\n";
623   }
624   print CONFIG "\n#endif\n";
625   close CONFIG;
626 }
627
628 # use pkg-config to probe for libraries
629 # works around the junk that pkg-config dumps on FreeBSD
630 sub _pkg_probe {
631   my ($pkg) = @_;
632
633   is_exe('pkg-config') or return;
634
635   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
636
637   !system("pkg-config $pkg --exists $redir");
638 }
639
640 # probes for freetype1 by scanning @incs for the includes and 
641 # @libs for the libs.  This is done separately because freetype's headers
642 # are stored in a freetype or freetype1 directory under PREFIX/include.
643 #
644 # we could find the files with the existing mechanism, but it won't set
645 # -I flags correctly.
646 #
647 # This could be extended to freetype2 too, but freetype-config catches
648 # that
649 sub freetype1_probe {
650   my ($frm, $frmkey) = @_;
651
652   my $found_inc;
653  INCS:
654   for my $inc (@incs) {
655     for my $subdir (qw/freetype freetype1/) {
656       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
657       -e $path or next;
658       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
659       -e $path and next;
660
661       $found_inc = File::Spec->catdir($inc, $subdir);
662       last INCS;
663     }
664   }
665
666   my $found_lib;
667  LIBS:
668   for my $lib (@libs) {
669     my $a_path = File::Spec->catfile($lib, "libttf$aext");
670     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
671     if (-e $a_path || -e $l_path) {
672       $found_lib = $lib;
673       last LIBS;
674     }
675   }
676
677   return unless $found_inc && $found_lib;
678   printf("%10s: includes %s - libraries %s\n", $frmkey,
679          ($found_inc ? 'found' : 'not found'), 
680          ($found_lib ? 'found' : 'not found'));
681
682   $frm->{cflags} = "-I$found_inc";
683   $frm->{libfiles} = "-lttf";
684
685   return 1;
686 }
687
688 # probes for freetype2 by trying to run freetype-config
689 sub freetype2_probe {
690   my ($frm, $frmkey) = @_;
691
692   is_exe('freetype-config') or return;
693
694   my $cflags = `freetype-config --cflags`
695     and !$? or return;
696   chomp $cflags;
697
698   my $lflags = `freetype-config --libs`
699     and !$? or return;
700   chomp $lflags;
701
702   # before 2.1.5 freetype-config --cflags could output
703   # the -I options in the wrong order, causing a conflict with
704   # freetype1.x installed with the same --prefix
705   #
706   # can happen iff:
707   #  - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
708   #    in that order
709   #  - freetype 1.x headers are in prefix/include/freetype
710   my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
711   if (@incdirs == 2 
712       && $incdirs[1] eq "$incdirs[0]/freetype2"
713       && -e "$incdirs[0]/freetype/freetype.h"
714       && -e "$incdirs[0]/freetype/fterrid.h") {
715     print "** freetype-config provided -I options out of order, correcting\n"
716       if $VERBOSE;
717     $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
718                    map "-I$_", reverse @incdirs);
719   }
720   $frm->{cflags} = $cflags;
721   $frm->{lflags} = $lflags;
722
723   printf "%10s: configured via freetype-config\n", $frmkey;
724
725   return 1;
726 }
727
728 # probes for libpng via pkg-config
729 sub png_probe {
730   my ($frm, $frmkey) = @_;
731
732   is_exe('pkg-config') or return;
733
734   my $config;
735   for my $check_conf (qw(libpng libpng12 libpng10)) {
736     if (_pkg_probe($check_conf)) {
737       $config = $check_conf;
738       last;
739     }
740   }
741   $config or return;
742
743   my $cflags = `pkg-config $config --cflags`
744     and !$? or return;
745
746   my $lflags = `pkg-config $config --libs`
747     and !$? or return;
748
749   chomp $cflags;
750   chomp $lflags;
751   $frm->{cflags} = $cflags;
752   $frm->{lflags} = $lflags;
753
754   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
755
756   return 1;
757 }
758
759 sub catfile {
760   return File::Spec->catfile(@_);
761 }
762
763 sub is_exe {
764   my ($name) = @_;
765
766   for my $dir (File::Spec->path) {
767     -x catfile($dir, "$name$Config{_exe}")
768       and return 1;
769   }
770
771   return;
772 }
773
774 sub usage {
775   print STDERR <<EOS;
776 Usage: $0 [--enable feature1,feature2,...] [other options]
777        $0 [--disable feature1,feature2,...]  [other options]
778        $0 --help
779 Possible feature names are:
780   png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
781 Other options:
782   --verbose | -v
783     Verbose library probing (or set IM_VERBOSE in the environment)
784   --nolog
785     Disable logging (or set IM_NOLOG in the environment)
786   --incpath dir
787     Add to the include search path
788   --libpath dir
789     Add to the library search path
790   --noprobe
791     Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
792 EOS
793   exit 1;
794
795 }
796
797 # generate the PM MM argument
798 # I'd prefer to modify the public version, but there doesn't seem to be 
799 # a public API to do that
800 sub gen_PM {
801   my %pm;
802   my $instbase = '$(INST_LIBDIR)';
803
804   # first the basics, .pm and .pod files
805   $pm{"Imager.pm"} = "$instbase/Imager.pm";
806
807   my $mani = maniread();
808
809   for my $filename (keys %$mani) {
810     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
811       (my $work = $filename) =~ s/^lib//;
812       $pm{$filename} = $instbase . $work;
813     }
814   }
815
816   # need the typemap
817   $pm{typemap} = $instbase . '/Imager/typemap';
818
819   # and the core headers
820   for my $filename (keys %$mani) {
821     if ($filename =~ /^\w+\.h$/) {
822       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
823     }
824   }
825
826   # and the generated header
827   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
828
829   \%pm;
830 }
831
832 sub make_metafile {
833   my ($opts) = @_;
834
835   # extract the version
836   my $version = MM->parse_version($opts->{VERSION_FROM})
837     or die "Could not extract version number from $opts->{VERSION_FROM}\n";
838
839   # we don't set this on older EU::MM and it corrupts META.yml
840   # so don't generate it
841   return unless $opts->{AUTHOR};
842
843   my $meta = <<YAML;
844 --- #YAML:1.0
845 name: $opts->{NAME}
846 version: $version
847 version_from: $opts->{VERSION_FROM}
848 author: $opts->{AUTHOR}
849 abstract: $opts->{ABSTRACT}
850 installdirs: site
851 YAML
852   if (keys %{$Recommends{$opts->{NAME}}}) {
853     $meta .= "recommends:\n";
854     while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
855       $meta .= "  $module: $version\n";
856     }
857   }
858   if (keys %{$BuildRequires{$opts->{NAME}}}) {
859     $meta .= "build_requires:\n";
860     while (my ($module, $version) = each %{$BuildRequires{$opts->{NAME}}}) {
861       $meta .= "  $module: $version\n";
862     }
863   }
864   $meta .= <<YAML;
865 license: perl
866 dynamic_config: 1
867 distribution_type: module
868 generated_by: $opts->{NAME} version $version
869 YAML
870   my $save_meta;
871   if (open META, "< META.yml") {
872     my $old_meta = do { local $/; <META> };
873     close META;
874
875     $save_meta = $old_meta ne $meta;
876   }
877   else {
878     ++$save_meta;
879   }
880   if ($save_meta) {
881     print "Updating META.yml\n";
882     open META, "> META.yml" or die "Cannot create META.yml: $!";
883     print META $meta;
884     close META;
885   }
886 }
887
888 # this is intended to only be running on the development
889 # machines
890 sub distcheck {
891   if (-e '.svn') {
892     # update Changes if needed
893     my $write_changes;
894     # get the last revision from Changes
895     if (open CHANGES, "< Changes") {
896       <CHANGES>;
897       my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
898         or ++$write_changes;
899
900       my ($revision) = grep s/^Revision: //, `svn info`
901         or die "Could not get Revision from svn";
902       chomp $revision;
903
904       $write_changes ||= $changes_rev != $revision;
905       close CHANGES;
906     }
907     else {
908       ++$write_changes;
909     }
910     if ($write_changes) {
911       print "Updating Changes file\n";
912       system 'svn log -v -r HEAD:943 >Changes';
913     }
914   }
915 }