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