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