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