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