we don't prompt for gif support anymore
[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 ExtUtils::Manifest qw(maniread);
9 use vars qw(%formats $VERBOSE $INCPATH $LIBPATH $NOLOG $DEBUG_MALLOC $MANUAL $CFLAGS $LFLAGS $DFLAGS);
10 use lib 'inc';
11 use Devel::CheckLib;
12
13 #
14 # IM_INCPATH      colon seperated list of paths to extra include paths
15 # IM_LIBPATH      colon seperated list of paths to extra library paths
16 #
17 # IM_VERBOSE      turns on verbose mode for the library finding and such
18 # IM_MANUAL       to manually select which libraries are used and which not
19 # IM_ENABLE       to programmatically select which libraries are used
20 #                 and which are not
21 # IM_NOLOG        if true logging will not be compiled into the module
22 # IM_DEBUG_MALLOC if true malloc debbuging will be compiled into the module
23 #                 do not use IM_DEBUG_MALLOC in production - this slows
24 #                 everything down by alot
25 # IM_CFLAGS       Extra flags to pass to the compiler
26 # IM_LFLAGS       Extra flags to pass to the linker
27 # IM_DFLAGS       Extra flags to pass to the preprocessor
28
29 my $KEEP_FILES = $ENV{IMAGER_KEEP_FILES};
30
31 getenv();     # get environment variables
32
33 my $lext=$Config{'so'};   # Get extensions of libraries
34 my $aext=$Config{'_a'};
35
36 my $help; # display help if set
37 my @enable; # list of drivers to enable
38 my @disable; # or list of drivers to disable
39 my @incpaths; # places to look for headers
40 my @libpaths; # places to look for libraries
41 my $noexif; # non-zero to disable EXIF parsing of JPEGs
42 my $no_gif_set_version; # disable calling EGifSetGifVersion
43 my $coverage; # build for coverage testing
44 GetOptions("help" => \$help,
45            "enable=s" => \@enable,
46            "disable=s" => \@disable,
47            "incpath=s", \@incpaths,
48            "libpath=s" => \@libpaths,
49            "verbose|v" => \$VERBOSE,
50            "nolog" => \$NOLOG,
51            "noexif" => \$noexif,
52            "nogifsetversion" => \$no_gif_set_version,
53            'coverage' => \$coverage);
54
55 if ($VERBOSE) { 
56   print "Verbose mode\n"; 
57   require Data::Dumper; 
58   import Data::Dumper qw(Dumper);
59 }
60
61 if ($help) {
62   usage();
63 }
64
65 my @defines;
66
67 if ($NOLOG)   { print "Logging not compiled into module\n"; }
68 else { 
69   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
70 }
71
72 if ($DEBUG_MALLOC) {
73   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
74   print "Malloc debugging enabled\n";
75 }
76
77 if (@enable && @disable) {
78   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
79   exit 1;
80 }
81
82 my %definc;
83 my %deflib;
84 my @incs; # all the places to look for headers
85 my @libs; # all the places to look for libraries
86
87 init();       # initialize global data
88 pathcheck();  # Check if directories exist
89
90 if (exists $ENV{IM_ENABLE}) {
91   my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
92   for my $key (keys %formats) {
93     delete $formats{$key} unless $en{$key};
94   }
95 }
96 if (@enable) {
97   my %en = map { $_ => 1 } map { split /,/ } @enable;
98   for my $key (keys %formats) {
99     delete $formats{$key} unless $en{$key};
100   }
101 }
102 elsif (@disable) {
103   delete @formats{map { split /,/ } @disable};
104 }
105
106 # Pick what libraries are used
107 if ($MANUAL) {
108   manual();
109 } else {
110   automatic();
111 }
112
113 # Make sure there isn't a clash between the gif libraries.
114 gifcheck();
115
116 my $lib_cflags = '';
117 my $lib_lflags = '';
118 my $F_LIBS = '';
119 my $F_OBJECT = '';
120 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
121   my $frm = $formats{$frmkey};
122   push @defines, [ $frm->{def}, 1, "$frmkey available" ];
123   $F_OBJECT .= ' '  .$frm->{objfiles};
124   if ($frm->{cflags}) {
125     $lib_cflags   .= ' '  .$frm->{cflags};
126     ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
127       grep /^-I./, split ' ', $frm->{cflags};
128   }
129   if ($frm->{lflags}) {
130     $lib_lflags .= ' ' . $frm->{lflags};
131   }
132   else {
133     $F_LIBS   .= ' '  .$frm->{libfiles};
134   }
135
136 }
137
138 unless ($noexif) {
139   print "EXIF support enabled\n";
140   push @defines, [ 'IMEXIF_ENABLE', 1, "Enable experimental EXIF support" ];
141   $F_OBJECT .= ' imexif.o';
142 }
143
144 my $F_INC  = join ' ', map "-I$_", map / / ? qq{"$_"} : $_, 
145   grep !$definc{$_}, @incs;
146 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_, 
147                grep !$deflib{$_}++, @libs) . $F_LIBS;
148
149 my $OSLIBS = '';
150 my $OSDEF  = "-DOS_$^O";
151
152 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
153 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
154
155 my @objs = qw(Imager.o draw.o polygon.o image.o io.o iolayer.o
156               log.o gaussian.o conv.o pnm.o raw.o feat.o font.o
157               filters.o dynaload.o stackmach.o datatypes.o
158               regmach.o trans2.o quant.o error.o convert.o
159               map.o tags.o palimg.o maskimg.o img16.o rotate.o
160               bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
161               imext.o scale.o rubthru.o render.o paste.o compose.o);
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 rubthru.c scale.c conv.c  filters.c gaussian.c render.c rubthru.c' },
171           PM             => gen_PM(),
172           PREREQ_PM      => { 'Test::More' => 0.47 },
173          );
174
175 if ($coverage) {
176     if ($Config{gccversion}) {
177         push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs';
178         #$opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
179     }
180     else {
181         die "Don't know the coverage C flags for your compiler\n";
182     }
183 }
184
185 # eval to prevent warnings about versions with _ in them
186 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
187 if ($MM_ver > 6.06) {
188   $opts{AUTHOR} = 'Tony Cook <tony@imager.perl.org>, Arnar M. Hrafnkelsson';
189   $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
190 }
191
192 if ($MM_ver >= 6.46) {
193   $opts{META_MERGE} =
194     {
195      recommends =>
196      {
197       "Parse::RecDescent" => 0
198      },
199      license => "perl",
200      dynamic_config => 1,
201     };
202 }
203
204 make_imconfig(\@defines);
205
206 if ($VERBOSE) { print Dumper(\%opts); }
207 mkdir('testout',0777); # since we cannot include it in the archive.
208
209 -d "probe" and rmdir "probe";
210
211 WriteMakefile(%opts);
212
213 exit;
214
215
216 sub MY::postamble {
217     my $self = shift;
218     my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
219     my $mani = maniread;
220
221     my @ims = grep /\.im$/, keys %$mani;
222 '
223 dyntest.$(MYEXTLIB) : dynfilt/Makefile
224         cd dynfilt && $(MAKE) $(PASTHRU)
225
226 lib/Imager/Regops.pm : regmach.h regops.perl
227         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
228
229 imconfig.h : Makefile.PL
230         $(ECHO) "imconfig.h out-of-date with respect to $?"
231         $(PERLRUN) Makefile.PL
232         $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
233 '.qq!
234 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
235         $perl apidocs.perl lib/Imager/APIRef.pod
236
237 !.join('', map _im_rule($perl, $_), @ims)
238
239 }
240
241 sub _im_rule {
242   my ($perl, $im) = @_;
243
244   (my $c = $im) =~ s/\.im$/.c/;
245   return <<MAKE;
246
247 $c: $im lib/Imager/Preprocess.pm
248         $perl -Ilib -MImager::Preprocess -epreprocess $im $c
249
250 MAKE
251
252 }
253
254 # manual configuration of helper libraries
255
256 sub manual {
257   print <<EOF;
258
259       Please answer the following questions about
260       which formats are avaliable on your computer
261
262 press <return> to continue
263 EOF
264
265   <STDIN>; # eat one return
266
267   for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
268   SWX:
269     if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
270     print "Enable $frm support: ";
271     my $gz = <STDIN>;
272     chomp($gz);
273     if ($gz =~ m/^(y|yes|n|no)/i) {
274       $gz=substr(lc($gz),0,1);
275       if ($gz eq 'n') {
276         delete $formats{$frm};
277       }
278     } else { goto SWX; }
279   }
280 }
281
282
283 # automatic configuration of helper libraries
284
285 sub automatic {
286   print "Automatic probing:\n" if $VERBOSE;
287   for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
288     delete $formats{$frm} if !checkformat($frm);        
289   }
290 }
291
292
293 sub gifcheck {
294   if ($formats{'gif'} and $formats{'ungif'}) {
295     print "ungif and gif can not coexist - removing ungif support\n";
296     delete $formats{'ungif'};
297   }
298
299   for my $frm (qw(gif ungif)) {
300     checkformat($frm) if ($MANUAL and $formats{$frm});
301   }
302
303   my @dirs;
304   for my $frm (grep $formats{$_}, qw(gif ungif)) {
305     push(@dirs, @{$formats{$frm}{incdir}}) if $formats{$frm}{incdir};
306   }
307   my $minor = 0;
308   my $major = 0;
309   FILES: for my $dir (@dirs) {
310     my $h = "$dir/gif_lib.h";
311     open H, "< $h" or next;
312     while (<H>) {
313       if (/GIF_LIB_VERSION\s+"\s*version\s*(\d+)\.(\d+)/i) {
314         $major = $1;
315         $minor = $2;
316         close H;
317         last FILES;
318       }
319     }
320     close H;
321   }
322
323   # we need the version in a #ifdefable form
324
325   push @defines, [ IM_GIFMAJOR => $major, "Parsed giflib version" ];
326   push @defines, [ IM_GIFMINOR => $minor ];
327   push @defines, [ IM_NO_SET_GIF_VERSION => 1, "Disable EGifSetGifVersion" ]
328     if $no_gif_set_version;
329 }
330
331
332 sub grep_directory {
333   my($path, $chk)=@_;
334
335 #    print "checking path $path\n";
336   if ( !opendir(DH,$path) ) {
337     warn "Cannot open dir $path: $!\n";
338     return;
339   }
340   my @l=grep { $chk->($_) } readdir(DH);
341   #    print @l;
342   close(DH);
343   return map $path, @l;
344 }
345
346 sub _probe_default {
347   my ($format, $frm) = @_;
348
349   my $lib_check=$formats{$frm}{'libcheck'};
350   my $inc_check=$formats{$frm}{'inccheck'};
351
352   if ($lib_check) {
353     my @l;
354     for my $lp (@libs) {
355       push(@l, grep_directory($lp,$lib_check));
356     }
357     
358     my @i;
359     for my $ip (@incs) {
360       push(@i, $ip) if $inc_check->($ip,$frm);
361     }
362     
363     printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
364     $formats{$frm}{incdir} = \@i;
365     $formats{$frm}{libdir} = \@l;
366     return 1 if scalar(@i && @l);
367   }
368   else {
369     printf("%10s: not available\n", $frm);
370   }
371
372   return 0;
373 }
374
375 sub checkformat {
376   my $frm=shift;
377
378   print "  checkformat($frm)\n" if $VERBOSE;
379   
380   my $format = $formats{$frm};
381
382   my @probes;
383   if (my $code = $format->{'code'}) {
384     if (ref $code eq 'ARRAY') {
385       push @probes, @$code;
386     }
387     else {
388       push @probes, $code;
389     }
390   }
391   push @probes, \&_probe_default;
392
393   print "    Calling probe function\n" if $VERBOSE;
394   my $found;
395   for my $func (@probes) {
396     if ($func->($format, $frm)) {
397       ++$found;
398       last;
399     }
400   }
401
402   $found or return;
403
404   if ($format->{postcheck}) {
405     print "    Calling postcheck function\n" if $VERBOSE;
406     $format->{postcheck}->($format, $frm)
407       or return;
408   }
409
410   return 1;
411 }
412
413
414 sub pathcheck {
415   if ($VERBOSE) {
416     print "pathcheck\n";
417     print "  Include paths:\n";
418     for (@incs) { print $_,"\n"; }
419   }
420   @incs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
421
422   if ($VERBOSE) {
423     print "\nLibrary paths:\n";
424     for (@libs) { print $_,"\n"; }
425   }
426   @libs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
427   print "\ndone.\n";
428 }
429
430
431 # Format data initialization
432
433 # format definition is:
434 # defines needed
435 # default include path
436 # files needed for include (boolean perl code)
437 # default lib path
438 # libs needed
439 # files needed for link (boolean perl code)
440 # object files needed for the format
441
442
443 sub init {
444
445   my @definc = qw(/usr/include);
446   @definc{@definc}=(1) x @definc;
447   @incs=
448     (
449      split(/\Q$Config{path_sep}/, $INCPATH),
450      map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths 
451     );
452   if ($Config{locincpth}) {
453     push @incs, grep -d, split ' ', $Config{locincpth};
454   }
455   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
456     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
457   }
458   if ($Config{incpath}) {
459     push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
460   }
461   push @incs, grep -d,
462       qw(/sw/include 
463          /usr/include/freetype2
464          /usr/local/include/freetype2
465          /usr/local/include/freetype1/freetype
466          /usr/include /usr/local/include /usr/include/freetype
467          /usr/local/include/freetype);
468   if ($Config{ccflags}) {
469     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
470     push @incs, @hidden;
471     @definc{@hidden} = (1) x @hidden;
472   }
473
474   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
475     map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
476   if ($Config{loclibpth}) {
477     push @libs, grep -d, split ' ', $Config{loclibpth};
478   }
479   
480   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
481   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
482   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
483     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
484   }
485   if ($^O eq 'cygwin') {
486     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
487     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
488   }
489   if ($Config{ldflags}) {
490     # some builds of perl put -Ldir into ldflags without putting it in
491     # loclibpth, let's extract them
492     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
493       split ' ', $Config{ldflags};
494     push @libs, @hidden;
495     # don't mark them as seen - EU::MM will remove any libraries
496     # it can't find and it doesn't look for -L in ldflags
497     #@deflib{@hidden} = @hidden;
498   }
499   push @libs, grep -d, qw(/usr/local/lib);
500
501   $formats{'jpeg'}={
502                     order=>'21',
503                     def=>'HAVE_LIBJPEG',
504                     inccheck=>sub { -e catfile($_[0], 'jpeglib.h') },
505                     libcheck=>sub { $_[0] eq "libjpeg$aext" or $_ eq "libjpeg.$lext" },
506                     libfiles=>'-ljpeg',
507                     objfiles=>'jpeg.o',
508                     docs=>q{
509                             In order to use jpeg with this module you need to have libjpeg
510                             installed on your computer}
511                    };
512
513   $formats{'tiff'}={
514                     order=>'23',
515                     def=>'HAVE_LIBTIFF',
516                     inccheck=>sub { -e catfile($_[0], 'tiffio.h') },
517                     libcheck=>sub { $_[0] eq "libtiff$aext" or $_ eq "libtiff.$lext" },
518                     libfiles=>'-ltiff',
519                     objfiles=>'tiff.o',
520                     docs=>q{
521                             In order to use tiff with this module you need to have libtiff
522                             installed on your computer},
523                     postcheck => \&postcheck_tiff,
524                    };
525
526   $formats{'png'}={
527                    order=>'22',
528                    def=>'HAVE_LIBPNG',
529                    inccheck=>sub { -e catfile($_[0], 'png.h') },
530                    libcheck=>sub { $_[0] eq "libpng$aext" or $_[0] eq "libpng.$lext" },
531                    libfiles=>$^O eq 'MSWin32' ? '-lpng -lzlib' : '-lpng -lz',
532                    objfiles=>'png.o',
533                    docs=>q{
534                            Png stands for Portable Network Graphics and is intended as
535                            a replacement for gif on the web. It is patent free and
536                            is recommended by the w3c, you need libpng to use these formats},
537                    code => \&png_probe,
538                   };
539
540   $formats{'gif'}={
541                    order=>'20',
542                    def=>'HAVE_LIBGIF',
543                    inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
544                    libcheck=>sub { $_[0] eq "libgif$aext" or $_[0] eq "libgif.$lext" },
545                    libfiles=>'-lgif',
546                    objfiles=>'gif.o',
547                    docs=>q{
548                            gif is the de facto standard for webgraphics at the moment,
549                            it does have some patent problems. If you have giflib and
550                            are not in violation with the unisys patent you should use
551                            this instead of the 'ungif' option.  Note that they cannot
552                            be in use at the same time}
553                   };
554
555   $formats{'ungif'}={
556                      order=>'21',
557                      def=>'HAVE_LIBGIF',
558                      inccheck=>sub { -e catfile($_[0], 'gif_lib.h') },
559                      libcheck=>sub { $_[0] eq "libungif$aext" or $_[0] eq "libungif.$lext" },
560                      libfiles=>'-lungif',
561                      objfiles=>'gif.o',
562                      docs=>q{
563                              gif is the de facto standard for webgraphics at the moment,
564                              it does have some patent problems. If you have libungif and
565                              want to create images free from LZW patented compression you
566                              should use this option instead of the 'gif' option}
567                     };
568
569   $formats{'T1-fonts'}={
570                         order=>'30',
571                         def=>'HAVE_LIBT1',
572                         inccheck=>sub { -e catfile($_[0], 't1lib.h') },
573                         libcheck=>sub { $_[0] eq "libt1$aext" or $_[0] eq "libt1.$lext" },
574                         libfiles=>'-lt1',
575                         objfiles=>'',
576                         docs=>q{
577                                 postscript t1 fonts are scalable fonts. They can include 
578                                 ligatures and kerning information and generally yield good
579                                 visual quality. We depend on libt1 to rasterize the fonts
580                                 for use in images.}
581                        };
582
583   $formats{'TT-fonts'}=
584     {
585      order=>'31',
586      def=>'HAVE_LIBTT',
587      inccheck=>sub { -e catfile($_[0], 'freetype.h')
588                        && !-e catfile($_[0], 'fterrors.h') },
589      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
590      libfiles=>'-lttf',
591      objfiles=>'',
592      code => \&freetype1_probe,
593      docs=>q{
594 Truetype fonts are scalable fonts. They can include 
595 kerning and hinting information and generally yield good
596 visual quality esp on low resultions. The freetype library is
597 used to rasterize for us. The only drawback is that there
598 are alot of badly designed fonts out there.}
599                        };
600   $formats{'w32'} = {
601                      order=>40,
602                      def=>'HAVE_WIN32',
603                      inccheck=>sub { -e catfile($_[0], 'windows.h') },
604                      libcheck=>sub { lc $_[0] eq 'gdi32.lib' 
605                                        || lc $_[0] eq 'libgdi32.a' },
606                      libfiles=>$^O eq 'cygwin' ? '-lgdi32' : '',
607                      objfiles=>'win32.o',
608                      docs => <<DOCS
609 Uses the Win32 GDI for rendering text.
610
611 This currently only works on under normal Win32 and cygwin.
612 DOCS
613                     };
614   $formats{'freetype2'} = 
615   {
616    order=>'29',
617    def=>'HAVE_FT2',
618    # we always use a probe function
619    #inccheck=>sub { -e catfile($_[0], 'ft2build.h') },
620    #libcheck=>sub { $_[0] eq "libfreetype$aext" or $_[0] eq "libfreetype.$lext" },
621    libfiles=>'-lfreetype',
622    objfiles=>'freetyp2.o',
623    docs=><<DOCS,
624 Freetype 2 supports both Truetype and Type 1 fonts, both of which are
625 scalable.  It also supports a variety of other fonts.
626 DOCS
627    code =>
628    [ 
629     \&freetype2_probe_ftconfig,
630     \&freetype2_probe_scan
631    ],
632   };
633
634   # Make fix indent
635   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
636 }
637
638
639
640 sub gen {
641   my $V = $ENV{$_[0]};
642   defined($V) ? $V : "";
643 }
644
645
646 # Get information from environment variables
647
648 sub getenv {
649
650   ($VERBOSE,
651    $INCPATH,
652    $LIBPATH,
653    $NOLOG,
654    $DEBUG_MALLOC,
655    $MANUAL,
656    $CFLAGS,
657    $LFLAGS,
658    $DFLAGS) = map { gen $_ } qw(IM_VERBOSE
659                                 IM_INCPATH
660                                 IM_LIBPATH
661                                 IM_NOLOG
662                                 IM_DEBUG_MALLOC
663                                 IM_MANUAL
664                                 IM_CFLAGS
665                                 IM_LFLAGS
666                                 IM_DFLAGS);
667
668 }
669
670 sub make_imconfig {
671   my ($defines) = @_;
672
673   open CONFIG, "> imconfig.h"
674     or die "Cannot create imconfig.h: $!\n";
675   print CONFIG <<EOS;
676 /* This file is automatically generated by Makefile.PL.
677    Don't edit this file, since any changes will be lost */
678
679 #ifndef IMAGER_IMCONFIG_H
680 #define IMAGER_IMCONFIG_H
681 EOS
682   for my $define (@$defines) {
683     if ($define->[2]) {
684       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
685     }
686     print CONFIG "#define $define->[0] $define->[1]\n";
687   }
688   print CONFIG "\n#endif\n";
689   close CONFIG;
690 }
691
692 # use pkg-config to probe for libraries
693 # works around the junk that pkg-config dumps on FreeBSD
694 sub _pkg_probe {
695   my ($pkg) = @_;
696
697   is_exe('pkg-config') or return;
698
699   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
700
701   !system("pkg-config $pkg --exists $redir");
702 }
703
704 # probes for freetype1 by scanning @incs for the includes and 
705 # @libs for the libs.  This is done separately because freetype's headers
706 # are stored in a freetype or freetype1 directory under PREFIX/include.
707 #
708 # we could find the files with the existing mechanism, but it won't set
709 # -I flags correctly.
710 #
711 # This could be extended to freetype2 too, but freetype-config catches
712 # that
713 sub freetype1_probe {
714   my ($frm, $frmkey) = @_;
715
716   my $found_inc;
717  INCS:
718   for my $inc (@incs) {
719     for my $subdir (qw/freetype freetype1/) {
720       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
721       -e $path or next;
722       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
723       -e $path and next;
724
725       $found_inc = File::Spec->catdir($inc, $subdir);
726       last INCS;
727     }
728   }
729
730   my $found_lib;
731  LIBS:
732   for my $lib (@libs) {
733     my $a_path = File::Spec->catfile($lib, "libttf$aext");
734     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
735     if (-e $a_path || -e $l_path) {
736       $found_lib = $lib;
737       last LIBS;
738     }
739   }
740
741   return unless $found_inc && $found_lib;
742   printf("%10s: includes %s - libraries %s\n", $frmkey,
743          ($found_inc ? 'found' : 'not found'), 
744          ($found_lib ? 'found' : 'not found'));
745
746   $frm->{cflags} = "-I$found_inc";
747   $frm->{libfiles} = "-lttf";
748
749   return 1;
750 }
751
752 # probes for freetype2 by trying to run freetype-config
753 sub freetype2_probe_ftconfig {
754   my ($frm, $frmkey) = @_;
755
756   is_exe('freetype-config') or return;
757
758   my $cflags = `freetype-config --cflags`
759     and !$? or return;
760   chomp $cflags;
761
762   my $lflags = `freetype-config --libs`
763     and !$? or return;
764   chomp $lflags;
765
766   # before 2.1.5 freetype-config --cflags could output
767   # the -I options in the wrong order, causing a conflict with
768   # freetype1.x installed with the same --prefix
769   #
770   # can happen iff:
771   #  - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
772   #    in that order
773   #  - freetype 1.x headers are in prefix/include/freetype
774   my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
775   if (@incdirs == 2 
776       && $incdirs[1] eq "$incdirs[0]/freetype2"
777       && -e "$incdirs[0]/freetype/freetype.h"
778       && -e "$incdirs[0]/freetype/fterrid.h") {
779     print "** freetype-config provided -I options out of order, correcting\n"
780       if $VERBOSE;
781     $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
782                    map "-I$_", reverse @incdirs);
783   }
784   $frm->{cflags} = $cflags;
785   $frm->{lflags} = $lflags;
786
787   printf "%10s: configured via freetype-config\n", $frmkey;
788
789   return 1;
790 }
791
792 # attempt to probe for freetype2 by scanning directories
793 # we can't use the normal scan since we need to find the directory
794 # containing most of the includes
795 sub freetype2_probe_scan {
796   my ($frm, $frmkey) = @_;
797
798   my $found_inc;
799   my $found_inc2;
800  INCS:
801   for my $inc (@incs) {
802     my $path = File::Spec->catfile($inc, 'ft2build.h');
803     -e $path or next;
804
805     # try to find what it's including
806     my $ftheader;
807     open FT2BUILD, "< $path"
808       or next;
809     while (<FT2BUILD>) {
810       if (m!^\s*\#\s*include\s+<([\w/.]+)>!
811           || m!^\s*\#\s*include\s+"([\w/.]+)"!) {
812         $ftheader = $1;
813         last;
814       }
815     }
816     close FT2BUILD;
817     $ftheader
818       or next;
819     # non-Unix installs put this directly under the same directory in
820     # theory
821     if (-e File::Spec->catfile($inc, $ftheader)) {
822       $found_inc = $inc;
823       last INCS;
824     }
825     for my $subdir (qw/freetype2 freetype/) {
826       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
827       -e $path and next;
828
829       $found_inc = $inc;
830       $found_inc2 = File::Spec->catdir($inc, $subdir);
831       last INCS;
832     }
833   }
834
835   my $found_lib;
836  LIBS:
837   for my $lib (@libs) {
838     my $a_path = File::Spec->catfile($lib, "libfreetype$aext");
839     my $l_path = File::Spec->catfile($lib, "libfreetype.$lext");
840     if (-e $a_path || -e $l_path) {
841       $found_lib = $lib;
842       last LIBS;
843     }
844   }
845
846   printf("%10s: includes %s - libraries %s\n", $frmkey,
847          ($found_inc ? 'found' : 'not found'), 
848          ($found_lib ? 'found' : 'not found'));
849
850   return unless $found_inc && $found_lib;
851
852   $frm->{cflags} = _make_I($found_inc);
853   $frm->{cflags} .= " " . _make_I($found_inc2) if $found_inc2;
854   $frm->{libfiles} = "-lfreetype";
855
856   return 1;
857 }
858
859 sub _make_I {
860   my ($inc_dir) = @_;
861
862   $definc{$inc_dir}
863     and return '';
864
865   $inc_dir =~ / / ? qq!-I"$inc_dir"! : "-I$inc_dir";
866 }
867
868 # probes for libpng via pkg-config
869 sub png_probe {
870   my ($frm, $frmkey) = @_;
871
872   is_exe('pkg-config') or return;
873
874   my $config;
875   for my $check_conf (qw(libpng libpng12 libpng10)) {
876     if (_pkg_probe($check_conf)) {
877       $config = $check_conf;
878       last;
879     }
880   }
881   $config or return;
882
883   my $cflags = `pkg-config $config --cflags`
884     and !$? or return;
885
886   my $lflags = `pkg-config $config --libs`
887     and !$? or return;
888
889   chomp $cflags;
890   chomp $lflags;
891   $frm->{cflags} = $cflags;
892   $frm->{lflags} = $lflags;
893
894   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
895
896   return 1;
897 }
898
899 sub catfile {
900   return File::Spec->catfile(@_);
901 }
902
903 sub is_exe {
904   my ($name) = @_;
905
906   my @exe_suffix = $Config{_exe};
907   if ($^O eq 'MSWin32') {
908     push @exe_suffix, qw/.bat .cmd/;
909   }
910
911   for my $dir (File::Spec->path) {
912     for my $suffix (@exe_suffix) {
913       -x catfile($dir, "$name$suffix")
914         and return 1;
915     }
916   }
917
918   return;
919 }
920
921 sub usage {
922   print STDERR <<EOS;
923 Usage: $0 [--enable feature1,feature2,...] [other options]
924        $0 [--disable feature1,feature2,...]  [other options]
925        $0 --help
926 Possible feature names are:
927   png gif ungif jpeg tiff T1-fonts TT-fonts freetype2
928 Other options:
929   --verbose | -v
930     Verbose library probing (or set IM_VERBOSE in the environment)
931   --nolog
932     Disable logging (or set IM_NOLOG in the environment)
933   --incpath dir
934     Add to the include search path
935   --libpath dir
936     Add to the library search path
937 EOS
938   exit 1;
939
940 }
941
942 # generate the PM MM argument
943 # I'd prefer to modify the public version, but there doesn't seem to be 
944 # a public API to do that
945 sub gen_PM {
946   my %pm;
947   my $instbase = '$(INST_LIBDIR)';
948
949   # first the basics, .pm and .pod files
950   $pm{"Imager.pm"} = "$instbase/Imager.pm";
951
952   my $mani = maniread();
953
954   for my $filename (keys %$mani) {
955     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
956       (my $work = $filename) =~ s/^lib//;
957       $pm{$filename} = $instbase . $work;
958     }
959   }
960
961   # need the typemap
962   $pm{typemap} = $instbase . '/Imager/typemap';
963
964   # and the core headers
965   for my $filename (keys %$mani) {
966     if ($filename =~ /^\w+\.h$/) {
967       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
968     }
969   }
970
971   # and the generated header
972   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
973
974   \%pm;
975 }
976
977 my $home;
978 sub _tilde_expand {
979   my ($path) = @_;
980
981   if ($path =~ m!^~[/\\]!) {
982     defined $home or $home = $ENV{HOME};
983     if (!defined $home && $^O eq 'MSWin32'
984        && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
985       $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
986     }
987     unless (defined $home) {
988       $home = eval { (getpwuid($<))[7] };
989     }
990     defined $home or die "You supplied $path, but I can't find your home directory\n";
991     $path =~ s/^~//;
992     $path = File::Spec->catdir($home, $path);
993   }
994
995   $path;
996 }
997
998 sub postcheck_tiff {
999   my ($format, $frm) = @_;
1000
1001   -d "probe" or mkdir "probe";
1002
1003   my $tiffver_name = "probe/tiffver.txt";
1004
1005   my $lib;
1006   if ($Config{cc} =~ /\b(cl|bcc)\b/) {
1007     $lib = "libtiff";
1008   }
1009   else {
1010     $lib = "tiff";
1011   }
1012
1013   my $good =
1014     eval {
1015       assert_lib
1016         (
1017          debug => $VERBOSE,
1018          incpath => $format->{incdir},
1019          libpath => $format->{libdir},
1020          lib => $lib,
1021          header => [ qw(stdio.h tiffio.h) ],
1022          function => <<FUNCTION,
1023   {
1024     const char *vers = TIFFGetVersion();
1025     FILE *f = fopen("$tiffver_name", "wb");
1026     if (!f)
1027       return 1;
1028     fputs(vers, f);
1029     if (fclose(f))
1030       return 1;
1031     return 0;
1032   }
1033 FUNCTION
1034         );
1035       1;
1036     };
1037
1038   unless ($good && -s $tiffver_name
1039           && open(VERS, "< probe/tiffver.txt")) {
1040     unlink $tiffver_name unless $KEEP_FILES;
1041     print <<EOS;
1042     **tiff: cannot determine libtiff version number
1043       tiff: DISABLED
1044 EOS
1045     return;
1046   }
1047
1048   # version file seems to be there, load it up
1049   my $ver_str = do { local $/; <VERS> };
1050   close VERS;
1051   unlink $tiffver_name unless $KEEP_FILES;
1052
1053   my ($version) = $ver_str =~ /(\d+\.\d+\.\d+)/;
1054
1055   if ($version eq '3.9.0') {
1056     print <<EOS;
1057     **tiff: libtiff 3.9.0 introduced a serious bug, please install 3.9.1
1058       tiff: DISABLED
1059 EOS
1060     return;
1061   }
1062
1063   return 1;
1064 }
1065
1066 # This isn't a module, but some broken tools, like
1067 # Module::Depends::Instrusive insist on treating it like one.
1068 #
1069 # http://rt.cpan.org/Public/Bug/Display.html?id=21229
1070
1071 1;