Various changes:
[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 render.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   if ($Config{incpath}) {
403     push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
404   }
405   push @incs, grep -d,
406       qw(/sw/include 
407          /usr/include/freetype2
408          /usr/local/include/freetype2
409          /usr/local/include/freetype1/freetype
410          /usr/include /usr/local/include /usr/include/freetype
411          /usr/local/include/freetype);
412   if ($Config{ccflags}) {
413     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
414     push @incs, @hidden;
415     @definc{@hidden} = (1) x @hidden;
416   }
417
418   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
419     map { split /\Q$Config{path_sep}/} @libpaths );
420   if ($Config{loclibpth}) {
421     push @libs, grep -d, split ' ', $Config{loclibpth};
422   }
423   
424   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
425   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
426   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
427     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
428   }
429   if ($^O eq 'cygwin') {
430     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
431     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
432   }
433   if ($Config{ldflags}) {
434     # some builds of perl put -Ldir into ldflags without putting it in
435     # loclibpth, let's extract them
436     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
437       split ' ', $Config{ldflags};
438     push @libs, @hidden;
439     # don't mark them as seen - EU::MM will remove any libraries
440     # it can't find and it doesn't look for -L in ldflags
441     #@deflib{@hidden} = @hidden;
442   }
443   push @libs, grep -d, qw(/usr/local/lib);
444
445   $formats{'jpeg'}={
446                     order=>'21',
447                     def=>'HAVE_LIBJPEG',
448                     inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
449                     libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
450                     libfiles=>'-ljpeg',
451                     objfiles=>'jpeg.o',
452                     docs=>q{
453                             In order to use jpeg with this module you need to have libjpeg
454                             installed on your computer}
455                    };
456
457   $formats{'tiff'}={
458                     order=>'23',
459                     def=>'HAVE_LIBTIFF',
460                     inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
461                     libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
462                     libfiles=>'-ltiff',
463                     objfiles=>'tiff.o',
464                     docs=>q{
465                             In order to use tiff with this module you need to have libtiff
466                             installed on your computer}
467                    };
468
469   $formats{'png'}={
470                    order=>'22',
471                    def=>'HAVE_LIBPNG',
472                    inccheck=>sub { -e catfile($_[0], 'png.h') },
473                    libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
474                    libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
475                    objfiles=>'png.o',
476                    docs=>q{
477                            Png stands for Portable Network Graphics and is intended as
478                            a replacement for gif on the web. It is patent free and
479                            is recommended by the w3c, you need libpng to use these formats},
480                    code => \&png_probe,
481                   };
482
483   $formats{'gif'}={
484                    order=>'20',
485                    def=>'HAVE_LIBGIF',
486                    inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
487                    libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
488                    libfiles=>'-lgif',
489                    objfiles=>'gif.o',
490                    docs=>q{
491                            gif is the de facto standard for webgraphics at the moment,
492                            it does have some patent problems. If you have giflib and
493                            are not in violation with the unisys patent you should use
494                            this instead of the 'ungif' option.  Note that they cannot
495                            be in use at the same time}
496                   };
497
498   $formats{'ungif'}={
499                      order=>'21',
500                      def=>'HAVE_LIBGIF',
501                      inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
502                      libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
503                      libfiles=>'-lungif',
504                      objfiles=>'gif.o',
505                      docs=>q{
506                              gif is the de facto standard for webgraphics at the moment,
507                              it does have some patent problems. If you have libungif and
508                              want to create images free from LZW patented compression you
509                              should use this option instead of the 'gif' option}
510                     };
511
512   $formats{'T1-fonts'}={
513                         order=>'30',
514                         def=>'HAVE_LIBT1',
515                         inccheck=>sub { -e catfile($_[0], 't1lib.h') },
516                         libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
517                         libfiles=>'-lt1',
518                         objfiles=>'',
519                         docs=>q{
520                                 postscript t1 fonts are scalable fonts. They can include 
521                                 ligatures and kerning information and generally yield good
522                                 visual quality. We depend on libt1 to rasterize the fonts
523                                 for use in images.}
524                        };
525
526   $formats{'TT-fonts'}=
527     {
528      order=>'31',
529      def=>'HAVE_LIBTT',
530      inccheck=>sub { -e catfile($_[0], 'freetype.h')
531                        && !-e catfile($_[0], 'fterrors.h') },
532      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
533      libfiles=>'-lttf',
534      objfiles=>'',
535      code => \&freetype1_probe,
536      docs=>q{
537 Truetype fonts are scalable fonts. They can include 
538 kerning and hinting information and generally yield good
539 visual quality esp on low resultions. The freetype library is
540 used to rasterize for us. The only drawback is that there
541 are alot of badly designed fonts out there.}
542                        };
543   $formats{'w32'} = {
544                      order=>40,
545                      def=>'HAVE_WIN32',
546                      inccheck=>sub { -e catfile($_[0], 'windows.h') },
547                      libcheck=>sub { lc $_[0] eq 'gdi32.lib' 
548                                        || lc $_[0] eq 'libgdi32.a' },
549                      libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
550                      objfiles=>'win32.o',
551                      docs => <<DOCS
552 Uses the Win32 GDI for rendering text.
553
554 This currently only works on under normal Win32 and cygwin.
555 DOCS
556                     };
557   $formats{'freetype2'} = {
558                            order=>'29',
559                            def=>'HAVE_FT2',
560                            inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
561                            libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
562                            libfiles=>'-lfreetype',
563                            objfiles=>'freetyp2.o',
564                            docs=><<DOCS,
565 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
566 scalable.  It also supports a variety of other fonts.
567 DOCS
568                            code => \&freetype2_probe,
569                           };
570
571   # Make fix indent
572   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
573 }
574
575
576
577 sub gen {
578   my $V = $ENV{$_[0]};
579   defined($V) ? $V : "";
580 }
581
582
583 # Get information from environment variables
584
585 sub getenv {
586
587   ($VERBOSE,
588    $INCPATH,
589    $LIBPATH,
590    $NOLOG,
591    $DEBUG_MALLOC,
592    $MANUAL,
593    $CFLAGS,
594    $LFLAGS,
595    $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
596                                 IM_INCPATH
597                                 IM_LIBPATH
598                                 IM_NOLOG
599                                 IM_DEBUG_MALLOC
600                                 IM_MANUAL
601                                 IM_CFLAGS
602                                 IM_LFLAGS
603                                 IM_DFLAGS);
604
605 }
606
607 sub make_imconfig {
608   my ($defines) = @_;
609
610   open CONFIG, "> imconfig.h"
611     or die "Cannot create imconfig.h: $!\n";
612   print CONFIG <<EOS;
613 /* This file is automatically generated by Makefile.PL.
614    Don't edit this file, since any changes will be lost */
615
616 #ifndef IMAGER_IMCONFIG_H
617 #define IMAGER_IMCONFIG_H
618 EOS
619   for my $define (@$defines) {
620     if ($define->[2]) {
621       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
622     }
623     print CONFIG "#define $define->[0] $define->[1]\n";
624   }
625   print CONFIG "\n#endif\n";
626   close CONFIG;
627 }
628
629 # use pkg-config to probe for libraries
630 # works around the junk that pkg-config dumps on FreeBSD
631 sub _pkg_probe {
632   my ($pkg) = @_;
633
634   is_exe('pkg-config') or return;
635
636   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
637
638   !system("pkg-config $pkg --exists $redir");
639 }
640
641 # probes for freetype1 by scanning @incs for the includes and 
642 # @libs for the libs.  This is done separately because freetype's headers
643 # are stored in a freetype or freetype1 directory under PREFIX/include.
644 #
645 # we could find the files with the existing mechanism, but it won't set
646 # -I flags correctly.
647 #
648 # This could be extended to freetype2 too, but freetype-config catches
649 # that
650 sub freetype1_probe {
651   my ($frm, $frmkey) = @_;
652
653   my $found_inc;
654  INCS:
655   for my $inc (@incs) {
656     for my $subdir (qw/freetype freetype1/) {
657       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
658       -e $path or next;
659       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
660       -e $path and next;
661
662       $found_inc = File::Spec->catdir($inc, $subdir);
663       last INCS;
664     }
665   }
666
667   my $found_lib;
668  LIBS:
669   for my $lib (@libs) {
670     my $a_path = File::Spec->catfile($lib, "libttf$aext");
671     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
672     if (-e $a_path || -e $l_path) {
673       $found_lib = $lib;
674       last LIBS;
675     }
676   }
677
678   return unless $found_inc && $found_lib;
679   printf("%10s: includes %s - libraries %s\n", $frmkey,
680          ($found_inc ? 'found' : 'not found'), 
681          ($found_lib ? 'found' : 'not found'));
682
683   $frm->{cflags} = "-I$found_inc";
684   $frm->{libfiles} = "-lttf";
685
686   return 1;
687 }
688
689 # probes for freetype2 by trying to run freetype-config
690 sub freetype2_probe {
691   my ($frm, $frmkey) = @_;
692
693   is_exe('freetype-config') or return;
694
695   my $cflags = `freetype-config --cflags`
696     and !$? or return;
697   chomp $cflags;
698
699   my $lflags = `freetype-config --libs`
700     and !$? or return;
701   chomp $lflags;
702
703   # before 2.1.5 freetype-config --cflags could output
704   # the -I options in the wrong order, causing a conflict with
705   # freetype1.x installed with the same --prefix
706   #
707   # can happen iff:
708   #  - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
709   #    in that order
710   #  - freetype 1.x headers are in prefix/include/freetype
711   my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
712   if (@incdirs == 2 
713       && $incdirs[1] eq "$incdirs[0]/freetype2"
714       && -e "$incdirs[0]/freetype/freetype.h"
715       && -e "$incdirs[0]/freetype/fterrid.h") {
716     print "** freetype-config provided -I options out of order, correcting\n"
717       if $VERBOSE;
718     $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
719                    map "-I$_", reverse @incdirs);
720   }
721   $frm->{cflags} = $cflags;
722   $frm->{lflags} = $lflags;
723
724   printf "%10s: configured via freetype-config\n", $frmkey;
725
726   return 1;
727 }
728
729 # probes for libpng via pkg-config
730 sub png_probe {
731   my ($frm, $frmkey) = @_;
732
733   is_exe('pkg-config') or return;
734
735   my $config;
736   for my $check_conf (qw(libpng libpng12 libpng10)) {
737     if (_pkg_probe($check_conf)) {
738       $config = $check_conf;
739       last;
740     }
741   }
742   $config or return;
743
744   my $cflags = `pkg-config $config --cflags`
745     and !$? or return;
746
747   my $lflags = `pkg-config $config --libs`
748     and !$? or return;
749
750   chomp $cflags;
751   chomp $lflags;
752   $frm->{cflags} = $cflags;
753   $frm->{lflags} = $lflags;
754
755   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
756
757   return 1;
758 }
759
760 sub catfile {
761   return File::Spec->catfile(@_);
762 }
763
764 sub is_exe {
765   my ($name) = @_;
766
767   for my $dir (File::Spec->path) {
768     -x catfile($dir, "$name$Config{_exe}")
769       and return 1;
770   }
771
772   return;
773 }
774
775 sub usage {
776   print STDERR <<EOS;
777 Usage: $0 [--enable feature1,feature2,...] [other options]
778        $0 [--disable feature1,feature2,...]  [other options]
779        $0 --help
780 Possible feature names are:
781   png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
782 Other options:
783   --verbose | -v
784     Verbose library probing (or set IM_VERBOSE in the environment)
785   --nolog
786     Disable logging (or set IM_NOLOG in the environment)
787   --incpath dir
788     Add to the include search path
789   --libpath dir
790     Add to the library search path
791   --noprobe
792     Don't use pkg-config or freetype2-config to probe for freetype2 and libpng
793 EOS
794   exit 1;
795
796 }
797
798 # generate the PM MM argument
799 # I'd prefer to modify the public version, but there doesn't seem to be 
800 # a public API to do that
801 sub gen_PM {
802   my %pm;
803   my $instbase = '$(INST_LIBDIR)';
804
805   # first the basics, .pm and .pod files
806   $pm{"Imager.pm"} = "$instbase/Imager.pm";
807
808   my $mani = maniread();
809
810   for my $filename (keys %$mani) {
811     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
812       (my $work = $filename) =~ s/^lib//;
813       $pm{$filename} = $instbase . $work;
814     }
815   }
816
817   # need the typemap
818   $pm{typemap} = $instbase . '/Imager/typemap';
819
820   # and the core headers
821   for my $filename (keys %$mani) {
822     if ($filename =~ /^\w+\.h$/) {
823       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
824     }
825   }
826
827   # and the generated header
828   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
829
830   \%pm;
831 }
832
833 sub make_metafile {
834   my ($opts) = @_;
835
836   # extract the version
837   my $version = MM->parse_version($opts->{VERSION_FROM})
838     or die "Could not extract version number from $opts->{VERSION_FROM}\n";
839
840   # we don't set this on older EU::MM and it corrupts META.yml
841   # so don't generate it
842   return unless $opts->{AUTHOR};
843
844   my $meta = <<YAML;
845 --- #YAML:1.0
846 name: $opts->{NAME}
847 version: $version
848 version_from: $opts->{VERSION_FROM}
849 author: $opts->{AUTHOR}
850 abstract: $opts->{ABSTRACT}
851 installdirs: site
852 YAML
853   if (keys %{$Recommends{$opts->{NAME}}}) {
854     $meta .= "recommends:\n";
855     while (my ($module, $version) = each %{$Recommends{$opts->{NAME}}}) {
856       $meta .= "  $module: $version\n";
857     }
858   }
859   if ($opts->{PREREQ_PM}) {
860     $meta .= "requires:\n";
861     while (my ($module, $version) = each %{$opts->{PREREQ_PM}}) {
862       $meta .= "  $module: $version\n";
863     }
864   }
865   $meta .= <<YAML;
866 license: perl
867 dynamic_config: 1
868 distribution_type: module
869 meta-spec:
870   version: 1.3
871   url: http://module-build.sourceforge.net/META-spec-v1.3.html
872 generated_by: $opts->{NAME} version $version
873 YAML
874   my $save_meta;
875   if (open META, "< META.yml") {
876     my $old_meta = do { local $/; <META> };
877     close META;
878
879     $save_meta = $old_meta ne $meta;
880   }
881   else {
882     ++$save_meta;
883   }
884   if ($save_meta) {
885     print "Updating META.yml\n";
886     open META, "> META.yml" or die "Cannot create META.yml: $!";
887     print META $meta;
888     close META;
889   }
890 }
891
892 # this is intended to only be running on the development
893 # machines
894 sub distcheck {
895   if (-e '.svn') {
896     # update Changes if needed
897     my $write_changes;
898     # get the last revision from Changes
899     if (open CHANGES, "< Changes") {
900       <CHANGES>;
901       my ($changes_rev) = <CHANGES> =~ /^r(\d+)/
902         or ++$write_changes;
903
904       my ($revision) = grep s/^Revision: //, `svn info`
905         or die "Could not get Revision from svn";
906       chomp $revision;
907
908       $write_changes ||= $changes_rev != $revision;
909       close CHANGES;
910     }
911     else {
912       ++$write_changes;
913     }
914     if ($write_changes) {
915       print "Updating Changes file\n";
916       system 'svn log -v -r HEAD:943 >Changes';
917     }
918   }
919 }