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