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