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