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