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