switch to using size_t and i_img_dim strictly
[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} > 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 EOS
747   }
748
749   print CONFIG <<EOS;
750 /*
751  Type and format code for formatted output as with printf.
752
753  This is intended for formatting i_img_dim values.
754 */
755 typedef $Config{ivtype} i_dim_format_t;
756 #define i_DF $Config{ivdformat}
757 EOS
758
759   print CONFIG "\n#endif\n";
760   close CONFIG;
761 }
762
763 # # use pkg-config to probe for libraries
764 # # works around the junk that pkg-config dumps on FreeBSD
765 # sub _pkg_probe {
766 #   my ($pkg) = @_;
767
768 #   is_exe('pkg-config') or return;
769
770 #   my $redir = $^O eq 'MSWin32' ? '' : '2>/dev/null';
771
772 #   !system("pkg-config $pkg --exists $redir");
773 # }
774
775 # probes for freetype1 by scanning @incs for the includes and 
776 # @libs for the libs.  This is done separately because freetype's headers
777 # are stored in a freetype or freetype1 directory under PREFIX/include.
778 #
779 # we could find the files with the existing mechanism, but it won't set
780 # -I flags correctly.
781 #
782 # This could be extended to freetype2 too, but freetype-config catches
783 # that
784 sub freetype1_probe {
785   my ($frm, $frmkey) = @_;
786
787   my $found_inc;
788  INCS:
789   for my $inc (@incs) {
790     for my $subdir (qw/freetype freetype1/) {
791       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
792       -e $path or next;
793       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
794       -e $path and next;
795
796       $found_inc = File::Spec->catdir($inc, $subdir);
797       last INCS;
798     }
799   }
800
801   my $found_lib;
802  LIBS:
803   for my $lib (@libs) {
804     my $a_path = File::Spec->catfile($lib, "libttf$aext");
805     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
806     if (-e $a_path || -e $l_path) {
807       $found_lib = $lib;
808       last LIBS;
809     }
810   }
811
812   return unless $found_inc && $found_lib;
813   printf("%10s: includes %s - libraries %s\n", $frmkey,
814          ($found_inc ? 'found' : 'not found'), 
815          ($found_lib ? 'found' : 'not found'));
816
817   $frm->{cflags} = "-I$found_inc";
818   $frm->{libfiles} = "-lttf";
819
820   return 1;
821 }
822
823 # probes for freetype2 by trying to run freetype-config
824 # sub freetype2_probe_ftconfig {
825 #   my ($frm, $frmkey) = @_;
826
827 #   is_exe('freetype-config') or return;
828
829 #   my $cflags = `freetype-config --cflags`
830 #     and !$? or return;
831 #   chomp $cflags;
832
833 #   my $lflags = `freetype-config --libs`
834 #     and !$? or return;
835 #   chomp $lflags;
836
837 #   # before 2.1.5 freetype-config --cflags could output
838 #   # the -I options in the wrong order, causing a conflict with
839 #   # freetype1.x installed with the same --prefix
840 #   #
841 #   # can happen iff:
842 #   #  - both -Iprefix/include and -Iprefix/include/freetype2 are in cflags
843 #   #    in that order
844 #   #  - freetype 1.x headers are in prefix/include/freetype
845 #   my @incdirs = map substr($_, 2), grep /^-I/, split ' ', $cflags;
846 #   if (@incdirs == 2 
847 #       && $incdirs[1] eq "$incdirs[0]/freetype2"
848 #       && -e "$incdirs[0]/freetype/freetype.h"
849 #       && -e "$incdirs[0]/freetype/fterrid.h") {
850 #     print "** freetype-config provided -I options out of order, correcting\n"
851 #       if $VERBOSE;
852 #     $cflags = join(' ', grep(!/-I/, split ' ', $cflags),
853 #                  map "-I$_", reverse @incdirs);
854 #   }
855 #   $frm->{cflags} = $cflags;
856 #   $frm->{lflags} = $lflags;
857
858 #   printf "%10s: configured via freetype-config\n", $frmkey;
859
860 #   return 1;
861 # }
862
863 # attempt to probe for freetype2 by scanning directories
864 # we can't use the normal scan since we need to find the directory
865 # containing most of the includes
866 # sub freetype2_probe_scan {
867 #   my ($frm, $frmkey) = @_;
868
869 #   my $found_inc;
870 #   my $found_inc2;
871 #  INCS:
872 #   for my $inc (@incs) {
873 #     my $path = File::Spec->catfile($inc, 'ft2build.h');
874 #     -e $path or next;
875
876 #     # try to find what it's including
877 #     my $ftheader;
878 #     open FT2BUILD, "< $path"
879 #       or next;
880 #     while (<FT2BUILD>) {
881 #       if (m!^\s*\#\s*include\s+<([\w/.]+)>!
882 #         || m!^\s*\#\s*include\s+"([\w/.]+)"!) {
883 #       $ftheader = $1;
884 #       last;
885 #       }
886 #     }
887 #     close FT2BUILD;
888 #     $ftheader
889 #       or next;
890 #     # non-Unix installs put this directly under the same directory in
891 #     # theory
892 #     if (-e File::Spec->catfile($inc, $ftheader)) {
893 #       $found_inc = $inc;
894 #       last INCS;
895 #     }
896 #     for my $subdir (qw/freetype2 freetype/) {
897 #       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
898 #       -e $path and next;
899
900 #       $found_inc = $inc;
901 #       $found_inc2 = File::Spec->catdir($inc, $subdir);
902 #       last INCS;
903 #     }
904 #   }
905
906 #   my $found_lib;
907 #  LIBS:
908 #   for my $lib (@libs) {
909 #     my $a_path = File::Spec->catfile($lib, "libfreetype$aext");
910 #     my $l_path = File::Spec->catfile($lib, "libfreetype.$lext");
911 #     if (-e $a_path || -e $l_path) {
912 #       $found_lib = $lib;
913 #       last LIBS;
914 #     }
915 #   }
916
917 #   printf("%10s: includes %s - libraries %s\n", $frmkey,
918 #        ($found_inc ? 'found' : 'not found'), 
919 #        ($found_lib ? 'found' : 'not found'));
920
921 #   return unless $found_inc && $found_lib;
922
923 #   $frm->{cflags} = _make_I($found_inc);
924 #   $frm->{cflags} .= " " . _make_I($found_inc2) if $found_inc2;
925 #   $frm->{libfiles} = "-lfreetype";
926
927 #   return 1;
928 # }
929
930 sub _make_I {
931   my ($inc_dir) = @_;
932
933   $definc{$inc_dir}
934     and return '';
935
936   $inc_dir =~ / / ? qq!-I"$inc_dir"! : "-I$inc_dir";
937 }
938
939 # probes for libpng via pkg-config
940 # sub png_probe {
941 #   my ($frm, $frmkey) = @_;
942
943 #   is_exe('pkg-config') or return;
944
945 #   my $config;
946 #   for my $check_conf (qw(libpng libpng12 libpng10)) {
947 #     if (_pkg_probe($check_conf)) {
948 #       $config = $check_conf;
949 #       last;
950 #     }
951 #   }
952 #   $config or return;
953
954 #   my $cflags = `pkg-config $config --cflags`
955 #     and !$? or return;
956
957 #   my $lflags = `pkg-config $config --libs`
958 #     and !$? or return;
959
960 #   chomp $cflags;
961 #   chomp $lflags;
962 #   $frm->{cflags} = $cflags;
963 #   $frm->{lflags} = $lflags;
964
965 #   printf "%10s: configured via `pkg-config $config ...`\n", $frmkey;
966
967 #   return 1;
968 # }
969
970 sub catfile {
971   return File::Spec->catfile(@_);
972 }
973
974 # sub is_exe {
975 #   my ($name) = @_;
976
977 #   my @exe_suffix = $Config{_exe};
978 #   if ($^O eq 'MSWin32') {
979 #     push @exe_suffix, qw/.bat .cmd/;
980 #   }
981
982 #   for my $dir (File::Spec->path) {
983 #     for my $suffix (@exe_suffix) {
984 #       -x catfile($dir, "$name$suffix")
985 #       and return 1;
986 #     }
987 #   }
988
989 #   return;
990 # }
991
992 sub usage {
993   print STDERR <<EOS;
994 Usage: $0 [--enable feature1,feature2,...] [other options]
995        $0 [--disable feature1,feature2,...]  [other options]
996        $0 --help
997 Possible feature names are:
998   T1-fonts TT-fonts freetype2
999 Other options:
1000   --verbose | -v
1001     Verbose library probing (or set IM_VERBOSE in the environment)
1002   --nolog
1003     Disable logging (or set IM_NOLOG in the environment)
1004   --incpath dir
1005     Add to the include search path
1006   --libpath dir
1007     Add to the library search path
1008   --coverage
1009     Build for coverage testing.
1010   --assert
1011     Build with assertions active.
1012 EOS
1013   exit 1;
1014
1015 }
1016
1017 # generate the PM MM argument
1018 # I'd prefer to modify the public version, but there doesn't seem to be 
1019 # a public API to do that
1020 sub gen_PM {
1021   my %pm;
1022   my $instbase = '$(INST_LIBDIR)';
1023
1024   # first the basics, .pm and .pod files
1025   $pm{"Imager.pm"} = "$instbase/Imager.pm";
1026
1027   my $mani = maniread();
1028
1029   for my $filename (keys %$mani) {
1030     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
1031       (my $work = $filename) =~ s/^lib//;
1032       $pm{$filename} = $instbase . $work;
1033     }
1034   }
1035
1036   # need the typemap
1037   $pm{typemap} = $instbase . '/Imager/typemap';
1038
1039   # and the core headers
1040   for my $filename (keys %$mani) {
1041     if ($filename =~ /^\w+\.h$/) {
1042       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
1043     }
1044   }
1045
1046   # and the generated header
1047   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
1048
1049   \%pm;
1050 }
1051
1052 my $home;
1053 sub _tilde_expand {
1054   my ($path) = @_;
1055
1056   if ($path =~ m!^~[/\\]!) {
1057     defined $home or $home = $ENV{HOME};
1058     if (!defined $home && $^O eq 'MSWin32'
1059        && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
1060       $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
1061     }
1062     unless (defined $home) {
1063       $home = eval { (getpwuid($<))[7] };
1064     }
1065     defined $home or die "You supplied $path, but I can't find your home directory\n";
1066     $path =~ s/^~//;
1067     $path = File::Spec->catdir($home, $path);
1068   }
1069
1070   $path;
1071 }
1072
1073 # sub postcheck_tiff {
1074 #   my ($format, $frm) = @_;
1075
1076 #   -d "probe" or mkdir "probe";
1077
1078 #   my $tiffver_name = "probe/tiffver.txt";
1079
1080 #   my $lib;
1081 #   if ($Config{cc} =~ /\b(cl|bcc)\b/) {
1082 #     $lib = "libtiff";
1083 #   }
1084 #   else {
1085 #     $lib = "tiff";
1086 #   }
1087
1088 #   # setup LD_RUN_PATH to match link time
1089 #   my $lopts = join " " , map("-L$_", @{$format->{libdir}}), " -ltiff";
1090 #   my ($extra, $bs_load, $ld_load, $ld_run_path) =
1091 #     ExtUtils::Liblist->ext($lopts, $VERBOSE);
1092 #   local $ENV{LD_RUN_PATH};
1093
1094 #   if ($ld_run_path) {
1095 #     print "Setting LD_RUN_PATH=$ld_run_path for TIFF probe\n" if $VERBOSE;
1096 #     $ENV{LD_RUN_PATH} = $ld_run_path;
1097 #   }
1098
1099 #   my $good =
1100 #     eval {
1101 #       assert_lib
1102 #       (
1103 #        debug => $VERBOSE,
1104 #        incpath => $format->{incdir},
1105 #        libpath => $format->{libdir},
1106 #        lib => $lib,
1107 #        header => [ qw(stdio.h tiffio.h) ],
1108 #        function => <<FUNCTION,
1109 #   {
1110 #     const char *vers = TIFFGetVersion();
1111 #     FILE *f = fopen("$tiffver_name", "wb");
1112 #     if (!f)
1113 #       return 1;
1114 #     fputs(vers, f);
1115 #     if (fclose(f))
1116 #       return 1;
1117 #     return 0;
1118 #   }
1119 # FUNCTION
1120 #       );
1121 #       1;
1122 #     };
1123
1124 #   unless ($good && -s $tiffver_name
1125 #         && open(VERS, "< $tiffver_name")) {
1126 #     unlink $tiffver_name unless $KEEP_FILES;
1127 #     print <<EOS;
1128 #     **tiff: cannot determine libtiff version number
1129 #       tiff: DISABLED
1130 # EOS
1131 #     return;
1132 #   }
1133
1134 #   # version file seems to be there, load it up
1135 #   my $ver_str = do { local $/; <VERS> };
1136 #   close VERS;
1137 #   unlink $tiffver_name unless $KEEP_FILES;
1138
1139 #   my ($version) = $ver_str =~ /(\d+\.\d+\.\d+)/;
1140
1141 #   if ($version eq '3.9.0') {
1142 #     print <<EOS;
1143 #     **tiff: libtiff 3.9.0 introduced a serious bug, please install 3.9.1
1144 #       tiff: DISABLED
1145 # EOS
1146 #     return;
1147 #   }
1148
1149 #   return 1;
1150 # }
1151
1152 # This isn't a module, but some broken tools, like
1153 # Module::Depends::Instrusive insist on treating it like one.
1154 #
1155 # http://rt.cpan.org/Public/Bug/Display.html?id=21229
1156
1157 1;