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