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