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