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