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