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