more verbose probe output
[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 # make sure --verbose will dump environment settings
40 if (grep $_ =~ /^--?v(?:erbose)?$/, @ARGV) {
41   $VERBOSE = 1;
42 }
43
44 getenv();     # get environment variables
45
46 my $lext=$Config{'so'};   # Get extensions of libraries
47 my $aext=$Config{'_a'};
48
49 my $help; # display help if set
50 my @enable; # list of drivers to enable
51 my @disable; # or list of drivers to disable
52 my @incpaths; # places to look for headers
53 my @libpaths; # places to look for libraries
54 my $coverage; # build for coverage testing
55 my $assert; # build with assertions
56 my $trace_context; # trace context management to stderr
57 GetOptions("help" => \$help,
58            "enable=s" => \@enable,
59            "disable=s" => \@disable,
60            "incpath=s", \@incpaths,
61            "libpath=s" => \@libpaths,
62            "verbose|v" => \$VERBOSE,
63            "nolog" => \$NOLOG,
64            'coverage' => \$coverage,
65            "assert|a" => \$assert,
66            "tracecontext" => \$trace_context);
67
68 setenv();
69
70 if ($ENV{AUTOMATED_TESTING}) {
71   $assert = 1;
72 }
73
74 if ($VERBOSE) { 
75   print "Verbose mode\n"; 
76   require Data::Dumper; 
77   import Data::Dumper qw(Dumper);
78 }
79
80 if ($help) {
81   usage();
82 }
83
84 my @defines;
85
86 if ($NOLOG)   { print "Logging not compiled into module\n"; }
87 else { 
88   push @defines, [ IMAGER_LOG => 1, "Logging system" ];
89 }
90
91 if ($assert) {
92   push @defines, [ IM_ASSERT => 1, "im_assert() are effective" ];
93 }
94
95 if ($DEBUG_MALLOC) {
96   push @defines, [ IMAGER_DEBUG_MALLOC => 1, "Use Imager's DEBUG malloc()" ];
97   print "Malloc debugging enabled\n";
98 }
99
100 if (@enable && @disable) {
101   print STDERR "Only --enable or --disable can be used, not both, try --help\n";
102   exit 1;
103 }
104
105 my %definc;
106 my %deflib;
107 my @incs; # all the places to look for headers
108 my @libs; # all the places to look for libraries
109
110 init();       # initialize global data
111 pathcheck();  # Check if directories exist
112
113 if (exists $ENV{IM_ENABLE}) {
114   my %en = map { $_, 1 } split ' ', $ENV{IM_ENABLE};
115   for my $key (keys %formats) {
116     delete $formats{$key} unless $en{$key};
117   }
118 }
119 if (@enable) {
120   my %en = map { $_ => 1 } map { split /,/ } @enable;
121   for my $key (keys %formats) {
122     delete $formats{$key} unless $en{$key};
123   }
124 }
125 elsif (@disable) {
126   delete @formats{map { split /,/ } @disable};
127 }
128
129 # Pick what libraries are used
130 if ($MANUAL) {
131   manual();
132 } else {
133   automatic();
134 }
135
136 my $lib_cflags = '';
137 my $lib_lflags = '';
138 my $F_LIBS = '';
139 my $F_OBJECT = '';
140 for my $frmkey (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
141   my $frm = $formats{$frmkey};
142   push @defines, [ $frm->{def}, 1, "$frmkey available" ];
143   $F_OBJECT .= ' '  .$frm->{objfiles};
144   if ($frm->{cflags}) {
145     $lib_cflags   .= ' '  .$frm->{cflags};
146     ++$definc{$_} for map { /^-I(.*)$/ ? ($1) : () }
147       grep /^-I./, split ' ', $frm->{cflags};
148   }
149   if ($frm->{lflags}) {
150     $lib_lflags .= ' ' . $frm->{lflags};
151   }
152   else {
153     $F_LIBS   .= ' '  .$frm->{libfiles};
154   }
155
156 }
157
158 my $F_INC  = join ' ', map "-I$_", map / / ? qq{"$_"} : $_, 
159   grep !$definc{$_}, @incs;
160 $F_LIBS = join(' ',map "-L$_", map / / ? qq{"$_"} : $_, 
161                grep !$deflib{$_}++, @libs) . $F_LIBS;
162
163 my $OSLIBS = '';
164 my $OSDEF  = "-DOS_$^O";
165
166 if ($^O eq 'hpux')                { $OSLIBS .= ' -ldld'; }
167 if (defined $Config{'d_dlsymun'}) { $OSDEF  .= ' -DDLSYMUN'; }
168
169 my @objs = qw(Imager.o context.o draw.o polygon.o image.o io.o iolayer.o
170               log.o gaussian.o conv.o pnm.o raw.o feat.o combine.o
171               filters.o dynaload.o stackmach.o datatypes.o
172               regmach.o trans2.o quant.o error.o convert.o
173               map.o tags.o palimg.o maskimg.o img8.o img16.o rotate.o
174               bmp.o tga.o color.o fills.o imgdouble.o limits.o hlines.o
175               imext.o scale.o rubthru.o render.o paste.o compose.o flip.o
176               perlio.o);
177
178 if ($Config{useithreads}) {
179   if ($Config{i_pthread}) {
180     print "POSIX threads\n";
181     push @objs, "mutexpthr.o";
182   }
183   elsif ($^O eq 'MSWin32') {
184     print "Win32 threads\n";
185     push @objs, "mutexwin.o";
186   }
187   else {
188     print "Unsupported threading model\n";
189     push @objs, "mutexnull.o";
190     if ($ENV{AUTOMATED_TESTING}) {
191       die "OS unsupported: no threading support code for this platform\n";
192     }
193   }
194 }
195 else {
196   print "No threads\n";
197   push @objs, "mutexnull.o";
198 }
199
200 my @typemaps = qw(typemap.local typemap);
201 if ($] < 5.008) {
202     unshift @typemaps, "typemap.oldperl";
203 }
204
205 if ($trace_context) {
206   $CFLAGS .= " -DIMAGER_TRACE_CONTEXT";
207 }
208
209 my $tests = 't/*.t t/*/*.t';
210 if (-d "xt" && scalar(() = glob("xt/*.t"))) {
211   $tests .= " xt/*.t";
212 }
213
214 my %opts=
215   (
216    'NAME'         => 'Imager',
217    'VERSION_FROM' => 'Imager.pm',
218    'LIBS'         => "$LFLAGS -lm $lib_lflags $OSLIBS $F_LIBS",
219    'DEFINE'       => "$OSDEF $CFLAGS",
220    'INC'          => "$lib_cflags $DFLAGS $F_INC",
221    'OBJECT'       => join(' ', @objs, $F_OBJECT),
222    clean          => { FILES=>'testout rubthru.c scale.c conv.c  filters.c gaussian.c render.c rubthru.c' },
223    PM             => gen_PM(),
224    PREREQ_PM      =>
225    { 
226     'Test::More' => 0.47,
227     'Scalar::Util' => 1.00,
228     'XSLoader'    => 0,
229    },
230    TYPEMAPS       => \@typemaps,
231    test =>        { TESTS => $tests },
232   );
233
234 if ($coverage) {
235     if ($Config{gccversion}) {
236         push @ARGV, 'OPTIMIZE=-ftest-coverage -fprofile-arcs -g';
237         $opts{dynamic_lib} = { OTHERLDFLAGS => '-ftest-coverage -fprofile-arcs' };
238     }
239     else {
240         die "Don't know the coverage C flags for your compiler\n";
241     }
242 }
243
244 # eval to prevent warnings about versions with _ in them
245 my $MM_ver = eval $ExtUtils::MakeMaker::VERSION;
246 if ($MM_ver > 6.06) {
247   $opts{AUTHOR} = 'Tony Cook <tonyc@cpan.org>, Arnar M. Hrafnkelsson';
248   $opts{ABSTRACT} = 'Perl extension for Generating 24 bit Images';
249 }
250
251 if ($MM_ver >= 6.46) {
252   $opts{META_MERGE} =
253     {
254      recommends =>
255      {
256       "Parse::RecDescent" => 0
257      },
258      license => "perl",
259      dynamic_config => 1,
260      no_index =>
261      {
262       directory =>
263       [
264        "PNG",
265        "GIF",
266        "TIFF",
267        "JPEG",
268        "W32",
269        "FT2",
270        "T1",
271       ],
272      },
273      resources =>
274      {
275       homepage => "http://imager.perl.org/",
276       repository => "git://git.imager.perl.org/imager.git",
277       bugtracker => "http://rt.cpan.org/NoAuth/Bugs.html?Dist=Imager",
278      },
279     };
280 }
281
282 make_imconfig(\@defines);
283
284 if ($VERBOSE) { print Dumper(\%opts); }
285 mkdir('testout',0777); # since we cannot include it in the archive.
286
287 -d "probe" and rmdir "probe";
288
289 WriteMakefile(%opts);
290
291 my @good;
292 my @bad;
293 for my $name (sort { lc $a cmp lc $b } keys %IMAGER_LIBS) {
294   if ($IMAGER_LIBS{$name}) {
295     push @good, $name;
296   }
297   else {
298     push @bad, $name;
299   }
300 }
301
302 print "\n";
303 print "Libraries found:\n" if @good;
304 print "  $_\n" for @good;
305 print "Libraries *not* found:\n" if @bad;
306 print "  $_\n" for @bad;
307
308 exit;
309
310
311 sub MY::postamble {
312     my $self = shift;
313     my $perl = $self->{PERLRUN} ? '$(PERLRUN)' : '$(PERL)';
314     my $mani = maniread;
315
316     my @ims = grep /\.im$/, keys %$mani;
317 '
318 dyntest.$(MYEXTLIB) : dynfilt/Makefile
319         cd dynfilt && $(MAKE) $(PASTHRU)
320
321 lib/Imager/Regops.pm : regmach.h regops.perl
322         $(PERL) regops.perl regmach.h lib/Imager/Regops.pm
323
324 imconfig.h : Makefile.PL
325         $(ECHO) "imconfig.h out-of-date with respect to $?"
326         $(PERLRUN) Makefile.PL
327         $(ECHO) "==> Your Makefile has been rebuilt - re-run your make command <=="
328 '.qq!
329 lib/Imager/APIRef.pod : \$(C_FILES) \$(H_FILES) apidocs.perl
330         $perl apidocs.perl lib/Imager/APIRef.pod
331
332 !.join('', map _im_rule($perl, $_), @ims)
333
334 }
335
336 sub _im_rule {
337   my ($perl, $im) = @_;
338
339   (my $c = $im) =~ s/\.im$/.c/;
340   return <<MAKE;
341
342 $c: $im lib/Imager/Preprocess.pm
343         $perl -Ilib -MImager::Preprocess -epreprocess $im $c
344
345 MAKE
346
347 }
348
349 # manual configuration of helper libraries
350
351 sub manual {
352   print <<EOF;
353
354       Please answer the following questions about
355       which formats are avaliable on your computer
356
357 press <return> to continue
358 EOF
359
360   <STDIN>; # eat one return
361
362   for my $frm(sort { $formats{$b}{order} <=> $formats{$a}{order} } keys %formats) {
363   SWX:
364     if ($formats{$frm}{docs}) { print "\n",$formats{$frm}{docs},"\n\n"; }
365     print "Enable $frm support: ";
366     my $gz = <STDIN>;
367     chomp($gz);
368     if ($gz =~ m/^(y|yes|n|no)/i) {
369       $gz=substr(lc($gz),0,1);
370       if ($gz eq 'n') {
371         delete $formats{$frm};
372       }
373     } else { goto SWX; }
374   }
375 }
376
377
378 # automatic configuration of helper libraries
379
380 sub automatic {
381   print "Automatic probing:\n" if $VERBOSE;
382   for my $frm (sort { $formats{$a}{order} <=> $formats{$b}{order} } keys %formats) {
383     delete $formats{$frm} if !checkformat($frm);        
384   }
385 }
386
387 sub grep_directory {
388   my($path, $chk)=@_;
389
390 #    print "checking path $path\n";
391   if ( !opendir(DH,$path) ) {
392     warn "Cannot open dir $path: $!\n";
393     return;
394   }
395   my @l=grep { $chk->($_) } readdir(DH);
396   #    print @l;
397   close(DH);
398   return map $path, @l;
399 }
400
401 sub _probe_default {
402   my ($format, $frm) = @_;
403
404   my $lib_check=$formats{$frm}{'libcheck'};
405   my $inc_check=$formats{$frm}{'inccheck'};
406
407   if ($lib_check) {
408     my @l;
409     for my $lp (@libs) {
410       push(@l, grep_directory($lp,$lib_check));
411     }
412     
413     my @i;
414     for my $ip (@incs) {
415       push(@i, $ip) if $inc_check->($ip,$frm);
416     }
417     
418     printf("%10s: includes %s - libraries %s\n",$frm,(@i?'found':'not found'),(@l?'found':'not found'));
419     $formats{$frm}{incdir} = \@i;
420     $formats{$frm}{libdir} = \@l;
421     return 1 if scalar(@i && @l);
422   }
423   else {
424     printf("%10s: not available\n", $frm);
425   }
426
427   return 0;
428 }
429
430 sub checkformat {
431   my $frm=shift;
432
433   print "  checkformat($frm)\n" if $VERBOSE;
434   
435   my $format = $formats{$frm};
436
437   my @probes;
438   if (my $code = $format->{'code'}) {
439     if (ref $code eq 'ARRAY') {
440       push @probes, @$code;
441     }
442     else {
443       push @probes, $code;
444     }
445   }
446   push @probes, \&_probe_default;
447
448   print "    Calling probe function\n" if $VERBOSE;
449   my $found;
450   for my $func (@probes) {
451     if ($func->($format, $frm)) {
452       ++$found;
453       last;
454     }
455   }
456
457   $found or return;
458
459   if ($format->{postcheck}) {
460     print "    Calling postcheck function\n" if $VERBOSE;
461     $format->{postcheck}->($format, $frm)
462       or return;
463   }
464
465   return 1;
466 }
467
468
469 sub pathcheck {
470   if ($VERBOSE) {
471     print "pathcheck\n";
472     print "  Include paths:\n";
473     for (@incs) { print $_,"\n"; }
474   }
475   @incs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @incs;
476
477   if ($VERBOSE) {
478     print "\nLibrary paths:\n";
479     for (@libs) { print $_,"\n"; }
480   }
481   @libs=grep { -d $_ && -r _ && -x _ or ( print("  $_ doesnt exist or is unaccessible - removed.\n"),0) } @libs;
482   print "\ndone.\n";
483 }
484
485
486 # Format data initialization
487
488 # format definition is:
489 # defines needed
490 # default include path
491 # files needed for include (boolean perl code)
492 # default lib path
493 # libs needed
494 # files needed for link (boolean perl code)
495 # object files needed for the format
496
497
498 sub init {
499
500   my @definc = qw(/usr/include);
501   @definc{@definc}=(1) x @definc;
502   @incs=
503     (
504      split(/\Q$Config{path_sep}/, $INCPATH),
505      map _tilde_expand($_), map { split /\Q$Config{path_sep}/ } @incpaths 
506     );
507   if ($Config{locincpth}) {
508     push @incs, grep -d, split ' ', $Config{locincpth};
509   }
510   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
511     push(@incs, split /;/, $ENV{INCLUDE}) if exists $ENV{INCLUDE};
512   }
513   if ($Config{incpath}) {
514     push @incs, grep -d, split /\Q$Config{path_sep}/, $Config{incpath};
515   }
516   push @incs, grep -d,
517       qw(/sw/include 
518          /usr/include/freetype2
519          /usr/local/include/freetype2
520          /usr/local/include/freetype1/freetype
521          /usr/include /usr/local/include /usr/include/freetype
522          /usr/local/include/freetype);
523   if ($Config{ccflags}) {
524     my @hidden = map { /^-I(.*)$/ ? ($1) : () } split ' ', $Config{ccflags};
525     push @incs, @hidden;
526     @definc{@hidden} = (1) x @hidden;
527   }
528
529   @libs= ( split(/\Q$Config{path_sep}/,$LIBPATH),
530     map _tilde_expand($_), map { split /\Q$Config{path_sep}/} @libpaths );
531   if ($Config{loclibpth}) {
532     push @libs, grep -d, split ' ', $Config{loclibpth};
533   }
534   
535   push @libs, grep -d, qw(/sw/lib),  split(/ /, $Config{'libpth'});
536   push @libs, grep -d, split / /, $Config{libspath} if $Config{libspath};
537   if ($^O =~ /win32/i && $Config{cc} =~ /\bcl\b/i) {
538     push(@libs, split /;/, $ENV{LIB}) if exists $ENV{LIB};
539   }
540   if ($^O eq 'cygwin') {
541     push(@libs, '/usr/lib/w32api') if -d '/usr/lib/w32api';
542     push(@incs, '/usr/include/w32api') if -d '/usr/include/w32api';
543   }
544   if ($Config{ldflags}) {
545     # some builds of perl put -Ldir into ldflags without putting it in
546     # loclibpth, let's extract them
547     my @hidden = grep -d, map { /^-L(.*)$/ ? ($1) : () }
548       split ' ', $Config{ldflags};
549     push @libs, @hidden;
550     # don't mark them as seen - EU::MM will remove any libraries
551     # it can't find and it doesn't look for -L in ldflags
552     #@deflib{@hidden} = @hidden;
553   }
554   push @libs, grep -d, qw(/usr/local/lib);
555
556   $formats{'TT-fonts'}=
557     {
558      order=>'31',
559      def=>'HAVE_LIBTT',
560      inccheck=>sub { -e catfile($_[0], 'freetype.h')
561                        && !-e catfile($_[0], 'fterrors.h') },
562      libcheck=>sub { $_[0] eq "libttf$aext" or $_[0] eq "libttf.$lext" },
563      libfiles=>'-lttf',
564      objfiles=>'fontft1.o',
565      code => \&freetype1_probe,
566      docs=>q{
567 Truetype fonts are scalable fonts. They can include 
568 kerning and hinting information and generally yield good
569 visual quality esp on low resultions. The freetype library is
570 used to rasterize for us. The only drawback is that there
571 are alot of badly designed fonts out there.
572
573 This driver uses Freetype 1.x which is obsolete}
574                        };
575   # Make fix indent
576   for (keys %formats) { $formats{$_}->{docs} =~ s/^\s+/  /mg; }
577 }
578
579
580
581 sub gen {
582   my $V = $ENV{$_[0]};
583   print "  $_[0]: '$V'\n"
584       if $VERBOSE && defined $V;
585   defined($V) ? $V : "";
586 }
587
588
589 # Get information from environment variables
590
591 sub getenv {
592
593   $VERBOSE ||= gen("IM_VERBOSE");
594
595   print "Environment config:\n" if $VERBOSE;
596
597   ($INCPATH,
598    $LIBPATH,
599    $NOLOG,
600    $DEBUG_MALLOC,
601    $MANUAL,
602    $CFLAGS,
603    $LFLAGS,
604    $DFLAGS) = map { gen $_ } qw(IM_INCPATH
605                                 IM_LIBPATH
606                                 IM_NOLOG
607                                 IM_DEBUG_MALLOC
608                                 IM_MANUAL
609                                 IM_CFLAGS
610                                 IM_LFLAGS
611                                 IM_DFLAGS);
612 }
613
614 # populate the environment so that sub-modules get the same info
615 sub setenv {
616   $ENV{IM_VERBOSE} = 1 if $VERBOSE;
617   $ENV{IM_INCPATH} = join $Config{path_sep}, @incpaths if @incpaths;
618   $ENV{IM_LIBPATH} = join $Config{path_sep}, @libpaths if @libpaths;
619 }
620
621 sub make_imconfig {
622   my ($defines) = @_;
623
624   open CONFIG, "> imconfig.h"
625     or die "Cannot create imconfig.h: $!\n";
626   print CONFIG <<EOS;
627 /* This file is automatically generated by Makefile.PL.
628    Don't edit this file, since any changes will be lost */
629
630 #ifndef IMAGER_IMCONFIG_H
631 #define IMAGER_IMCONFIG_H
632 EOS
633   for my $define (@$defines) {
634     if ($define->[2]) {
635       print CONFIG "\n/*\n  $define->[2]\n*/\n\n";
636     }
637     print CONFIG "#define $define->[0] $define->[1]\n";
638   }
639   if ($Config{gccversion} && $Config{gccversion} =~ /^([0-9]+)/ && $1 > 3) {
640     print CONFIG <<EOS;
641 /*
642
643 Compiler supports the GCC __attribute__((format...)) syntax.
644
645 */
646
647 #define IMAGER_FORMAT_ATTR 1
648
649 EOS
650   }
651
652   if ($Config{d_snprintf}) {
653     print CONFIG <<EOS;
654 /* We can use snprintf() */
655 #define IMAGER_SNPRINTF 1
656
657 EOS
658   }
659
660   if ($Config{d_vsnprintf}) {
661     print CONFIG <<EOS;
662 /* We can use vsnprintf() */
663 #define IMAGER_VSNPRINTF 1
664
665 EOS
666   }
667
668   print CONFIG <<EOS;
669 /*
670  Type and format code for formatted output as with printf.
671
672  This is intended for formatting i_img_dim values.
673 */
674 typedef $Config{ivtype} i_dim_format_t;
675 #define i_DF $Config{ivdformat}
676 EOS
677
678   print CONFIG "\n#endif\n";
679   close CONFIG;
680 }
681
682 # probes for freetype1 by scanning @incs for the includes and 
683 # @libs for the libs.  This is done separately because freetype's headers
684 # are stored in a freetype or freetype1 directory under PREFIX/include.
685 #
686 # we could find the files with the existing mechanism, but it won't set
687 # -I flags correctly.
688 #
689 # This could be extended to freetype2 too, but freetype-config catches
690 # that
691 sub freetype1_probe {
692   my ($frm, $frmkey) = @_;
693
694   my $found_inc;
695  INCS:
696   for my $inc (@incs) {
697     for my $subdir (qw/freetype freetype1/) {
698       print "TT: include check ", File::Spec->catdir($inc, $subdir), "\n"
699         if $VERBOSE;
700       my $path = File::Spec->catfile($inc, $subdir, 'freetype.h');
701       -e $path or next;
702       $path = File::Spec->catfile($inc, $subdir, 'fterrors.h');
703       -e $path and next;
704
705       print "TT: Found!\n"
706         if $VERBOSE;
707
708       $found_inc = File::Spec->catdir($inc, $subdir);
709       last INCS;
710     }
711   }
712
713   my $found_lib;
714  LIBS:
715   for my $lib (@libs) {
716     my $a_path = File::Spec->catfile($lib, "libttf$aext");
717     my $l_path = File::Spec->catfile($lib, "libttf.$lext");
718     print "TT: lib check $lib\n"
719       if $VERBOSE;
720     if (-e $a_path || -e $l_path) {
721       $found_lib = $lib;
722       print "TT: Found!\n"
723         if $VERBOSE;
724       last LIBS;
725     }
726   }
727
728   return unless $found_inc && $found_lib;
729   printf("%10s: includes %s - libraries %s\n", $frmkey,
730          ($found_inc ? 'found' : 'not found'), 
731          ($found_lib ? 'found' : 'not found'));
732
733   $frm->{cflags} = "-I$found_inc";
734   $frm->{libfiles} = "-lttf";
735
736   return 1;
737 }
738
739 sub catfile {
740   return File::Spec->catfile(@_);
741 }
742
743 sub usage {
744   print STDERR <<EOS;
745 Usage: $0 [--enable feature1,feature2,...] [other options]
746        $0 [--disable feature1,feature2,...]  [other options]
747        $0 --help
748 Possible feature names are:
749   T1-fonts
750 Other options:
751   --verbose | -v
752     Verbose library probing (or set IM_VERBOSE in the environment)
753   --nolog
754     Disable logging (or set IM_NOLOG in the environment)
755   --incpath dir
756     Add to the include search path
757   --libpath dir
758     Add to the library search path
759   --coverage
760     Build for coverage testing.
761   --assert
762     Build with assertions active.
763 EOS
764   exit 1;
765
766 }
767
768 # generate the PM MM argument
769 # I'd prefer to modify the public version, but there doesn't seem to be 
770 # a public API to do that
771 sub gen_PM {
772   my %pm;
773   my $instbase = '$(INST_LIBDIR)';
774
775   # first the basics, .pm and .pod files
776   $pm{"Imager.pm"} = "$instbase/Imager.pm";
777
778   my $mani = maniread();
779
780   for my $filename (keys %$mani) {
781     if ($filename =~ m!^lib/! && $filename =~ /\.(pm|pod)$/) {
782       (my $work = $filename) =~ s/^lib//;
783       $pm{$filename} = $instbase . $work;
784     }
785   }
786
787   # need the typemap
788   $pm{typemap} = $instbase . '/Imager/typemap';
789
790   # and the core headers
791   for my $filename (keys %$mani) {
792     if ($filename =~ /^\w+\.h$/) {
793       $pm{$filename} = $instbase . '/Imager/include/' . $filename;
794     }
795   }
796
797   # and the generated header
798   $pm{"imconfig.h"} = $instbase . '/Imager/include/imconfig.h';
799
800   \%pm;
801 }
802
803 my $home;
804 sub _tilde_expand {
805   my ($path) = @_;
806
807   if ($path =~ m!^~[/\\]!) {
808     defined $home or $home = $ENV{HOME};
809     if (!defined $home && $^O eq 'MSWin32'
810        && defined $ENV{HOMEDRIVE} && defined $ENV{HOMEPATH}) {
811       $home = $ENV{HOMEDRIVE} . $ENV{HOMEPATH};
812     }
813     unless (defined $home) {
814       $home = eval { (getpwuid($<))[7] };
815     }
816     defined $home or die "You supplied $path, but I can't find your home directory\n";
817     $path =~ s/^~//;
818     $path = File::Spec->catdir($home, $path);
819   }
820
821   $path;
822 }
823
824 1;